1,6 → 1,6 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; |
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
7,7 → 7,65 |
|
$Revision$ |
|
struct NTFS PARTITION |
Lock MUTEX ? ; currently operations with one partition |
; can not be executed in parallel since the |
; legacy code is not ready; this mutex guards |
; all operations |
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 ? |
|
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 |
|
cur_subnode_size dd ? |
ntfs_attr_iRecord dd ? |
ntfs_attr_iBaseRecord dd ? |
ntfs_attr_offs dd ? |
ntfs_attr_list dd ? |
ntfs_attr_size dq ? |
ntfs_cur_tail dd ? |
|
ntfs_attrlist_buf rb 0x400 |
ntfs_attrlist_mft_buf rb 0x400 |
ntfs_bitmap_buf rb 0x400 |
ends |
|
iglobal |
align 4 |
ntfs_user_functions: |
dd ntfs_free |
dd (ntfs_user_functions_end - ntfs_user_functions - 4) / 4 |
dd ntfs_Read |
dd ntfs_ReadFolder |
dd ntfs_Rewrite |
dd ntfs_Write |
dd ntfs_SetFileEnd |
dd ntfs_GetFileInfo |
dd ntfs_SetFileInfo |
dd 0 |
dd ntfs_Delete |
dd ntfs_CreateFolder |
ntfs_user_functions_end: |
endg |
|
ntfs_test_bootsec: |
; in: ebx->buffer, edx=size of partition |
; out: CF set <=> invalid |
93,25 → 151,66 |
stc |
ret |
|
ntfs_setup: ; CODE XREF: part_set.inc |
proc ntfs_create_partition |
mov edx, dword [ebp+PARTITION.Length] |
cmp dword [esp+4], 0 |
jz .boot_read_ok |
add ebx, 512 |
lea eax, [edx-1] |
call fs_read32_sys |
test eax, eax |
jnz @f |
call ntfs_test_bootsec |
jnc .ntfs_setup |
@@: |
mov eax, edx |
shr eax, 1 |
call fs_read32_sys |
test eax, eax |
jnz .nope ; no chance... |
.boot_read_ok: |
call ntfs_test_bootsec |
jnc .ntfs_setup |
.nope: |
xor eax, eax |
jmp .exit |
|
.ntfs_setup: |
; By given bootsector, initialize some NTFS variables |
; call ntfs_test_bootsec ; checking boot sector was already |
; jc problem_fat_dec_count |
movi eax, sizeof.NTFS |
call malloc |
test eax, eax |
jz .exit |
mov ecx, dword [ebp+PARTITION.FirstSector] |
mov dword [eax+NTFS.FirstSector], ecx |
mov ecx, dword [ebp+PARTITION.FirstSector+4] |
mov dword [eax+NTFS.FirstSector+4], ecx |
mov ecx, dword [ebp+PARTITION.Length] |
mov dword [eax+NTFS.Length], ecx |
mov ecx, dword [ebp+PARTITION.Length+4] |
mov dword [eax+NTFS.Length+4], ecx |
mov ecx, [ebp+PARTITION.Disk] |
mov [eax+NTFS.Disk], ecx |
mov [eax+NTFS.FSUserFunctions], ntfs_user_functions |
push ebx ebp esi |
mov ebp, eax |
|
lea ecx, [ebp+NTFS.Lock] |
call mutex_init |
|
movzx eax, byte [ebx+13] |
mov [ntfs_data.sectors_per_cluster], eax |
mov [ebp+NTFS.sectors_per_cluster], eax |
mov eax, [ebx+0x28] |
add eax, [PARTITION_START] |
dec eax |
mov [PARTITION_END], eax |
mov [fs_type], 1 |
mov dword [ebp+NTFS.Length], eax |
and dword [ebp+NTFS.Length+4], 0 |
mov eax, [ebx+0x30] |
mov [ntfs_data.mft_cluster], eax |
mov [ebp+NTFS.mft_cluster], eax |
mov eax, [ebx+0x38] |
mov [ntfs_data.mftmirr_cluster], eax |
mov [ebp+NTFS.mftmirr_cluster], eax |
movsx eax, byte [ebx+0x40] |
test eax, eax |
js .1 |
mul [ntfs_data.sectors_per_cluster] |
mul [ebp+NTFS.sectors_per_cluster] |
shl eax, 9 |
jmp .2 |
.1: |
120,11 → 219,11 |
mov eax, 1 |
shl eax, cl |
.2: |
mov [ntfs_data.frs_size], eax |
mov [ebp+NTFS.frs_size], eax |
movsx eax, byte [ebx+0x44] |
test eax, eax |
js .3 |
mul [ntfs_data.sectors_per_cluster] |
mul [ebp+NTFS.sectors_per_cluster] |
shl eax, 9 |
jmp .4 |
.3: |
133,21 → 232,21 |
mov eax, 1 |
shl eax, cl |
.4: |
mov [ntfs_data.iab_size], eax |
mov [ebp+NTFS.iab_size], eax |
; allocate space for buffers |
add eax, [ntfs_data.frs_size] |
add eax, [ebp+NTFS.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 |
jz .fail_free |
mov [ebp+NTFS.frs_buffer], eax |
add eax, [ebp+NTFS.frs_size] |
mov [ebp+NTFS.iab_buffer], eax |
; read $MFT disposition |
mov eax, [ntfs_data.mft_cluster] |
mul [ntfs_data.sectors_per_cluster] |
mov eax, [ebp+NTFS.mft_cluster] |
mul [ebp+NTFS.sectors_per_cluster] |
call ntfs_read_frs_sector |
cmp [hd_error], 0 |
test eax, eax |
jnz .usemirr |
cmp dword [ebx], 'FILE' |
jnz .usemirr |
154,11 → 253,10 |
call ntfs_restore_usa_frs |
jnc .mftok |
.usemirr: |
and [hd_error], 0 |
mov eax, [ntfs_data.mftmirr_cluster] |
mul [ntfs_data.sectors_per_cluster] |
mov eax, [ebp+NTFS.mftmirr_cluster] |
mul [ebp+NTFS.sectors_per_cluster] |
call ntfs_read_frs_sector |
cmp [hd_error], 0 |
test eax, eax |
jnz @f |
cmp dword [ebx], 'FILE' |
jnz @f |
167,11 → 265,22 |
@@: |
; $MFT and $MFTMirr invalid! |
.fail_free_frs: |
push [ntfs_data.frs_buffer] |
push [ebp+NTFS.frs_buffer] |
call kernel_free |
jmp problem_fat_dec_count |
.fail_free: |
mov eax, ebp |
call free |
xor eax, eax |
.pop_exit: |
pop esi ebp ebx |
.exit: |
cmp dword [esp+4], 0 |
jz @f |
sub ebx, 512 |
@@: |
ret |
.fail_free_mft: |
push [ntfs_data.mft_retrieval] |
push [ebp+NTFS.mft_retrieval] |
call kernel_free |
jmp .fail_free_frs |
.mftok: |
183,9 → 292,9 |
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 |
mov [ebp+NTFS.mft_retrieval], eax |
and [ebp+NTFS.mft_retrieval_size], 0 |
mov [ebp+NTFS.mft_retrieval_alloc], 0x1000/8 |
; $MFT base record must contain unnamed non-resident $DATA attribute |
movzx eax, word [ebx+14h] |
add eax, ebx |
204,7 → 313,7 |
jz .fail_free_mft |
; load first portion of $DATA attribute retrieval information |
mov edx, [eax+0x18] |
mov [ntfs_data.mft_retrieval_end], edx |
mov [ebp+NTFS.mft_retrieval_end], edx |
mov esi, eax |
movzx eax, word [eax+0x20] |
add esi, eax |
217,7 → 326,7 |
mov [eax], edx |
mov edx, [esp+8] ; block addr (relative) |
mov [eax+4], edx |
inc [ntfs_data.mft_retrieval_size] |
inc [ebp+NTFS.mft_retrieval_size] |
jmp .scanmcb |
.scanmcbend: |
add esp, 10h |
224,25 → 333,24 |
; 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 |
mov [ebp+NTFS.cur_index_size], 0x1000/0x200 |
push 0x1000 |
call kernel_alloc |
test eax, eax |
jz .fail_free_mft |
mov [ntfs_data.cur_index_buf], eax |
mov [ebp+NTFS.cur_index_buf], eax |
|
popad |
call free_hd_channel |
and [hd1_status], 0 |
ret |
mov eax, ebp |
jmp .pop_exit |
endp |
|
.get_mft_retrieval_ptr: |
pushad |
mov eax, [ntfs_data.mft_retrieval_size] |
cmp eax, [ntfs_data.mft_retrieval_alloc] |
mov eax, [ebp+NTFS.mft_retrieval_size] |
cmp eax, [ebp+NTFS.mft_retrieval_alloc] |
jnz .ok |
add eax, 0x1000/8 |
mov [ntfs_data.mft_retrieval_alloc], eax |
mov [ebp+NTFS.mft_retrieval_alloc], eax |
shl eax, 3 |
push eax |
call kernel_alloc |
252,83 → 360,88 |
add esp, 14h |
jmp .fail_free_mft |
@@: |
mov esi, [ntfs_data.mft_retrieval] |
mov esi, [ebp+NTFS.mft_retrieval] |
mov edi, eax |
mov ecx, [ntfs_data.mft_retrieval_size] |
mov ecx, [ebp+NTFS.mft_retrieval_size] |
add ecx, ecx |
rep movsd |
push [ntfs_data.mft_retrieval] |
mov [ntfs_data.mft_retrieval], eax |
push [ebp+NTFS.mft_retrieval] |
mov [ebp+NTFS.mft_retrieval], eax |
call kernel_free |
mov eax, [ntfs_data.mft_retrieval_size] |
mov eax, [ebp+NTFS.mft_retrieval_size] |
.ok: |
shl eax, 3 |
add eax, [ntfs_data.mft_retrieval] |
add eax, [ebp+NTFS.mft_retrieval] |
mov [esp+28], eax |
popad |
ret |
|
proc ntfs_free |
push ebx |
xchg ebx, eax |
stdcall kernel_free, [ebx+NTFS.frs_buffer] |
stdcall kernel_free, [ebx+NTFS.mft_retrieval] |
stdcall kernel_free, [ebx+NTFS.cur_index_buf] |
xchg ebx, eax |
call free |
pop ebx |
ret |
endp |
|
proc ntfs_lock |
lea ecx, [ebp+NTFS.Lock] |
jmp mutex_lock |
endp |
|
proc ntfs_unlock |
lea ecx, [ebp+NTFS.Lock] |
jmp mutex_unlock |
endp |
|
ntfs_read_frs_sector: |
push eax ecx |
add eax, [PARTITION_START] |
mov ecx, [ntfs_data.frs_size] |
push ecx |
mov ebx, [ebp+NTFS.frs_buffer] |
push ebx |
mov ecx, [ebp+NTFS.frs_size] |
shr ecx, 9 |
mov ebx, [ntfs_data.frs_buffer] |
push ebx |
push ecx |
mov ecx, eax |
@@: |
call hd_read |
cmp [hd_error], 0 |
mov eax, ecx |
call fs_read32_sys |
test eax, eax |
jnz .fail |
add ebx, 0x200 |
inc eax |
loop @b |
inc ecx |
dec dword [esp] |
jnz @b |
pop eax |
.fail: |
pop ebx |
pop ecx eax |
pop ecx |
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] |
; in: variables in ebp+NTFS.* |
; out: [ebp+NTFS.ntfs_cur_read] |
; out: CF=1 => notfound, in this case eax=0 => disk ok, otherwise eax=disk error code |
xor eax, eax |
pushad |
and [ntfs_cur_read], 0 |
cmp [ntfs_cur_iRecord], 0 |
and [ebp+NTFS.ntfs_cur_read], 0 |
cmp [ebp+NTFS.ntfs_cur_iRecord], 0 |
jnz .nomft |
cmp [ntfs_cur_attr], 0x80 |
cmp [ebp+NTFS.ntfs_cur_attr], 0x80 |
jnz .nomft |
mov eax, [ntfs_data.mft_retrieval_end] |
mov eax, [ebp+NTFS.mft_retrieval_end] |
inc eax |
mul [ntfs_data.sectors_per_cluster] |
cmp eax, [ntfs_cur_offs] |
mul [ebp+NTFS.sectors_per_cluster] |
cmp eax, [ebp+NTFS.ntfs_cur_offs] |
jbe .nomft |
; precalculated part of $Mft $DATA |
mov esi, [ntfs_data.mft_retrieval] |
mov eax, [ntfs_cur_offs] |
mov esi, [ebp+NTFS.mft_retrieval] |
mov eax, [ebp+NTFS.ntfs_cur_offs] |
xor edx, edx |
div [ntfs_data.sectors_per_cluster] |
div [ebp+NTFS.sectors_per_cluster] |
; eax = VCN, edx = offset in sectors from beginning of cluster |
xor ecx, ecx ; ecx will contain LCN |
.mftscan: |
337,9 → 450,9 |
jb @f |
add esi, 8 |
push eax |
mov eax, [ntfs_data.mft_retrieval_end] |
mov eax, [ebp+NTFS.mft_retrieval_end] |
shl eax, 3 |
add eax, [ntfs_data.mft_retrieval] |
add eax, [ebp+NTFS.mft_retrieval] |
cmp eax, esi |
pop eax |
jnz .mftscan |
350,42 → 463,43 |
add ecx, [esi] |
push eax |
push edx |
mov eax, [ntfs_data.sectors_per_cluster] |
mov eax, [ebp+NTFS.sectors_per_cluster] |
mul ecx |
; eax = sector on partition |
add eax, [PARTITION_START] |
pop edx |
add eax, edx |
mov ebx, [ntfs_cur_buf] |
mov ebx, [ebp+NTFS.ntfs_cur_buf] |
pop ecx |
neg ecx |
imul ecx, [ntfs_data.sectors_per_cluster] |
imul ecx, [ebp+NTFS.sectors_per_cluster] |
sub ecx, edx |
cmp ecx, [ntfs_cur_size] |
cmp ecx, [ebp+NTFS.ntfs_cur_size] |
jb @f |
mov ecx, [ntfs_cur_size] |
mov ecx, [ebp+NTFS.ntfs_cur_size] |
@@: |
; ecx = number of sequential sectors to read |
call hd_read |
cmp [hd_error], 0 |
push eax |
call fs_read32_sys |
pop edx |
test eax, eax |
jnz .errread |
add [ntfs_cur_read], 0x200 |
dec [ntfs_cur_size] |
inc [ntfs_cur_offs] |
add [ebp+NTFS.ntfs_cur_read], 0x200 |
dec [ebp+NTFS.ntfs_cur_size] |
inc [ebp+NTFS.ntfs_cur_offs] |
add ebx, 0x200 |
mov [ntfs_cur_buf], ebx |
inc eax |
mov [ebp+NTFS.ntfs_cur_buf], ebx |
lea eax, [edx+1] |
loop @b |
pop ecx |
xor eax, eax |
xor edx, edx |
cmp [ntfs_cur_size], eax |
cmp [ebp+NTFS.ntfs_cur_size], eax |
jz @f |
add esi, 8 |
push eax |
mov eax, [ntfs_data.mft_retrieval_end] |
mov eax, [ebp+NTFS.mft_retrieval_end] |
shl eax, 3 |
add eax, [ntfs_data.mft_retrieval] |
add eax, [ebp+NTFS.mft_retrieval] |
cmp eax, esi |
pop eax |
jz .nomft |
396,6 → 510,7 |
.errread: |
pop ecx |
.errret: |
mov [esp+28], eax |
stc |
popad |
ret |
402,17 → 517,16 |
.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 |
mov eax, [ebp+NTFS.ntfs_cur_iRecord] |
mov [ebp+NTFS.ntfs_attr_iRecord], eax |
and [ebp+NTFS.ntfs_attr_list], 0 |
or dword [ebp+NTFS.ntfs_attr_size], -1 |
or dword [ebp+NTFS.ntfs_attr_size+4], -1 |
or [ebp+NTFS.ntfs_attr_iBaseRecord], -1 |
call ntfs_read_file_record |
test eax, eax |
jz .errret |
jc .errret |
; 2. Find required attribute. |
mov eax, [ntfs_data.frs_buffer] |
mov eax, [ebp+NTFS.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 |
422,27 → 536,26 |
; test eax, eax |
; jz @f |
.beginfindattr: |
mov [ntfs_attr_iRecord], eax |
mov [ebp+NTFS.ntfs_attr_iRecord], eax |
call ntfs_read_file_record |
test eax, eax |
jz .errret |
jc .errret |
@@: |
; b) Scan for required attribute and for $ATTR_LIST |
mov eax, [ntfs_data.frs_buffer] |
mov eax, [ebp+NTFS.frs_buffer] |
movzx ecx, word [eax+14h] |
add eax, ecx |
mov ecx, [ntfs_cur_attr] |
and [ntfs_attr_offs], 0 |
mov ecx, [ebp+NTFS.ntfs_cur_attr] |
and [ebp+NTFS.ntfs_attr_offs], 0 |
.scanattr: |
cmp dword [eax], -1 |
jz .scandone |
cmp dword [eax], ecx |
jz .okattr |
cmp [ntfs_attr_iBaseRecord], -1 |
cmp [ebp+NTFS.ntfs_attr_iBaseRecord], -1 |
jnz .scancont |
cmp dword [eax], 0x20 ; $ATTR_LIST |
jnz .scancont |
mov [ntfs_attr_list], eax |
mov [ebp+NTFS.ntfs_attr_list], eax |
jmp .scancont |
.okattr: |
; ignore named $DATA attributes (aka NTFS streams) |
451,30 → 564,30 |
cmp byte [eax+9], 0 |
jnz .scancont |
@@: |
mov [ntfs_attr_offs], eax |
mov [ebp+NTFS.ntfs_attr_offs], eax |
.scancont: |
add eax, [eax+4] |
jmp .scanattr |
.continue: |
pushad |
and [ntfs_cur_read], 0 |
and [ebp+NTFS.ntfs_cur_read], 0 |
.scandone: |
; c) Check for required offset and length |
mov ecx, [ntfs_attr_offs] |
mov ecx, [ebp+NTFS.ntfs_attr_offs] |
jecxz .noattr |
push [ntfs_cur_size] |
push [ntfs_cur_read] |
push [ebp+NTFS.ntfs_cur_size] |
push [ebp+NTFS.ntfs_cur_read] |
call .doreadattr |
pop edx |
pop eax |
pop ecx |
jc @f |
cmp [ntfs_bCanContinue], 0 |
cmp [ebp+NTFS.ntfs_bCanContinue], 0 |
jz @f |
sub edx, [ntfs_cur_read] |
sub edx, [ebp+NTFS.ntfs_cur_read] |
neg edx |
shr edx, 9 |
sub eax, edx |
mov [ntfs_cur_size], eax |
sub ecx, edx |
mov [ebp+NTFS.ntfs_cur_size], ecx |
jnz .not_in_cur |
@@: |
popad |
481,13 → 594,14 |
ret |
.noattr: |
.not_in_cur: |
cmp [ntfs_cur_attr], 0x20 |
cmp [ebp+NTFS.ntfs_cur_attr], 0x20 |
jz @f |
mov ecx, [ntfs_attr_list] |
mov ecx, [ebp+NTFS.ntfs_attr_list] |
test ecx, ecx |
jnz .lookattr |
.ret_is_attr: |
cmp [ntfs_attr_offs], 1 ; CF set <=> ntfs_attr_offs == 0 |
and dword [esp+28], 0 |
cmp [ebp+NTFS.ntfs_attr_offs], 1 ; CF set <=> ntfs_attr_offs == 0 |
popad |
ret |
.lookattr: |
494,49 → 608,49 |
; 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] |
mov eax, [ebp+NTFS.ntfs_attr_iBaseRecord] |
cmp eax, -1 |
jz @f |
call ntfs_read_file_record |
test eax, eax |
jz .errret |
or [ntfs_attr_iBaseRecord], -1 |
jc .errret |
or [ebp+NTFS.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 |
push [ebp+NTFS.ntfs_cur_offs] |
push [ebp+NTFS.ntfs_cur_size] |
push [ebp+NTFS.ntfs_cur_read] |
push [ebp+NTFS.ntfs_cur_buf] |
push dword [ebp+NTFS.ntfs_attr_size] |
push dword [ebp+NTFS.ntfs_attr_size+4] |
or dword [ebp+NTFS.ntfs_attr_size], -1 |
or dword [ebp+NTFS.ntfs_attr_size+4], -1 |
and [ebp+NTFS.ntfs_cur_offs], 0 |
mov [ebp+NTFS.ntfs_cur_size], 2 |
and [ebp+NTFS.ntfs_cur_read], 0 |
lea eax, [ebp+NTFS.ntfs_attrlist_buf] |
cmp [ebp+NTFS.ntfs_cur_iRecord], 0 |
jnz @f |
mov eax, ntfs_attrlist_mft_buf |
lea eax, [ebp+NTFS.ntfs_attrlist_mft_buf] |
@@: |
mov [ntfs_cur_buf], eax |
mov [ebp+NTFS.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] |
pop dword [ebp+NTFS.ntfs_attr_size+4] |
pop dword [ebp+NTFS.ntfs_attr_size] |
mov ecx, [ebp+NTFS.ntfs_cur_read] |
pop [ebp+NTFS.ntfs_cur_buf] |
pop [ebp+NTFS.ntfs_cur_read] |
pop [ebp+NTFS.ntfs_cur_size] |
pop [ebp+NTFS.ntfs_cur_offs] |
jc .errret |
or edi, -1 |
lea ebp, [ebp+esi-1Ah] |
lea ecx, [ecx+esi-1Ah] |
.scanliststart: |
mov eax, [ntfs_cur_attr] |
push ecx |
mov eax, [ebp+NTFS.ntfs_cur_attr] |
.scanlist: |
cmp esi, ebp |
cmp esi, [esp] |
jae .scanlistdone |
cmp eax, [esi] |
jz @f |
555,26 → 669,28 |
mov eax, [esi+8] |
test eax, eax |
jnz .testf |
mov eax, dword [ntfs_attr_size] |
and eax, dword [ntfs_attr_size+4] |
mov eax, dword [ebp+NTFS.ntfs_attr_size] |
and eax, dword [ebp+NTFS.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 |
jnc @f |
.errret_pop: |
pop eax |
pop ecx ecx |
jmp .errret |
.errret2_pop: |
xor eax, eax |
jmp .errret_pop |
@@: |
mov eax, [ntfs_data.frs_buffer] |
mov eax, [ebp+NTFS.frs_buffer] |
movzx ecx, word [eax+14h] |
add eax, ecx |
mov ecx, [ntfs_cur_attr] |
mov ecx, [ebp+NTFS.ntfs_cur_attr] |
@@: |
cmp dword [eax], -1 |
jz .errret_pop |
jz .errret2_pop |
cmp dword [eax], ecx |
jz @f |
.l1: |
589,24 → 705,25 |
cmp byte [eax+8], 0 |
jnz .sdnores |
mov eax, [eax+10h] |
mov dword [ntfs_attr_size], eax |
and dword [ntfs_attr_size+4], 0 |
mov dword [ebp+NTFS.ntfs_attr_size], eax |
and dword [ebp+NTFS.ntfs_attr_size+4], 0 |
jmp .testfz |
.sdnores: |
mov ecx, [eax+30h] |
mov dword [ntfs_attr_size], ecx |
mov dword [ebp+NTFS.ntfs_attr_size], ecx |
mov ecx, [eax+34h] |
mov dword [ntfs_attr_size+4], ecx |
mov dword [ebp+NTFS.ntfs_attr_size+4], ecx |
.testfz: |
xor eax, eax |
.testf: |
imul eax, [ntfs_data.sectors_per_cluster] |
cmp eax, [ntfs_cur_offs] |
imul eax, [ebp+NTFS.sectors_per_cluster] |
cmp eax, [ebp+NTFS.ntfs_cur_offs] |
pop eax |
ja @f |
mov edi, [esi+10h] ; keep previous iRecord |
jmp .scanlistcont |
@@: |
pop ecx |
.scanlistfound: |
cmp edi, -1 |
jnz @f |
613,30 → 730,28 |
popad |
ret |
@@: |
mov eax, [ntfs_cur_iRecord] |
mov [ntfs_attr_iBaseRecord], eax |
mov eax, [ebp+NTFS.ntfs_cur_iRecord] |
mov [ebp+NTFS.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 |
pop ecx |
sub ecx, ebp |
sub ecx, NTFS.ntfs_attrlist_buf-1Ah |
cmp [ebp+NTFS.ntfs_cur_iRecord], 0 |
jnz @f |
sub ebp, ntfs_attrlist_mft_buf-ntfs_attrlist_buf |
sub ecx, NTFS.ntfs_attrlist_mft_buf-NTFS.ntfs_attrlist_buf |
@@: |
cmp ebp, 0x400 |
cmp ecx, 0x400 |
jnz .scanlistfound |
inc edx |
push esi edi |
mov esi, ntfs_attrlist_buf+0x200 |
mov edi, ntfs_attrlist_buf |
cmp [ntfs_cur_iRecord], 0 |
lea esi, [ebp+NTFS.ntfs_attrlist_buf+0x200] |
lea edi, [ebp+NTFS.ntfs_attrlist_buf] |
cmp [ebp+NTFS.ntfs_cur_iRecord], 0 |
jnz @f |
mov esi, ntfs_attrlist_mft_buf+0x200 |
mov edi, ntfs_attrlist_mft_buf |
lea esi, [ebp+NTFS.ntfs_attrlist_mft_buf+0x200] |
lea edi, [ebp+NTFS.ntfs_attrlist_mft_buf] |
@@: |
mov ecx, 0x200/4 |
rep movsd |
643,43 → 758,43 |
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 |
push [ebp+NTFS.ntfs_cur_offs] |
push [ebp+NTFS.ntfs_cur_size] |
push [ebp+NTFS.ntfs_cur_read] |
push [ebp+NTFS.ntfs_cur_buf] |
push dword [ebp+NTFS.ntfs_attr_size] |
push dword [ebp+NTFS.ntfs_attr_size+4] |
or dword [ebp+NTFS.ntfs_attr_size], -1 |
or dword [ebp+NTFS.ntfs_attr_size+4], -1 |
mov [ebp+NTFS.ntfs_cur_offs], edx |
mov [ebp+NTFS.ntfs_cur_size], 1 |
and [ebp+NTFS.ntfs_cur_read], 0 |
mov [ebp+NTFS.ntfs_cur_buf], eax |
mov ecx, [ebp+NTFS.ntfs_attr_list] |
push esi edx edi |
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] |
pop edi edx esi |
mov ecx, [ebp+NTFS.ntfs_cur_read] |
pop dword [ebp+NTFS.ntfs_attr_size+4] |
pop dword [ebp+NTFS.ntfs_attr_size] |
pop [ebp+NTFS.ntfs_cur_buf] |
pop [ebp+NTFS.ntfs_cur_read] |
pop [ebp+NTFS.ntfs_cur_size] |
pop [ebp+NTFS.ntfs_cur_offs] |
jc .errret |
add ebp, ntfs_attrlist_buf+0x200-0x1A |
cmp [ntfs_cur_iRecord], 0 |
lea ecx, [ecx+ebp+NTFS.ntfs_attrlist_buf+0x200-0x1A] |
cmp [ebp+NTFS.ntfs_cur_iRecord], 0 |
jnz .scanliststart |
add ebp, ntfs_attrlist_mft_buf-ntfs_attrlist_buf |
add ecx, NTFS.ntfs_attrlist_mft_buf-NTFS.ntfs_attrlist_buf |
jmp .scanliststart |
|
.doreadattr: |
mov [ntfs_bCanContinue], 0 |
mov [ebp+NTFS.ntfs_bCanContinue], 0 |
cmp byte [ecx+8], 0 |
jnz .nonresident |
mov eax, [ecx+10h] ; length |
mov esi, eax |
mov edx, [ntfs_cur_offs] |
mov edx, [ebp+NTFS.ntfs_cur_offs] |
shr eax, 9 |
cmp eax, edx |
jb .okret |
688,7 → 803,7 |
movzx eax, word [ecx+14h] |
add edx, eax |
add edx, ecx ; edx -> data |
mov eax, [ntfs_cur_size] |
mov eax, [ebp+NTFS.ntfs_cur_size] |
cmp eax, (0xFFFFFFFF shr 9)+1 |
jbe @f |
mov eax, (0xFFFFFFFF shr 9)+1 |
699,17 → 814,17 |
mov eax, esi |
@@: |
; eax = length, edx -> data |
mov [ntfs_cur_read], eax |
mov [ebp+NTFS.ntfs_cur_read], eax |
mov ecx, eax |
mov eax, edx |
mov ebx, [ntfs_cur_buf] |
mov ebx, [ebp+NTFS.ntfs_cur_buf] |
call memmove |
and [ntfs_cur_size], 0 ; CF=0 |
and [ebp+NTFS.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] |
mov eax, dword [ebp+NTFS.ntfs_attr_size] |
mov edx, dword [ebp+NTFS.ntfs_attr_size+4] |
push eax |
and eax, edx |
cmp eax, -1 |
717,34 → 832,34 |
jnz @f |
mov eax, [ecx+30h] ; FileSize |
mov edx, [ecx+34h] |
mov dword [ntfs_attr_size], eax |
mov dword [ntfs_attr_size+4], edx |
mov dword [ebp+NTFS.ntfs_attr_size], eax |
mov dword [ebp+NTFS.ntfs_attr_size+4], edx |
@@: |
add eax, 0x1FF |
adc edx, 0 |
shrd eax, edx, 9 |
sub eax, [ntfs_cur_offs] |
sub eax, [ebp+NTFS.ntfs_cur_offs] |
ja @f |
; return with nothing read |
and [ntfs_cur_size], 0 |
and [ebp+NTFS.ntfs_cur_size], 0 |
.okret: |
clc |
ret |
@@: |
; reduce read length |
and [ntfs_cur_tail], 0 |
cmp [ntfs_cur_size], eax |
and [ebp+NTFS.ntfs_cur_tail], 0 |
cmp [ebp+NTFS.ntfs_cur_size], eax |
jb @f |
mov [ntfs_cur_size], eax |
mov eax, dword [ntfs_attr_size] |
mov [ebp+NTFS.ntfs_cur_size], eax |
mov eax, dword [ebp+NTFS.ntfs_attr_size] |
and eax, 0x1FF |
mov [ntfs_cur_tail], eax |
mov [ebp+NTFS.ntfs_cur_tail], eax |
@@: |
cmp [ntfs_cur_size], 0 |
cmp [ebp+NTFS.ntfs_cur_size], 0 |
jz .okret |
mov eax, [ntfs_cur_offs] |
mov eax, [ebp+NTFS.ntfs_cur_offs] |
xor edx, edx |
div [ntfs_data.sectors_per_cluster] |
div [ebp+NTFS.sectors_per_cluster] |
sub eax, [ecx+10h] ; first_vbo |
jb .okret |
; eax = cluster, edx = starting sector |
751,51 → 866,60 |
sub esp, 10h |
movzx esi, word [ecx+20h] ; mcb_info_ofs |
add esi, ecx |
xor ebp, ebp |
xor edi, edi |
.readloop: |
call ntfs_decode_mcb_entry |
jnc .break |
add ebp, [esp+8] |
add edi, [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, edi |
imul eax, [ebp+NTFS.sectors_per_cluster] |
add eax, edx |
add eax, [PARTITION_START] |
pop ecx |
neg ecx |
imul ecx, [ntfs_data.sectors_per_cluster] |
imul ecx, [ebp+NTFS.sectors_per_cluster] |
sub ecx, edx |
cmp ecx, [ntfs_cur_size] |
cmp ecx, [ebp+NTFS.ntfs_cur_size] |
jb @f |
mov ecx, [ntfs_cur_size] |
mov ecx, [ebp+NTFS.ntfs_cur_size] |
@@: |
mov ebx, [ntfs_cur_buf] |
mov ebx, [ebp+NTFS.ntfs_cur_buf] |
@@: |
call hd_read |
cmp [hd_error], 0 |
push eax |
cmp [ebp+NTFS.ntfs_cur_attr], 0x80 |
jnz .sys |
cmp [ebp+NTFS.ntfs_cur_iRecord], 0 |
jz .sys |
call fs_read32_app |
jmp .appsys |
.sys: |
call fs_read32_sys |
.appsys: |
pop edx |
test eax, eax |
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] |
mov [ebp+NTFS.ntfs_cur_buf], ebx |
lea eax, [edx+1] |
add [ebp+NTFS.ntfs_cur_read], 0x200 |
dec [ebp+NTFS.ntfs_cur_size] |
inc [ebp+NTFS.ntfs_cur_offs] |
loop @b |
pop ecx |
xor eax, eax |
xor edx, edx |
cmp [ntfs_cur_size], 0 |
cmp [ebp+NTFS.ntfs_cur_size], 0 |
jnz .readloop |
add esp, 10h |
mov eax, [ntfs_cur_tail] |
mov eax, [ebp+NTFS.ntfs_cur_tail] |
test eax, eax |
jz @f |
sub eax, 0x200 |
add [ntfs_cur_read], eax |
add [ebp+NTFS.ntfs_cur_read], eax |
@@: |
clc |
ret |
806,58 → 930,57 |
ret |
.break: |
add esp, 10h ; CF=0 |
mov [ntfs_bCanContinue], 1 |
mov [ebp+NTFS.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] |
; out: [ebp+NTFS.frs_buffer] contains information |
; CF=1 - failed, in this case eax=0 => something with FS, eax nonzero => disk error |
; Read attr $DATA of $Mft, starting from eax*[ebp+NTFS.frs_size] |
push ecx edx |
mov ecx, [ntfs_data.frs_size] |
mov ecx, [ebp+NTFS.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 |
jnz .errret |
push [ebp+NTFS.ntfs_attr_iRecord] |
push [ebp+NTFS.ntfs_attr_iBaseRecord] |
push [ebp+NTFS.ntfs_attr_offs] |
push [ebp+NTFS.ntfs_attr_list] |
push dword [ebp+NTFS.ntfs_attr_size+4] |
push dword [ebp+NTFS.ntfs_attr_size] |
push [ebp+NTFS.ntfs_cur_iRecord] |
push [ebp+NTFS.ntfs_cur_attr] |
push [ebp+NTFS.ntfs_cur_offs] |
push [ebp+NTFS.ntfs_cur_size] |
push [ebp+NTFS.ntfs_cur_buf] |
push [ebp+NTFS.ntfs_cur_read] |
mov [ebp+NTFS.ntfs_cur_attr], 0x80 ; $DATA |
and [ebp+NTFS.ntfs_cur_iRecord], 0 ; $Mft |
mov [ebp+NTFS.ntfs_cur_offs], eax |
shr ecx, 9 |
mov [ntfs_cur_size], ecx |
mov eax, [ntfs_data.frs_buffer] |
mov [ntfs_cur_buf], eax |
mov [ebp+NTFS.ntfs_cur_size], ecx |
mov eax, [ebp+NTFS.frs_buffer] |
mov [ebp+NTFS.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] |
mov edx, [ebp+NTFS.ntfs_cur_read] |
pop [ebp+NTFS.ntfs_cur_read] |
pop [ebp+NTFS.ntfs_cur_buf] |
pop [ebp+NTFS.ntfs_cur_size] |
pop [ebp+NTFS.ntfs_cur_offs] |
pop [ebp+NTFS.ntfs_cur_attr] |
pop [ebp+NTFS.ntfs_cur_iRecord] |
pop dword [ebp+NTFS.ntfs_attr_size] |
pop dword [ebp+NTFS.ntfs_attr_size+4] |
pop [ebp+NTFS.ntfs_attr_list] |
pop [ebp+NTFS.ntfs_attr_offs] |
pop [ebp+NTFS.ntfs_attr_iBaseRecord] |
pop [ebp+NTFS.ntfs_attr_iRecord] |
jc .ret |
cmp edx, [ebp+NTFS.frs_size] |
jnz .errret |
mov eax, [ntfs_data.frs_buffer] |
mov eax, [ebp+NTFS.frs_buffer] |
cmp dword [eax], 'FILE' |
jnz .errret |
push ebx |
864,18 → 987,18 |
mov ebx, eax |
call ntfs_restore_usa_frs |
pop ebx |
setnc al |
movzx eax, al |
jc .errret |
.ret: |
pop edx ecx |
ret |
.err: |
.errret: |
pop edx ecx |
.errret: |
xor eax, eax |
stc |
ret |
|
ntfs_restore_usa_frs: |
mov eax, [ntfs_data.frs_size] |
mov eax, [ebp+NTFS.frs_size] |
ntfs_restore_usa: |
pushad |
shr eax, 9 |
955,82 → 1078,83 |
ret |
|
ntfs_find_lfn: |
; in: esi+ebp -> name |
; in: esi+[esp+4] -> 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 |
; else CF=0, [ebp+NTFS.ntfs_cur_iRecord] valid, eax->record in parent directory |
mov [ebp+NTFS.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 |
mov [ebp+NTFS.ntfs_cur_attr], 0x90 ; $INDEX_ROOT |
and [ebp+NTFS.ntfs_cur_offs], 0 |
mov eax, [ebp+NTFS.cur_index_size] |
mov [ebp+NTFS.ntfs_cur_size], eax |
mov eax, [ebp+NTFS.cur_index_buf] |
mov [ebp+NTFS.ntfs_cur_buf], eax |
call ntfs_read_attr |
jnc @f |
.ret: |
ret |
ret 4 |
@@: |
cmp [ntfs_cur_read], 0x20 |
xor eax, eax |
cmp [ebp+NTFS.ntfs_cur_read], 0x20 |
jc .ret |
pushad |
mov esi, [ntfs_data.cur_index_buf] |
mov esi, [ebp+NTFS.cur_index_buf] |
mov eax, [esi+14h] |
add eax, 10h |
cmp [ntfs_cur_read], eax |
cmp [ebp+NTFS.ntfs_cur_read], eax |
jae .readok1 |
add eax, 1FFh |
shr eax, 9 |
cmp eax, [ntfs_data.cur_index_size] |
cmp eax, [ebp+NTFS.cur_index_size] |
ja @f |
.stc_ret: |
popad |
stc |
ret |
ret 4 |
@@: |
; reallocate |
push eax |
push [ntfs_data.cur_index_buf] |
push [ebp+NTFS.cur_index_buf] |
call kernel_free |
pop eax |
mov [ntfs_data.cur_index_size], eax |
mov [ebp+NTFS.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 |
and [ebp+NTFS.cur_index_size], 0 |
and [ebp+NTFS.cur_index_buf], 0 |
jmp .stc_ret |
@@: |
mov [ntfs_data.cur_index_buf], eax |
mov [ebp+NTFS.cur_index_buf], eax |
popad |
jmp .doit2 |
.readok1: |
mov ebp, [esi+8] ; subnode_size |
shr ebp, 9 |
cmp ebp, [ntfs_data.cur_index_size] |
mov edx, [esi+8] ; subnode_size |
shr edx, 9 |
cmp edx, [ebp+NTFS.cur_index_size] |
jbe .ok2 |
push esi ebp |
push ebp |
push esi edx |
push edx |
call kernel_alloc |
pop ebp esi |
pop edx esi |
test eax, eax |
jz .stc_ret |
mov edi, eax |
mov ecx, [ntfs_data.cur_index_size] |
mov ecx, [ebp+NTFS.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] |
mov [ebp+NTFS.cur_index_size], edx |
push esi edx |
push [ebp+NTFS.cur_index_buf] |
call kernel_free |
pop ebp esi |
mov [ntfs_data.cur_index_buf], esi |
pop edx esi |
mov [ebp+NTFS.cur_index_buf], esi |
.ok2: |
add esi, 10h |
mov edi, [esp+4] |
; edi -> name, esi -> current index data, ebp = subnode size |
; edi -> name, esi -> current index data, edx = subnode size |
.scanloop: |
add esi, [esi] |
.scanloopint: |
1070,17 → 1194,19 |
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] |
imul eax, [ebp+NTFS.sectors_per_cluster] |
mov [ebp+NTFS.ntfs_cur_offs], eax |
mov [ebp+NTFS.ntfs_cur_attr], 0xA0 ; $INDEX_ALLOCATION |
mov [ebp+NTFS.ntfs_cur_size], edx |
mov eax, [ebp+NTFS.cur_index_buf] |
mov esi, eax |
mov [ntfs_cur_buf], eax |
mov [ebp+NTFS.ntfs_cur_buf], eax |
push edx |
call ntfs_read_attr |
mov eax, ebp |
pop edx |
mov eax, edx |
shl eax, 9 |
cmp [ntfs_cur_read], eax |
cmp [ebp+NTFS.ntfs_cur_read], eax |
jnz .notfound |
cmp dword [esi], 'INDX' |
jnz .notfound |
1092,7 → 1218,7 |
.notfound: |
popad |
stc |
ret |
ret 4 |
.found: |
cmp byte [edi], 0 |
jz .done |
1106,7 → 1232,7 |
pop esi |
pop esi |
mov eax, [esi] |
mov [ntfs_cur_iRecord], eax |
mov [ebp+NTFS.ntfs_cur_iRecord], eax |
mov [esp+1Ch], esi |
mov [esp+4], edi |
popad |
1113,29 → 1239,22 |
inc esi |
cmp byte [esi-1], 0 |
jnz .doit2 |
test ebp, ebp |
cmp dword [esp+4], 0 |
jz @f |
mov esi, ebp |
xor ebp, ebp |
mov esi, [esp+4] |
mov dword [esp+4], 0 |
jmp .doit2 |
@@: |
ret |
ret 4 |
|
;---------------------------------------------------------------- |
; |
; 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: |
; ntfs_Read - NTFS implementation of reading a file |
; in: ebp = pointer to NTFS structure |
; in: esi+[esp+4] = name |
; in: ebx = pointer to parameters from sysfunc 70 |
; out: eax, ebx = return values for sysfunc 70 |
;---------------------------------------------------------------- |
ntfs_Read: |
cmp byte [esi], 0 |
jnz @f |
or ebx, -1 |
1142,17 → 1261,20 |
movi eax, ERROR_ACCESS_DENIED |
ret |
@@: |
call ntfs_find_lfn |
call ntfs_lock |
stdcall ntfs_find_lfn, [esp+4] |
jnc .found |
call ntfs_unlock |
or ebx, -1 |
movi eax, ERROR_FILE_NOT_FOUND |
ret |
.found: |
mov [ntfs_cur_attr], 0x80 ; $DATA |
and [ntfs_cur_offs], 0 |
and [ntfs_cur_size], 0 |
mov [ebp+NTFS.ntfs_cur_attr], 0x80 ; $DATA |
and [ebp+NTFS.ntfs_cur_offs], 0 |
and [ebp+NTFS.ntfs_cur_size], 0 |
call ntfs_read_attr |
jnc @f |
call ntfs_unlock |
or ebx, -1 |
movi eax, ERROR_ACCESS_DENIED |
ret |
1160,9 → 1282,7 |
pushad |
and dword [esp+10h], 0 |
xor eax, eax |
test ebx, ebx |
jz .zero1 |
cmp dword [ebx+4], 0x200 |
cmp dword [ebx+8], 0x200 |
jb @f |
.eof0: |
popad |
1169,23 → 1289,29 |
xor ebx, ebx |
.eof: |
movi eax, ERROR_END_OF_FILE |
push eax |
call ntfs_unlock |
pop eax |
ret |
@@: |
mov eax, [ebx] |
mov ecx, [ebx+12] |
mov edx, [ebx+16] |
mov eax, [ebx+4] |
test eax, 0x1FF |
jz .alignedstart |
push edx |
mov edx, [ebx+4] |
mov edx, [ebx+8] |
shrd eax, edx, 9 |
pop edx |
mov [ntfs_cur_offs], eax |
mov [ntfs_cur_size], 1 |
mov [ntfs_cur_buf], ntfs_bitmap_buf |
mov [ebp+NTFS.ntfs_cur_offs], eax |
mov [ebp+NTFS.ntfs_cur_size], 1 |
lea eax, [ebp+NTFS.ntfs_bitmap_buf] |
mov [ebp+NTFS.ntfs_cur_buf], eax |
call ntfs_read_attr.continue |
mov eax, [ebx] |
mov eax, [ebx+4] |
and eax, 0x1FF |
lea esi, [ntfs_bitmap_buf+eax] |
sub eax, [ntfs_cur_read] |
lea esi, [ebp+NTFS.ntfs_bitmap_buf+eax] |
sub eax, [ebp+NTFS.ntfs_cur_read] |
jae .eof0 |
neg eax |
push ecx |
1202,115 → 1328,113 |
jnz @f |
.retok: |
popad |
call ntfs_unlock |
xor eax, eax |
ret |
@@: |
cmp [ntfs_cur_read], 0x200 |
cmp [ebp+NTFS.ntfs_cur_read], 0x200 |
jz .alignedstart |
.eof_ebx: |
popad |
jmp .eof |
.alignedstart: |
mov eax, [ebx] |
mov eax, [ebx+4] |
push edx |
mov edx, [ebx+4] |
mov edx, [ebx+8] |
add eax, 511 |
adc edx, 0 |
shrd eax, edx, 9 |
pop edx |
.zero1: |
mov [ntfs_cur_offs], eax |
mov [ntfs_cur_buf], edx |
mov [ebp+NTFS.ntfs_cur_offs], eax |
mov [ebp+NTFS.ntfs_cur_buf], edx |
mov eax, ecx |
shr eax, 9 |
mov [ntfs_cur_size], eax |
add eax, [ntfs_cur_offs] |
mov [ebp+NTFS.ntfs_cur_size], eax |
add eax, [ebp+NTFS.ntfs_cur_offs] |
push eax |
call ntfs_read_attr.continue |
pop [ntfs_cur_offs] |
mov eax, [ntfs_cur_read] |
pop [ebp+NTFS.ntfs_cur_offs] |
mov eax, [ebp+NTFS.ntfs_cur_read] |
add [esp+10h], eax |
mov eax, ecx |
and eax, not 0x1FF |
cmp [ntfs_cur_read], eax |
cmp [ebp+NTFS.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 |
add edx, [ebp+NTFS.ntfs_cur_read] |
mov [ebp+NTFS.ntfs_cur_size], 1 |
lea eax, [ebp+NTFS.ntfs_bitmap_buf] |
mov [ebp+NTFS.ntfs_cur_buf], eax |
call ntfs_read_attr.continue |
cmp [ntfs_cur_read], ecx |
cmp [ebp+NTFS.ntfs_cur_read], ecx |
jb @f |
mov [ntfs_cur_read], ecx |
mov [ebp+NTFS.ntfs_cur_read], ecx |
@@: |
xchg ecx, [ntfs_cur_read] |
xchg ecx, [ebp+NTFS.ntfs_cur_read] |
push ecx |
mov edi, edx |
mov esi, ntfs_bitmap_buf |
lea esi, [ebp+NTFS.ntfs_bitmap_buf] |
add [esp+10h+4], ecx |
rep movsb |
pop ecx |
xor eax, eax |
cmp ecx, [ntfs_cur_read] |
cmp ecx, [ebp+NTFS.ntfs_cur_read] |
jz @f |
mov al, ERROR_END_OF_FILE |
@@: |
mov [esp+1Ch], eax |
call ntfs_unlock |
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: |
; ntfs_ReadFolder - NTFS implementation of reading a folder |
; in: ebp = pointer to NTFS structure |
; in: esi+[esp+4] = name |
; in: ebx = pointer to parameters from sysfunc 70 |
; out: eax, ebx = return values for sysfunc 70 |
;---------------------------------------------------------------- |
ntfs_ReadFolder: |
call ntfs_lock |
mov eax, 5 ; root cluster |
cmp byte [esi], 0 |
jz .doit |
call ntfs_find_lfn |
stdcall ntfs_find_lfn, [esp+4] |
jnc .doit2 |
.notfound: |
or ebx, -1 |
push ERROR_FILE_NOT_FOUND |
.pop_ret: |
call ntfs_unlock |
pop eax |
ret |
.doit: |
mov [ntfs_cur_iRecord], eax |
mov [ebp+NTFS.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 |
mov [ebp+NTFS.ntfs_cur_attr], 0x10 ; $STANDARD_INFORMATION |
and [ebp+NTFS.ntfs_cur_offs], 0 |
mov [ebp+NTFS.ntfs_cur_size], 1 |
lea eax, [ebp+NTFS.ntfs_bitmap_buf] |
mov [ebp+NTFS.ntfs_cur_buf], eax |
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 |
mov [ebp+NTFS.ntfs_cur_attr], 0x90 ; $INDEX_ROOT |
and [ebp+NTFS.ntfs_cur_offs], 0 |
mov eax, [ebp+NTFS.cur_index_size] |
mov [ebp+NTFS.ntfs_cur_size], eax |
mov eax, [ebp+NTFS.cur_index_buf] |
mov [ebp+NTFS.ntfs_cur_buf], eax |
call ntfs_read_attr |
jnc .ok |
cmp [hd_error], 0 |
test eax, eax |
jz .notfound |
or ebx, -1 |
push 11 |
jmp .pop_ret |
.ok: |
cmp [ntfs_cur_read], 0x20 |
cmp [ebp+NTFS.ntfs_cur_read], 0x20 |
jae @f |
or ebx, -1 |
.fserr: |
1318,14 → 1442,14 |
jmp .pop_ret |
@@: |
pushad |
mov esi, [ntfs_data.cur_index_buf] |
mov esi, [ebp+NTFS.cur_index_buf] |
mov eax, [esi+14h] |
add eax, 10h |
cmp [ntfs_cur_read], eax |
cmp [ebp+NTFS.ntfs_cur_read], eax |
jae .readok1 |
add eax, 1FFh |
shr eax, 9 |
cmp eax, [ntfs_data.cur_index_size] |
cmp eax, [ebp+NTFS.cur_index_size] |
ja @f |
popad |
jmp .fserr |
1332,53 → 1456,51 |
@@: |
; reallocate |
push eax |
push [ntfs_data.cur_index_buf] |
push [ebp+NTFS.cur_index_buf] |
call kernel_free |
pop eax |
mov [ntfs_data.cur_index_size], eax |
mov [ebp+NTFS.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 |
and [ebp+NTFS.cur_index_size], 0 |
and [ebp+NTFS.cur_index_buf], 0 |
.nomem: |
call ntfs_unlock |
popad |
or ebx, -1 |
movi eax, 12 |
ret |
@@: |
mov [ntfs_data.cur_index_buf], eax |
mov [ebp+NTFS.cur_index_buf], eax |
popad |
jmp .doit2 |
.readok1: |
mov ebp, [esi+8] ; subnode_size |
shr ebp, 9 |
cmp ebp, [ntfs_data.cur_index_size] |
mov edx, [esi+8] ; subnode_size |
shr edx, 9 |
mov [ebp+NTFS.cur_subnode_size], edx |
cmp edx, [ebp+NTFS.cur_index_size] |
jbe .ok2 |
push esi ebp |
push ebp |
push esi edx |
push edx |
call kernel_alloc |
pop ebp esi |
pop edx esi |
test eax, eax |
jz .nomem |
mov edi, eax |
mov ecx, [ntfs_data.cur_index_size] |
mov ecx, [ebp+NTFS.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] |
mov [ebp+NTFS.cur_index_size], edx |
push [ebp+NTFS.cur_index_buf] |
call kernel_free |
pop ebp esi |
mov [ntfs_data.cur_index_buf], esi |
mov [ebp+NTFS.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] |
mov edx, [ebx+16] |
push dword [ebx+8] ; read ANSI/UNICODE name |
; init header |
mov edi, edx |
mov ecx, 32/4 |
1385,13 → 1507,14 |
xor eax, eax |
rep stosd |
mov byte [edx], 1 ; version |
mov ecx, [esp+4+18h] |
mov ecx, [ebx+12] |
mov ebx, [ebx+4] |
push edx |
mov edx, esp |
; edi -> BDFE, esi -> current index data, ebp = subnode size, ebx = first wanted block, |
; edi -> BDFE, esi -> current index data, ebx = first wanted block, |
; ecx = number of blocks to read |
; edx -> parameters block: dd <output>, dd <flags> |
cmp [ntfs_cur_iRecord], 5 |
cmp [ebp+NTFS.ntfs_cur_iRecord], 5 |
jz .skip_specials |
; dot and dotdot entries |
push esi |
1413,38 → 1536,39 |
.dump_root_done: |
; now dump all subnodes |
push ecx edi |
mov edi, ntfs_bitmap_buf |
mov [ntfs_cur_buf], edi |
lea edi, [ebp+NTFS.ntfs_bitmap_buf] |
mov [ebp+NTFS.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 |
mov [ebp+NTFS.ntfs_cur_attr], 0xB0 ; $BITMAP |
and [ebp+NTFS.ntfs_cur_offs], 0 |
mov [ebp+NTFS.ntfs_cur_size], 2 |
call ntfs_read_attr |
pop edi ecx |
push 0 ; save offset in $BITMAP attribute |
and [ntfs_cur_offs], 0 |
and [ebp+NTFS.ntfs_cur_offs], 0 |
.dumploop: |
mov [ntfs_cur_attr], 0xA0 |
mov [ntfs_cur_size], ebp |
mov eax, [ntfs_data.cur_index_buf] |
mov [ebp+NTFS.ntfs_cur_attr], 0xA0 |
mov eax, [ebp+NTFS.cur_subnode_size] |
mov [ebp+NTFS.ntfs_cur_size], eax |
mov eax, [ebp+NTFS.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 |
mov [ebp+NTFS.ntfs_cur_buf], eax |
push [ebp+NTFS.ntfs_cur_offs] |
mov eax, [ebp+NTFS.ntfs_cur_offs] |
imul eax, [ebp+NTFS.cur_subnode_size] |
mov [ebp+NTFS.ntfs_cur_offs], eax |
call ntfs_read_attr |
pop [ntfs_cur_offs] |
mov eax, ebp |
pop [ebp+NTFS.ntfs_cur_offs] |
mov eax, [ebp+NTFS.cur_subnode_size] |
shl eax, 9 |
cmp [ntfs_cur_read], eax |
cmp [ebp+NTFS.ntfs_cur_read], eax |
jnz .done |
push eax |
mov eax, [ntfs_cur_offs] |
mov eax, [ebp+NTFS.ntfs_cur_offs] |
and eax, 0x400*8-1 |
bt dword [ntfs_bitmap_buf], eax |
bt dword [ebp+NTFS.ntfs_bitmap_buf], eax |
pop eax |
jnc .dump_subnode_done |
cmp dword [esi], 'INDX' |
1464,26 → 1588,26 |
add esi, eax |
jmp .dump_subnode |
.dump_subnode_done: |
inc [ntfs_cur_offs] |
test [ntfs_cur_offs], 0x400*8-1 |
inc [ebp+NTFS.ntfs_cur_offs] |
test [ebp+NTFS.ntfs_cur_offs], 0x400*8-1 |
jnz .dumploop |
mov [ntfs_cur_attr], 0xB0 |
mov [ebp+NTFS.ntfs_cur_attr], 0xB0 |
push ecx edi |
mov edi, ntfs_bitmap_buf |
mov [ntfs_cur_buf], edi |
lea edi, [ebp+NTFS.ntfs_bitmap_buf] |
mov [ebp+NTFS.ntfs_cur_buf], edi |
mov ecx, 0x400/4 |
xor eax, eax |
rep stosd |
pop edi ecx |
pop eax |
push [ntfs_cur_offs] |
push [ebp+NTFS.ntfs_cur_offs] |
inc eax |
mov [ntfs_cur_offs], eax |
mov [ntfs_cur_size], 2 |
mov [ebp+NTFS.ntfs_cur_offs], eax |
mov [ebp+NTFS.ntfs_cur_size], 2 |
push eax |
call ntfs_read_attr |
pop eax |
pop [ntfs_cur_offs] |
pop [ebp+NTFS.ntfs_cur_offs] |
push eax |
jmp .dumploop |
.done: |
1498,6 → 1622,7 |
@@: |
mov [esp+1Ch], eax |
mov [esp+10h], ebx |
call ntfs_unlock |
popad |
ret |
|
1517,14 → 1642,14 |
stosd |
scasd |
push edx |
mov eax, dword [ntfs_bitmap_buf] |
mov edx, dword [ntfs_bitmap_buf+4] |
mov eax, dword [ebp+NTFS.ntfs_bitmap_buf] |
mov edx, dword [ebp+NTFS.ntfs_bitmap_buf+4] |
call ntfs_datetime_to_bdfe |
mov eax, dword [ntfs_bitmap_buf+0x18] |
mov edx, dword [ntfs_bitmap_buf+0x1C] |
mov eax, dword [ebp+NTFS.ntfs_bitmap_buf+0x18] |
mov edx, dword [ebp+NTFS.ntfs_bitmap_buf+0x1C] |
call ntfs_datetime_to_bdfe |
mov eax, dword [ntfs_bitmap_buf+8] |
mov edx, dword [ntfs_bitmap_buf+0xC] |
mov eax, dword [ebp+NTFS.ntfs_bitmap_buf+8] |
mov edx, dword [ebp+NTFS.ntfs_bitmap_buf+0xC] |
call ntfs_datetime_to_bdfe |
pop edx |
xor eax, eax |
1733,90 → 1858,69 |
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: |
; ntfs_Rewrite - NTFS implementation of creating a new file |
; in: ebp = pointer to NTFS structure |
; in: esi+[esp+4] = name |
; in: ebx = pointer to parameters from sysfunc 70 |
; out: eax, ebx = return values for sysfunc 70 |
;---------------------------------------------------------------- |
ntfs_Rewrite: |
ntfs_CreateFolder: |
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: |
; ntfs_Write - NTFS implementation of writing to file |
; in: ebp = pointer to NTFS structure |
; in: esi+[esp+4] = name |
; in: ebx = pointer to parameters from sysfunc 70 |
; out: eax, ebx = return values for sysfunc 70 |
;---------------------------------------------------------------- |
ntfs_Write: |
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: |
ntfs_SetFileEnd: |
ntfs_SetFileInfo: |
ntfs_Delete: |
mov eax, ERROR_UNSUPPORTED_FS |
ret |
|
ntfs_HdGetFileInfo: |
;---------------------------------------------------------------- |
; ntfs_GetFileInfo - NTFS implementation of getting file info |
; in: ebp = pointer to NTFS structure |
; in: esi+[esp+4] = name |
; in: ebx = pointer to parameters from sysfunc 70 |
; out: eax, ebx = return values for sysfunc 70 |
;---------------------------------------------------------------- |
ntfs_GetFileInfo: |
cmp byte [esi], 0 |
jnz @f |
movi eax, 2 |
ret |
@@: |
call ntfs_find_lfn |
call ntfs_lock |
stdcall ntfs_find_lfn, [esp+4] |
jnc .doit |
test eax, eax |
movi eax, ERROR_FILE_NOT_FOUND |
cmp [hd_error], 0 |
jz @f |
mov al, 11 |
@@: |
push eax |
call ntfs_unlock |
pop eax |
ret |
.doit: |
push esi edi |
mov esi, eax |
mov edi, edx |
mov edi, [ebx+16] |
xor eax, eax |
call ntfs_direntry_to_bdfe |
pop edi esi |
call ntfs_unlock |
xor eax, eax |
ret |
|