Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 6272 → Rev 6273

/kernel/trunk/fs/ntfs.inc
29,8 → 29,10
 
; Offsets:
; record header
magic = 0
updateSequenceOffset = 4
updateSequenceSize = 6
; FileRecord header
reuseCounter = 16
hardLinkCounter = 12h
attributeOffset = 14h
50,7 → 52,7
attributeID = 14
; resident attribute header
sizeWithoutHeader = 10h
; attributeOffset = 14h
attributeOffset = 14h
indexedFlag = 16h
; non resident attribute header
firstVCN = 10h
60,13 → 62,19
attributeRealSize = 30h
initialDataSize = 38h
; $IndexRoot
indexedAttributesType = 0
collationRule = 4
indexRecordSize = 8
indexRecordSizeClus = 12
rootNode = 16
; IndexRecord header
recordVCN = 16
recordNode = 18h
; node header
indexOffset = 0
nodeRealSize = 4
nodeAllocatedSize = 8
nonLeafFlag = 12
; $Filename index
fileRecordReference = 0
fileReferenceReuse = 6
103,13 → 111,13
mftBitmapSize dd ? ; bytes readen
mftBitmapLocation dd ? ; starting sector
 
ntfs_cur_attr dd ? ; attribute type
ntfs_cur_iRecord dd ? ; number of fileRecord in MFT
ntfs_cur_offs dd ? ; attribute VCN in sectors
ntfs_cur_size dd ? ; max sectors to read
ntfs_cur_buf dd ?
ntfs_cur_read dd ? ; bytes readen
ntfsLastRead dd ? ; last readen block of sectors
cur_attr dd ? ; attribute type
cur_iRecord dd ? ; number of fileRecord in MFT
cur_offs dd ? ; attribute VCN in sectors
cur_size dd ? ; max sectors to read
cur_buf dd ?
cur_read dd ? ; bytes readen
LastRead dd ? ; last readen block of sectors
newMftRecord dd ? ; number of fileRecord in MFT
fileDataStart dd ? ; starting cluster
fileDataSize dd ? ; in clusters
116,22 → 124,22
fileRealSize dd ? ; in bytes
indexOffset dd ?
nodeLastRead dd ?
ntfs_bCanContinue db ?
ntfsFolder db ?
ntfsWriteAttr db ? ; Warning: Don't forget to turn off!!!
ntfsFragmentCount db ?
fragmentCount db ?
bCanContinue db ?
bFolder db ?
bWriteAttr db ? ; Warning: Don't forget to turn off!!!
 
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 ?
attr_iRecord dd ?
attr_iBaseRecord dd ?
attr_offs dd ?
attr_list dd ?
attr_size dq ?
cur_tail dd ?
 
ntfs_attrlist_buf rb 0x400
ntfs_attrlist_mft_buf rb 0x400
ntfs_bitmap_buf rb 0x400
attrlist_buf rb 0x400
attrlist_mft_buf rb 0x400
bitmap_buf rb 0x400
ends
 
; NTFS external functions
279,7 → 287,7
mov ecx, [ebp+PARTITION.Disk]
mov [eax+NTFS.Disk], ecx
mov [eax+NTFS.FSUserFunctions], ntfs_user_functions
mov [eax+NTFS.ntfsWriteAttr], 0
mov [eax+NTFS.bWriteAttr], 0
 
push ebx ebp esi
mov ebp, eax
397,7 → 405,7
test eax, eax
jz .failFreeIndex
mov [ebp+NTFS.BitmapBuffer], eax
mov [ebp+NTFS.ntfs_cur_buf], eax
mov [ebp+NTFS.cur_buf], eax
mov eax, [ebp+NTFS.BitmapTotalSize]
add eax, [ebp+NTFS.mft_cluster]
shr eax, 3+2 ; reserve 1/8 of partition for $MFT
409,7 → 417,7
push eax
push eax
shl eax, 3
mov [ebp+NTFS.ntfs_cur_size], eax
mov [ebp+NTFS.cur_size], eax
call alloc_pages
test eax, eax
pop ecx
417,36 → 425,36
add eax, 3
mov ebx, [ebp+NTFS.BitmapBuffer]
call commit_pages
mov [ebp+NTFS.ntfs_cur_iRecord], 6
mov [ebp+NTFS.ntfs_cur_attr], 0x80
mov [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.cur_iRecord], 6
mov [ebp+NTFS.cur_attr], 0x80
mov [ebp+NTFS.cur_offs], 0
call ntfs_read_attr
jc .failFreeBitmap
mov eax, [ebp+NTFS.ntfs_cur_read]
mov eax, [ebp+NTFS.cur_read]
mov [ebp+NTFS.BitmapSize], eax
mov eax, [ebp+NTFS.ntfsLastRead]
mov eax, [ebp+NTFS.LastRead]
mov [ebp+NTFS.BitmapLocation], eax
; read MFT $BITMAP attribute
mov eax, [ebp+NTFS.sectors_per_cluster]
mov [ebp+NTFS.ntfs_cur_size], eax
mov [ebp+NTFS.cur_size], eax
shl eax, 9
stdcall kernel_alloc, eax
test eax, eax
jz .failFreeBitmap
mov [ebp+NTFS.mftBitmapBuffer], eax
mov [ebp+NTFS.ntfs_cur_buf], eax
mov [ebp+NTFS.ntfs_cur_iRecord], 0
mov [ebp+NTFS.ntfs_cur_attr], 0xB0
mov [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.cur_buf], eax
mov [ebp+NTFS.cur_iRecord], 0
mov [ebp+NTFS.cur_attr], 0xB0
mov [ebp+NTFS.cur_offs], 0
call ntfs_read_attr
mov eax, [ebp+NTFS.ntfs_cur_read]
mov eax, [ebp+NTFS.cur_read]
cmp eax, 4
jc .failFreeBitmapMFT
mov ecx, [ebp+NTFS.ntfs_attr_offs]
mov ecx, [ebp+NTFS.attr_offs]
cmp byte [ecx+nonResidentFlag], 1
jnz .failFreeBitmapMFT
mov [ebp+NTFS.mftBitmapSize], eax
mov eax, [ebp+NTFS.ntfsLastRead]
mov eax, [ebp+NTFS.LastRead]
mov [ebp+NTFS.mftBitmapLocation], eax
 
mov eax, ebp
550,31 → 558,31
ret
 
ntfs_read_attr:
; [ebp+NTFS.ntfsWriteAttr]=1 -> write attribute
; [ebp+NTFS.bWriteAttr]=1 -> write attribute
; in:
; [ebp+NTFS.ntfs_cur_iRecord] = number of fileRecord
; [ebp+NTFS.ntfs_cur_attr] = attribute type
; [ebp+NTFS.ntfs_cur_offs] = attribute VCN in sectors
; [ebp+NTFS.ntfs_cur_buf] -> buffer for data
; [ebp+NTFS.ntfs_cur_size] = max sectors to read
; [ebp+NTFS.cur_iRecord] = number of fileRecord
; [ebp+NTFS.cur_attr] = attribute type
; [ebp+NTFS.cur_offs] = attribute VCN in sectors
; [ebp+NTFS.cur_buf] -> buffer for data
; [ebp+NTFS.cur_size] = max sectors to read
; out:
; [ebp+NTFS.ntfs_cur_read] = bytes readen
; [ebp+NTFS.cur_read] = bytes readen
; CF=1 -> failed, eax = disk error code, eax=0 -> something with FS
xor eax, eax
pushad
and [ebp+NTFS.ntfs_cur_read], 0
cmp [ebp+NTFS.ntfs_cur_iRecord], 0
and [ebp+NTFS.cur_read], 0
cmp [ebp+NTFS.cur_iRecord], 0
jnz .nomft
cmp [ebp+NTFS.ntfs_cur_attr], 0x80
cmp [ebp+NTFS.cur_attr], 0x80
jnz .nomft
mov eax, [ebp+NTFS.mft_retrieval_end]
inc eax
mul [ebp+NTFS.sectors_per_cluster]
cmp eax, [ebp+NTFS.ntfs_cur_offs]
cmp eax, [ebp+NTFS.cur_offs]
jbe .nomft
; precalculated part of $Mft $DATA
mov esi, [ebp+NTFS.mft_retrieval]
mov eax, [ebp+NTFS.ntfs_cur_offs]
mov eax, [ebp+NTFS.cur_offs]
xor edx, edx
div [ebp+NTFS.sectors_per_cluster]
; eax = VCN, edx = offset in sectors from beginning of cluster
603,15 → 611,15
; eax = sector on partition
pop edx
add eax, edx
mov ebx, [ebp+NTFS.ntfs_cur_buf]
mov ebx, [ebp+NTFS.cur_buf]
pop ecx
neg ecx
imul ecx, [ebp+NTFS.sectors_per_cluster]
sub ecx, edx
mov [ebp+NTFS.ntfsLastRead], eax
cmp ecx, [ebp+NTFS.ntfs_cur_size]
mov [ebp+NTFS.LastRead], eax
cmp ecx, [ebp+NTFS.cur_size]
jb @f
mov ecx, [ebp+NTFS.ntfs_cur_size]
mov ecx, [ebp+NTFS.cur_size]
@@:
; ecx = number of sequential sectors to read
push eax
619,17 → 627,17
pop edx
test eax, eax
jnz .errread
add [ebp+NTFS.ntfs_cur_read], 0x200
dec [ebp+NTFS.ntfs_cur_size]
inc [ebp+NTFS.ntfs_cur_offs]
add [ebp+NTFS.cur_read], 0x200
dec [ebp+NTFS.cur_size]
inc [ebp+NTFS.cur_offs]
add ebx, 0x200
mov [ebp+NTFS.ntfs_cur_buf], ebx
mov [ebp+NTFS.cur_buf], ebx
lea eax, [edx+1]
loop @b
pop ecx
xor eax, eax
xor edx, edx
cmp [ebp+NTFS.ntfs_cur_size], eax
cmp [ebp+NTFS.cur_size], eax
jz @f
add esi, 8
push eax
653,12 → 661,12
.nomft:
; 1. Read file record.
; N.B. This will do recursive call of read_attr for $MFT::$Data.
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
mov eax, [ebp+NTFS.cur_iRecord]
mov [ebp+NTFS.attr_iRecord], eax
and [ebp+NTFS.attr_list], 0
or dword [ebp+NTFS.attr_size], -1
or dword [ebp+NTFS.attr_size+4], -1
or [ebp+NTFS.attr_iBaseRecord], -1
call ntfs_read_file_record
jc .errret
; 2. Find required attribute.
670,7 → 678,7
jz @f
mov eax, [eax+20h]
.beginfindattr:
mov [ebp+NTFS.ntfs_attr_iRecord], eax
mov [ebp+NTFS.attr_iRecord], eax
call ntfs_read_file_record
jc .errret
jmp @f
681,18 → 689,18
mov eax, [ebp+NTFS.frs_buffer]
movzx ecx, word [eax+14h]
add eax, ecx
mov ecx, [ebp+NTFS.ntfs_cur_attr]
and [ebp+NTFS.ntfs_attr_offs], 0
mov ecx, [ebp+NTFS.cur_attr]
and [ebp+NTFS.attr_offs], 0
.scanattr:
cmp dword [eax], -1
jz .scandone
cmp dword [eax], ecx
jz .okattr
cmp [ebp+NTFS.ntfs_attr_iBaseRecord], -1
cmp [ebp+NTFS.attr_iBaseRecord], -1
jnz .scancont
cmp dword [eax], 0x20 ; $ATTR_LIST
jnz .scancont
mov [ebp+NTFS.ntfs_attr_list], eax
mov [ebp+NTFS.attr_list], eax
jmp .scancont
.okattr:
; ignore named $DATA attributes (aka NTFS streams)
701,30 → 709,30
cmp byte [eax+9], 0
jnz .scancont
@@:
mov [ebp+NTFS.ntfs_attr_offs], eax
mov [ebp+NTFS.attr_offs], eax
.scancont:
add eax, [eax+4]
jmp .scanattr
.continue:
pushad
and [ebp+NTFS.ntfs_cur_read], 0
and [ebp+NTFS.cur_read], 0
.scandone:
; c) Check for required offset and length
mov ecx, [ebp+NTFS.ntfs_attr_offs]
mov ecx, [ebp+NTFS.attr_offs]
jecxz .noattr
push [ebp+NTFS.ntfs_cur_size]
push [ebp+NTFS.ntfs_cur_read]
push [ebp+NTFS.cur_size]
push [ebp+NTFS.cur_read]
call .doreadattr
pop edx
pop ecx
jc @f
cmp [ebp+NTFS.ntfs_bCanContinue], 0
cmp [ebp+NTFS.bCanContinue], 0
jz @f
sub edx, [ebp+NTFS.ntfs_cur_read]
sub edx, [ebp+NTFS.cur_read]
neg edx
shr edx, 9
sub ecx, edx
mov [ebp+NTFS.ntfs_cur_size], ecx
mov [ebp+NTFS.cur_size], ecx
jnz .not_in_cur
@@:
popad
731,14 → 739,14
ret
.noattr:
.not_in_cur:
cmp [ebp+NTFS.ntfs_cur_attr], 0x20
cmp [ebp+NTFS.cur_attr], 0x20
jz @f
mov ecx, [ebp+NTFS.ntfs_attr_list]
mov ecx, [ebp+NTFS.attr_list]
test ecx, ecx
jnz .lookattr
.ret_is_attr:
and dword [esp+28], 0
cmp [ebp+NTFS.ntfs_attr_offs], 1 ; CF set <=> ntfs_attr_offs == 0
cmp [ebp+NTFS.attr_offs], 1 ; CF set <=> attr_offs == 0
popad
ret
.lookattr:
745,47 → 753,47
; required attribute or required offset was not found in base record;
; it may be present in auxiliary records;
; scan $ATTR_LIST
mov eax, [ebp+NTFS.ntfs_attr_iBaseRecord]
mov eax, [ebp+NTFS.attr_iBaseRecord]
cmp eax, -1
jz @f
call ntfs_read_file_record
jc .errret
or [ebp+NTFS.ntfs_attr_iBaseRecord], -1
or [ebp+NTFS.attr_iBaseRecord], -1
@@:
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
push [ebp+NTFS.cur_offs]
push [ebp+NTFS.cur_size]
push [ebp+NTFS.cur_read]
push [ebp+NTFS.cur_buf]
push dword [ebp+NTFS.attr_size]
push dword [ebp+NTFS.attr_size+4]
or dword [ebp+NTFS.attr_size], -1
or dword [ebp+NTFS.attr_size+4], -1
and [ebp+NTFS.cur_offs], 0
mov [ebp+NTFS.cur_size], 2
and [ebp+NTFS.cur_read], 0
lea eax, [ebp+NTFS.attrlist_buf]
cmp [ebp+NTFS.cur_iRecord], 0
jnz @f
lea eax, [ebp+NTFS.ntfs_attrlist_mft_buf]
lea eax, [ebp+NTFS.attrlist_mft_buf]
@@:
mov [ebp+NTFS.ntfs_cur_buf], eax
mov [ebp+NTFS.cur_buf], eax
push eax
call .doreadattr
pop esi
mov edx, 1
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]
pop dword [ebp+NTFS.attr_size+4]
pop dword [ebp+NTFS.attr_size]
mov ecx, [ebp+NTFS.cur_read]
pop [ebp+NTFS.cur_buf]
pop [ebp+NTFS.cur_read]
pop [ebp+NTFS.cur_size]
pop [ebp+NTFS.cur_offs]
jc .errret
or edi, -1
lea ecx, [ecx+esi-1Ah]
.scanliststart:
push ecx
mov eax, [ebp+NTFS.ntfs_cur_attr]
mov eax, [ebp+NTFS.cur_attr]
.scanlist:
cmp esi, [esp]
jae .scanlistdone
806,8 → 814,8
mov eax, [esi+8]
test eax, eax
jnz .testf
mov eax, dword [ebp+NTFS.ntfs_attr_size]
and eax, dword [ebp+NTFS.ntfs_attr_size+4]
mov eax, dword [ebp+NTFS.attr_size]
and eax, dword [ebp+NTFS.attr_size+4]
cmp eax, -1
jnz .testfz
; if attribute is in auxiliary records, its size is defined only in first
824,7 → 832,7
mov eax, [ebp+NTFS.frs_buffer]
movzx ecx, word [eax+14h]
add eax, ecx
mov ecx, [ebp+NTFS.ntfs_cur_attr]
mov ecx, [ebp+NTFS.cur_attr]
@@:
cmp dword [eax], -1
jz .errret2_pop
842,19 → 850,19
cmp byte [eax+8], 0
jnz .sdnores
mov eax, [eax+10h]
mov dword [ebp+NTFS.ntfs_attr_size], eax
and dword [ebp+NTFS.ntfs_attr_size+4], 0
mov dword [ebp+NTFS.attr_size], eax
and dword [ebp+NTFS.attr_size+4], 0
jmp .testfz
.sdnores:
mov ecx, [eax+30h]
mov dword [ebp+NTFS.ntfs_attr_size], ecx
mov dword [ebp+NTFS.attr_size], ecx
mov ecx, [eax+34h]
mov dword [ebp+NTFS.ntfs_attr_size+4], ecx
mov dword [ebp+NTFS.attr_size+4], ecx
.testfz:
xor eax, eax
.testf:
imul eax, [ebp+NTFS.sectors_per_cluster]
cmp eax, [ebp+NTFS.ntfs_cur_offs]
cmp eax, [ebp+NTFS.cur_offs]
pop eax
ja @f
mov edi, [esi+10h] ; keep previous iRecord
867,28 → 875,28
popad
ret
@@:
mov eax, [ebp+NTFS.ntfs_cur_iRecord]
mov [ebp+NTFS.ntfs_attr_iBaseRecord], eax
mov eax, [ebp+NTFS.cur_iRecord]
mov [ebp+NTFS.attr_iBaseRecord], eax
mov eax, edi
jmp .beginfindattr
.scanlistdone:
pop ecx
sub ecx, ebp
sub ecx, NTFS.ntfs_attrlist_buf-1Ah
cmp [ebp+NTFS.ntfs_cur_iRecord], 0
sub ecx, NTFS.attrlist_buf-1Ah
cmp [ebp+NTFS.cur_iRecord], 0
jnz @f
sub ecx, NTFS.ntfs_attrlist_mft_buf-NTFS.ntfs_attrlist_buf
sub ecx, NTFS.attrlist_mft_buf-NTFS.attrlist_buf
@@:
cmp ecx, 0x400
jnz .scanlistfound
inc edx
push esi edi
lea esi, [ebp+NTFS.ntfs_attrlist_buf+0x200]
lea edi, [ebp+NTFS.ntfs_attrlist_buf]
cmp [ebp+NTFS.ntfs_cur_iRecord], 0
lea esi, [ebp+NTFS.attrlist_buf+0x200]
lea edi, [ebp+NTFS.attrlist_buf]
cmp [ebp+NTFS.cur_iRecord], 0
jnz @f
lea esi, [ebp+NTFS.ntfs_attrlist_mft_buf+0x200]
lea edi, [ebp+NTFS.ntfs_attrlist_mft_buf]
lea esi, [ebp+NTFS.attrlist_mft_buf+0x200]
lea edi, [ebp+NTFS.attrlist_mft_buf]
@@:
mov ecx, 0x200/4
rep movsd
895,43 → 903,43
mov eax, edi
pop edi esi
sub esi, 0x200
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 [ebp+NTFS.cur_offs]
push [ebp+NTFS.cur_size]
push [ebp+NTFS.cur_read]
push [ebp+NTFS.cur_buf]
push dword [ebp+NTFS.attr_size]
push dword [ebp+NTFS.attr_size+4]
or dword [ebp+NTFS.attr_size], -1
or dword [ebp+NTFS.attr_size+4], -1
mov [ebp+NTFS.cur_offs], edx
mov [ebp+NTFS.cur_size], 1
and [ebp+NTFS.cur_read], 0
mov [ebp+NTFS.cur_buf], eax
mov ecx, [ebp+NTFS.attr_list]
push esi edx edi
call .doreadattr
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]
mov ecx, [ebp+NTFS.cur_read]
pop dword [ebp+NTFS.attr_size+4]
pop dword [ebp+NTFS.attr_size]
pop [ebp+NTFS.cur_buf]
pop [ebp+NTFS.cur_read]
pop [ebp+NTFS.cur_size]
pop [ebp+NTFS.cur_offs]
jc .errret
lea ecx, [ecx+ebp+NTFS.ntfs_attrlist_buf+0x200-0x1A]
cmp [ebp+NTFS.ntfs_cur_iRecord], 0
lea ecx, [ecx+ebp+NTFS.attrlist_buf+0x200-0x1A]
cmp [ebp+NTFS.cur_iRecord], 0
jnz .scanliststart
add ecx, NTFS.ntfs_attrlist_mft_buf-NTFS.ntfs_attrlist_buf
add ecx, NTFS.attrlist_mft_buf-NTFS.attrlist_buf
jmp .scanliststart
 
.doreadattr:
mov [ebp+NTFS.ntfs_bCanContinue], 0
mov [ebp+NTFS.bCanContinue], 0
cmp byte [ecx+8], 0
jnz .nonresident
mov eax, [ecx+10h] ; length
mov esi, eax
mov edx, [ebp+NTFS.ntfs_cur_offs]
mov edx, [ebp+NTFS.cur_offs]
shr eax, 9
cmp eax, edx
jb .okret
940,7 → 948,7
movzx eax, word [ecx+14h]
add edx, eax
add edx, ecx ; edx -> data
mov eax, [ebp+NTFS.ntfs_cur_size]
mov eax, [ebp+NTFS.cur_size]
cmp eax, (0xFFFFFFFF shr 9)+1
jbe @f
mov eax, (0xFFFFFFFF shr 9)+1
951,17 → 959,17
mov eax, esi
@@:
; eax = length, edx -> data
mov [ebp+NTFS.ntfs_cur_read], eax
mov [ebp+NTFS.cur_read], eax
mov ecx, eax
mov eax, edx
mov ebx, [ebp+NTFS.ntfs_cur_buf]
mov ebx, [ebp+NTFS.cur_buf]
call memmove
and [ebp+NTFS.ntfs_cur_size], 0 ; CF=0
and [ebp+NTFS.cur_size], 0 ; CF=0
ret
.nonresident:
; Not all auxiliary records contain correct FileSize info
mov eax, dword [ebp+NTFS.ntfs_attr_size]
mov edx, dword [ebp+NTFS.ntfs_attr_size+4]
mov eax, dword [ebp+NTFS.attr_size]
mov edx, dword [ebp+NTFS.attr_size+4]
push eax
and eax, edx
cmp eax, -1
969,43 → 977,43
jnz @f
mov eax, [ecx+30h] ; FileSize
mov edx, [ecx+34h]
mov dword [ebp+NTFS.ntfs_attr_size], eax
mov dword [ebp+NTFS.ntfs_attr_size+4], edx
mov dword [ebp+NTFS.attr_size], eax
mov dword [ebp+NTFS.attr_size+4], edx
@@:
add eax, 0x1FF
adc edx, 0
shrd eax, edx, 9
sub eax, [ebp+NTFS.ntfs_cur_offs]
sub eax, [ebp+NTFS.cur_offs]
ja @f
; return with nothing read
and [ebp+NTFS.ntfs_cur_size], 0
and [ebp+NTFS.cur_size], 0
.okret:
clc
ret
@@:
; reduce read length
and [ebp+NTFS.ntfs_cur_tail], 0
cmp [ebp+NTFS.ntfs_cur_size], eax
and [ebp+NTFS.cur_tail], 0
cmp [ebp+NTFS.cur_size], eax
jb @f
mov [ebp+NTFS.ntfs_cur_size], eax
mov eax, dword [ebp+NTFS.ntfs_attr_size]
mov [ebp+NTFS.cur_size], eax
mov eax, dword [ebp+NTFS.attr_size]
and eax, 0x1FF
mov [ebp+NTFS.ntfs_cur_tail], eax
mov [ebp+NTFS.cur_tail], eax
@@:
cmp [ebp+NTFS.ntfs_cur_size], 0
cmp [ebp+NTFS.cur_size], 0
jz .okret
mov eax, [ebp+NTFS.ntfs_cur_offs]
mov eax, [ebp+NTFS.cur_offs]
xor edx, edx
div [ebp+NTFS.sectors_per_cluster]
sub eax, [ecx+10h] ; first_vbo
jb .okret
; eax = cluster, edx = starting sector
cmp [ebp+NTFS.ntfs_cur_attr], 0x80
cmp [ebp+NTFS.cur_attr], 0x80
jnz .sys
cmp [ebp+NTFS.ntfs_cur_iRecord], 0
cmp [ebp+NTFS.cur_iRecord], 0
jz .sys
push fs_read64_app
cmp [ebp+NTFS.ntfsWriteAttr], 1
cmp [ebp+NTFS.bWriteAttr], 1
jnz @f
mov dword[esp], fs_write64_app
jmp @f
1016,7 → 1024,7
movzx esi, word [ecx+20h] ; mcb_info_ofs
add esi, ecx
xor edi, edi
mov [ebp+NTFS.ntfsFragmentCount], 0
mov [ebp+NTFS.fragmentCount], 0
.readloop:
call ntfs_decode_mcb_entry
jnc .break
1033,12 → 1041,12
neg ecx
imul ecx, [ebp+NTFS.sectors_per_cluster]
sub ecx, edx
cmp ecx, [ebp+NTFS.ntfs_cur_size]
cmp ecx, [ebp+NTFS.cur_size]
jb @f
mov ecx, [ebp+NTFS.ntfs_cur_size]
mov ecx, [ebp+NTFS.cur_size]
@@:
mov ebx, [ebp+NTFS.ntfs_cur_buf]
mov [ebp+NTFS.ntfsLastRead], eax
mov ebx, [ebp+NTFS.cur_buf]
mov [ebp+NTFS.LastRead], eax
push ecx
xor edx, edx
call dword[esp+18h]
1045,23 → 1053,23
pop ecx
test eax, eax
jnz .errread2
sub [ebp+NTFS.ntfs_cur_size], ecx
add [ebp+NTFS.ntfs_cur_offs], ecx
sub [ebp+NTFS.cur_size], ecx
add [ebp+NTFS.cur_offs], ecx
shl ecx, 9
add [ebp+NTFS.ntfs_cur_read], ecx
add [ebp+NTFS.ntfs_cur_buf], ecx
inc [ebp+NTFS.ntfsFragmentCount]
add [ebp+NTFS.cur_read], ecx
add [ebp+NTFS.cur_buf], ecx
inc [ebp+NTFS.fragmentCount]
pop ecx
xor eax, eax
xor edx, edx
cmp [ebp+NTFS.ntfs_cur_size], 0
cmp [ebp+NTFS.cur_size], 0
jnz .readloop
add esp, 14h
mov eax, [ebp+NTFS.ntfs_cur_tail]
mov eax, [ebp+NTFS.cur_tail]
test eax, eax
jz @f
sub eax, 0x200
add [ebp+NTFS.ntfs_cur_read], eax
add [ebp+NTFS.cur_read], eax
@@:
clc
ret
1072,7 → 1080,7
ret
.break:
add esp, 14h ; CF=0
mov [ebp+NTFS.ntfs_bCanContinue], 1
mov [ebp+NTFS.bCanContinue], 1
ret
 
ntfs_read_file_record:
1086,39 → 1094,39
shrd eax, edx, 9
shr edx, 9
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
push [ebp+NTFS.attr_iRecord]
push [ebp+NTFS.attr_iBaseRecord]
push [ebp+NTFS.attr_offs]
push [ebp+NTFS.attr_list]
push dword [ebp+NTFS.attr_size+4]
push dword [ebp+NTFS.attr_size]
push [ebp+NTFS.cur_iRecord]
push [ebp+NTFS.cur_attr]
push [ebp+NTFS.cur_offs]
push [ebp+NTFS.cur_size]
push [ebp+NTFS.cur_buf]
push [ebp+NTFS.cur_read]
mov [ebp+NTFS.cur_attr], 0x80 ; $DATA
and [ebp+NTFS.cur_iRecord], 0 ; $Mft
mov [ebp+NTFS.cur_offs], eax
shr ecx, 9
mov [ebp+NTFS.ntfs_cur_size], ecx
mov [ebp+NTFS.cur_size], ecx
mov eax, [ebp+NTFS.frs_buffer]
mov [ebp+NTFS.ntfs_cur_buf], eax
mov [ebp+NTFS.cur_buf], eax
call ntfs_read_attr
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]
mov edx, [ebp+NTFS.cur_read]
pop [ebp+NTFS.cur_read]
pop [ebp+NTFS.cur_buf]
pop [ebp+NTFS.cur_size]
pop [ebp+NTFS.cur_offs]
pop [ebp+NTFS.cur_attr]
pop [ebp+NTFS.cur_iRecord]
pop dword [ebp+NTFS.attr_size]
pop dword [ebp+NTFS.attr_size+4]
pop [ebp+NTFS.attr_list]
pop [ebp+NTFS.attr_offs]
pop [ebp+NTFS.attr_iBaseRecord]
pop [ebp+NTFS.attr_iRecord]
jc .ret
cmp edx, [ebp+NTFS.frs_size]
jnz .errret
1233,17 → 1241,17
ntfs_find_lfn:
; in: [esi]+[esp+4] = name
; out:
; [ebp+NTFS.ntfs_cur_iRecord] = number of MFT fileRecord
; [ebp+NTFS.cur_iRecord] = number of MFT fileRecord
; eax -> index in the parent index node
; CF=1 -> file not found, eax=0 -> error
mov [ebp+NTFS.ntfs_cur_iRecord], 5 ; start parse from root cluster
mov [ebp+NTFS.cur_iRecord], 5 ; start parse from root cluster
.doit2:
mov [ebp+NTFS.ntfs_cur_attr], 0x90 ; $INDEX_ROOT
and [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.cur_attr], 0x90 ; $INDEX_ROOT
and [ebp+NTFS.cur_offs], 0
mov eax, [ebp+NTFS.cur_index_size]
mov [ebp+NTFS.ntfs_cur_size], eax
mov [ebp+NTFS.cur_size], eax
mov eax, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.ntfs_cur_buf], eax
mov [ebp+NTFS.cur_buf], eax
call ntfs_read_attr
mov eax, 0
jnc @f
1250,13 → 1258,13
.ret:
ret 4
@@:
cmp [ebp+NTFS.ntfs_cur_read], 0x20
cmp [ebp+NTFS.cur_read], 0x20
jc .ret
pushad
mov esi, [ebp+NTFS.cur_index_buf]
mov eax, [esi+14h]
add eax, 10h
cmp [ebp+NTFS.ntfs_cur_read], eax
cmp [ebp+NTFS.cur_read], eax
jae .readok1
add eax, 1FFh
shr eax, 9
1346,22 → 1354,22
movzx eax, word [esi+8]
mov eax, [esi+eax-8]
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 [ebp+NTFS.cur_offs], eax
mov [ebp+NTFS.cur_attr], 0xA0 ; $INDEX_ALLOCATION
mov [ebp+NTFS.cur_size], edx
mov eax, [ebp+NTFS.cur_index_buf]
mov esi, eax
mov [ebp+NTFS.ntfs_cur_buf], eax
mov [ebp+NTFS.cur_buf], eax
push edx
call ntfs_read_attr
pop edx
mov eax, edx
shl eax, 9
cmp [ebp+NTFS.ntfs_cur_read], eax
cmp [ebp+NTFS.cur_read], eax
jnz .err
cmp dword [esi], 'INDX'
jnz .err
mov [ebp+NTFS.ntfs_cur_buf], esi
mov [ebp+NTFS.cur_buf], esi
mov ebx, esi
call ntfs_restore_usa
jc .err
1386,7 → 1394,7
pop esi
pop esi
mov eax, [esi]
mov [ebp+NTFS.ntfs_cur_iRecord], eax
mov [ebp+NTFS.cur_iRecord], eax
mov [esp+1Ch], esi
mov [esp+4], edi
popad
1417,9 → 1425,9
movi eax, ERROR_FILE_NOT_FOUND
ret
.found:
mov [ebp+NTFS.ntfs_cur_attr], 0x80 ; $DATA
and [ebp+NTFS.ntfs_cur_offs], 0
and [ebp+NTFS.ntfs_cur_size], 0
mov [ebp+NTFS.cur_attr], 0x80 ; $DATA
and [ebp+NTFS.cur_offs], 0
and [ebp+NTFS.cur_size], 0
call ntfs_read_attr
jnc @f
call ntfs_unlock
1450,15 → 1458,15
mov edx, [ebx+8]
shrd eax, edx, 9
pop edx
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
mov [ebp+NTFS.cur_offs], eax
mov [ebp+NTFS.cur_size], 1
lea eax, [ebp+NTFS.bitmap_buf]
mov [ebp+NTFS.cur_buf], eax
call ntfs_read_attr.continue
mov eax, [ebx+4]
and eax, 0x1FF
lea esi, [ebp+NTFS.ntfs_bitmap_buf+eax]
sub eax, [ebp+NTFS.ntfs_cur_read]
lea esi, [ebp+NTFS.bitmap_buf+eax]
sub eax, [ebp+NTFS.cur_read]
jae .eof0
neg eax
push ecx
1479,7 → 1487,7
xor eax, eax
ret
@@:
cmp [ebp+NTFS.ntfs_cur_read], 0x200
cmp [ebp+NTFS.cur_read], 0x200
jz .alignedstart
.eof_ebx:
popad
1492,41 → 1500,41
adc edx, 0
shrd eax, edx, 9
pop edx
mov [ebp+NTFS.ntfs_cur_offs], eax
mov [ebp+NTFS.ntfs_cur_buf], edx
mov [ebp+NTFS.cur_offs], eax
mov [ebp+NTFS.cur_buf], edx
mov eax, ecx
shr eax, 9
mov [ebp+NTFS.ntfs_cur_size], eax
add eax, [ebp+NTFS.ntfs_cur_offs]
mov [ebp+NTFS.cur_size], eax
add eax, [ebp+NTFS.cur_offs]
push eax
call ntfs_read_attr.continue
pop [ebp+NTFS.ntfs_cur_offs]
mov eax, [ebp+NTFS.ntfs_cur_read]
pop [ebp+NTFS.cur_offs]
mov eax, [ebp+NTFS.cur_read]
add [esp+10h], eax
mov eax, ecx
and eax, not 0x1FF
cmp [ebp+NTFS.ntfs_cur_read], eax
cmp [ebp+NTFS.cur_read], eax
jnz .eof_ebx
and ecx, 0x1FF
jz .retok
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
add edx, [ebp+NTFS.cur_read]
mov [ebp+NTFS.cur_size], 1
lea eax, [ebp+NTFS.bitmap_buf]
mov [ebp+NTFS.cur_buf], eax
call ntfs_read_attr.continue
cmp [ebp+NTFS.ntfs_cur_read], ecx
cmp [ebp+NTFS.cur_read], ecx
jb @f
mov [ebp+NTFS.ntfs_cur_read], ecx
mov [ebp+NTFS.cur_read], ecx
@@:
xchg ecx, [ebp+NTFS.ntfs_cur_read]
xchg ecx, [ebp+NTFS.cur_read]
push ecx
mov edi, edx
lea esi, [ebp+NTFS.ntfs_bitmap_buf]
lea esi, [ebp+NTFS.bitmap_buf]
add [esp+10h+4], ecx
rep movsb
pop ecx
xor eax, eax
cmp ecx, [ebp+NTFS.ntfs_cur_read]
cmp ecx, [ebp+NTFS.cur_read]
jz @f
mov al, ERROR_END_OF_FILE
@@:
1551,21 → 1559,21
pop eax
ret
.doit:
mov [ebp+NTFS.ntfs_cur_iRecord], eax
mov [ebp+NTFS.cur_iRecord], eax
.doit2:
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
mov [ebp+NTFS.cur_attr], 0x10 ; $STANDARD_INFORMATION
and [ebp+NTFS.cur_offs], 0
mov [ebp+NTFS.cur_size], 1
lea eax, [ebp+NTFS.bitmap_buf]
mov [ebp+NTFS.cur_buf], eax
call ntfs_read_attr
jc .notfound
mov [ebp+NTFS.ntfs_cur_attr], 0x90 ; $INDEX_ROOT
and [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.cur_attr], 0x90 ; $INDEX_ROOT
and [ebp+NTFS.cur_offs], 0
mov eax, [ebp+NTFS.cur_index_size]
mov [ebp+NTFS.ntfs_cur_size], eax
mov [ebp+NTFS.cur_size], eax
mov eax, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.ntfs_cur_buf], eax
mov [ebp+NTFS.cur_buf], eax
call ntfs_read_attr
jnc .ok
test eax, eax
1574,7 → 1582,7
push ERROR_DEVICE
jmp .pop_ret
.ok:
cmp [ebp+NTFS.ntfs_cur_read], 0x20
cmp [ebp+NTFS.cur_read], 0x20
jae @f
or ebx, -1
.fserr:
1585,7 → 1593,7
mov esi, [ebp+NTFS.cur_index_buf]
mov eax, [esi+14h]
add eax, 10h
cmp [ebp+NTFS.ntfs_cur_read], eax
cmp [ebp+NTFS.cur_read], eax
jae .readok1
add eax, 1FFh
shr eax, 9
1650,7 → 1658,7
; edi -> BDFE, esi -> current index data, ebx = first wanted block,
; ecx = number of blocks to read
; edx -> parameters block: dd <output>, dd <flags>
cmp [ebp+NTFS.ntfs_cur_iRecord], 5
cmp [ebp+NTFS.cur_iRecord], 5
jz .skip_specials
; dot and dotdot entries
push esi
1672,39 → 1680,39
.dump_root_done:
; now dump all subnodes
push ecx edi
lea edi, [ebp+NTFS.ntfs_bitmap_buf]
mov [ebp+NTFS.ntfs_cur_buf], edi
lea edi, [ebp+NTFS.bitmap_buf]
mov [ebp+NTFS.cur_buf], edi
mov ecx, 0x400/4
xor eax, eax
rep stosd
mov [ebp+NTFS.ntfs_cur_attr], 0xB0 ; $BITMAP
and [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.ntfs_cur_size], 2
mov [ebp+NTFS.cur_attr], 0xB0 ; $BITMAP
and [ebp+NTFS.cur_offs], 0
mov [ebp+NTFS.cur_size], 2
call ntfs_read_attr
pop edi ecx
push 0 ; save offset in $BITMAP attribute
and [ebp+NTFS.ntfs_cur_offs], 0
and [ebp+NTFS.cur_offs], 0
.dumploop:
mov [ebp+NTFS.ntfs_cur_attr], 0xA0
mov [ebp+NTFS.cur_attr], 0xA0
mov eax, [ebp+NTFS.cur_subnode_size]
mov [ebp+NTFS.ntfs_cur_size], eax
mov [ebp+NTFS.cur_size], eax
mov eax, [ebp+NTFS.cur_index_buf]
mov esi, eax
mov [ebp+NTFS.ntfs_cur_buf], eax
push [ebp+NTFS.ntfs_cur_offs]
mov eax, [ebp+NTFS.ntfs_cur_offs]
mov [ebp+NTFS.cur_buf], eax
push [ebp+NTFS.cur_offs]
mov eax, [ebp+NTFS.cur_offs]
imul eax, [ebp+NTFS.cur_subnode_size]
mov [ebp+NTFS.ntfs_cur_offs], eax
mov [ebp+NTFS.cur_offs], eax
call ntfs_read_attr
pop [ebp+NTFS.ntfs_cur_offs]
pop [ebp+NTFS.cur_offs]
mov eax, [ebp+NTFS.cur_subnode_size]
shl eax, 9
cmp [ebp+NTFS.ntfs_cur_read], eax
cmp [ebp+NTFS.cur_read], eax
jnz .done
push eax
mov eax, [ebp+NTFS.ntfs_cur_offs]
mov eax, [ebp+NTFS.cur_offs]
and eax, 0x400*8-1
bt dword [ebp+NTFS.ntfs_bitmap_buf], eax
bt dword [ebp+NTFS.bitmap_buf], eax
pop eax
jnc .dump_subnode_done
cmp dword [esi], 'INDX'
1724,26 → 1732,26
add esi, eax
jmp .dump_subnode
.dump_subnode_done:
inc [ebp+NTFS.ntfs_cur_offs]
test [ebp+NTFS.ntfs_cur_offs], 0x400*8-1
inc [ebp+NTFS.cur_offs]
test [ebp+NTFS.cur_offs], 0x400*8-1
jnz .dumploop
mov [ebp+NTFS.ntfs_cur_attr], 0xB0
mov [ebp+NTFS.cur_attr], 0xB0
push ecx edi
lea edi, [ebp+NTFS.ntfs_bitmap_buf]
mov [ebp+NTFS.ntfs_cur_buf], edi
lea edi, [ebp+NTFS.bitmap_buf]
mov [ebp+NTFS.cur_buf], edi
mov ecx, 0x400/4
xor eax, eax
rep stosd
pop edi ecx
pop eax
push [ebp+NTFS.ntfs_cur_offs]
push [ebp+NTFS.cur_offs]
inc eax
mov [ebp+NTFS.ntfs_cur_offs], eax
mov [ebp+NTFS.ntfs_cur_size], 2
mov [ebp+NTFS.cur_offs], eax
mov [ebp+NTFS.cur_size], 2
push eax
call ntfs_read_attr
pop eax
pop [ebp+NTFS.ntfs_cur_offs]
pop [ebp+NTFS.cur_offs]
push eax
jmp .dumploop
.done:
1772,20 → 1780,20
inc dword [eax+4] ; new file block copied
mov eax, [edx+4]
mov [edi+4], eax
; mov eax, dword [ntfs_bitmap_buf+0x20]
; mov eax, dword [bitmap_buf+0x20]
; or al, 0x10
mov eax, 0x10
stosd
scasd
push edx
mov eax, dword [ebp+NTFS.ntfs_bitmap_buf]
mov edx, dword [ebp+NTFS.ntfs_bitmap_buf+4]
mov eax, dword [ebp+NTFS.bitmap_buf]
mov edx, dword [ebp+NTFS.bitmap_buf+4]
call ntfs_datetime_to_bdfe
mov eax, dword [ebp+NTFS.ntfs_bitmap_buf+0x18]
mov edx, dword [ebp+NTFS.ntfs_bitmap_buf+0x1C]
mov eax, dword [ebp+NTFS.bitmap_buf+0x18]
mov edx, dword [ebp+NTFS.bitmap_buf+0x1C]
call ntfs_datetime_to_bdfe
mov eax, dword [ebp+NTFS.ntfs_bitmap_buf+8]
mov edx, dword [ebp+NTFS.ntfs_bitmap_buf+0xC]
mov eax, dword [ebp+NTFS.bitmap_buf+8]
mov edx, dword [ebp+NTFS.bitmap_buf+0xC]
call ntfs_datetime_to_bdfe
pop edx
xor eax, eax
1995,11 → 2003,11
 
;----------------------------------------------------------------
ntfs_CreateFolder:
mov [ebp+NTFS.ntfsFolder], 1
mov [ebp+NTFS.bFolder], 1
jmp @f
 
ntfs_CreateFile:
mov [ebp+NTFS.ntfsFolder], 0
mov [ebp+NTFS.bFolder], 0
@@:
cmp byte [esi], 0
jnz @f
2011,11 → 2019,11
stdcall ntfs_find_lfn, [esp+4]
jc .notFound
; found, rewrite
cmp [ebp+NTFS.ntfs_cur_iRecord], 16
cmp [ebp+NTFS.cur_iRecord], 16
jc ntfsDenied
cmp [ebp+NTFS.ntfsFolder], 1
cmp [ebp+NTFS.bFolder], 1
jz .folder
cmp [ebp+NTFS.ntfsFragmentCount], 1
cmp [ebp+NTFS.fragmentCount], 1
jnz ntfsUnsupported ; record fragmented
; edit directory node
mov edi, [ebp+NTFS.cur_index_buf]
2025,7 → 2033,7
mov ecx, [esi+recordRealSize]
shr ecx, 2
rep movsd
mov esi, [ebp+NTFS.ntfs_attr_offs]
mov esi, [ebp+NTFS.attr_offs]
mov cl, [esi+attributeOffset]
sub esi, [ebp+NTFS.frs_buffer]
add eax, ecx
2034,11 → 2042,11
mov edx, [ebx+12]
mov [eax+fileRealSize], edx
mov dword [eax+fileRealSize+4], 0
mov eax, [ebp+NTFS.ntfsLastRead]
mov eax, [ebp+NTFS.LastRead]
mov [ebp+NTFS.nodeLastRead], eax
mov [ebp+NTFS.ntfs_cur_attr], 0x80
mov [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.ntfs_cur_size], 0
mov [ebp+NTFS.cur_attr], 0x80
mov [ebp+NTFS.cur_offs], 0
mov [ebp+NTFS.cur_size], 0
call ntfs_read_attr
jc ntfsFail
mov ecx, [ebp+NTFS.frs_buffer]
2046,7 → 2054,7
xor edx, edx
cmp word [ecx+baseRecordReuse], 0
jnz ntfsUnsupported ; auxiliary record
mov ecx, [ebp+NTFS.ntfs_attr_offs]
mov ecx, [ebp+NTFS.attr_offs]
cmp word [ecx+attributeFlags], 0
jnz ntfsUnsupported
push ebx
2068,7 → 2076,7
.notFound: ; create
test eax, eax
jz ntfsFail
cmp [ebp+NTFS.ntfsFragmentCount], 1
cmp [ebp+NTFS.fragmentCount], 1
jnz ntfsUnsupported ; record fragmented
; 2. Prepare directory record
mov ecx, esi
2099,7 → 2107,7
mov ecx, edx
shr ecx, 2
rep movsd
mov edi, [ebp+NTFS.ntfs_attr_offs]
mov edi, [ebp+NTFS.attr_offs]
sub edi, [ebp+NTFS.frs_buffer]
add edi, [ebp+NTFS.cur_index_buf]
mov esi, [esp]
2107,8 → 2115,8
add [edi+sizeWithoutHeader], esi
mov cl, [edi+attributeOffset]
add edi, ecx
add [edi+16+nodeRealSize], esi
add [edi+16+nodeAllocatedSize], esi
add [edi+rootNode+nodeRealSize], esi
add [edi+rootNode+nodeAllocatedSize], esi
sub eax, [ebp+NTFS.cur_index_buf]
add eax, edi
mov edi, [ebp+NTFS.cur_index_buf]
2117,15 → 2125,17
jmp .common
 
.indexRecord:
mov edx, [edi+28]
add edi, recordNode
mov edx, [edi+nodeRealSize]
add edx, ecx
cmp [edi+32], edx
cmp [edi+nodeAllocatedSize], edx
jnc @f
add esp, 12
jmp ntfsUnsupported ; new node required
@@: ; index fits in the node
mov [edi+28], edx
lea edi, [edi+edx+24-4]
mov [edi+nodeRealSize], edx
add edi, edx
sub edi, 4
.common:
mov esi, edi
sub esi, [esp]
2148,7 → 2158,7
shl eax, 1
add eax, 42h
mov [edi+indexRawSize], ax
mov eax, [ebp+NTFS.ntfs_attr_iRecord]
mov eax, [ebp+NTFS.attr_iRecord]
mov [edi+directoryRecordReference], eax
mov eax, [ebp+NTFS.frs_buffer]
mov eax, [eax+reuseCounter]
2183,9 → 2193,9
stosw
dec ecx
jnz @b
mov eax, [ebp+NTFS.ntfsLastRead]
mov eax, [ebp+NTFS.LastRead]
mov [ebp+NTFS.nodeLastRead], eax
cmp [ebp+NTFS.ntfsFolder], 0
cmp [ebp+NTFS.bFolder], 0
jz @f
mov edi, [ebp+NTFS.indexOffset]
bts dword [edi+fileFlags], 28
2228,14 → 2238,14
mov eax, [ebp+NTFS.frs_size]
shr eax, 9
mul edi
mov [ebp+NTFS.ntfs_cur_iRecord], 0
mov [ebp+NTFS.ntfs_cur_attr], 0x80
mov [ebp+NTFS.ntfs_cur_offs], eax
mov [ebp+NTFS.ntfs_cur_size], 1
mov [ebp+NTFS.cur_iRecord], 0
mov [ebp+NTFS.cur_attr], 0x80
mov [ebp+NTFS.cur_offs], eax
mov [ebp+NTFS.cur_size], 1
mov eax, [ebp+NTFS.frs_buffer]
mov [ebp+NTFS.ntfs_cur_buf], eax
mov [ebp+NTFS.cur_buf], eax
call ntfs_read_attr
cmp [ebp+NTFS.ntfs_cur_read], 0
cmp [ebp+NTFS.cur_read], 0
jz .extendMFT
jmp .mftRecord
 
2244,21 → 2254,21
shl eax, 9
cmp [ebp+NTFS.mftBitmapSize], eax
jnc ntfsUnsupported
mov [ebp+NTFS.ntfs_cur_iRecord], 0
mov [ebp+NTFS.ntfs_cur_attr], 0xB0
mov [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.ntfs_cur_size], 0
mov [ebp+NTFS.cur_iRecord], 0
mov [ebp+NTFS.cur_attr], 0xB0
mov [ebp+NTFS.cur_offs], 0
mov [ebp+NTFS.cur_size], 0
call ntfs_read_attr
jc ntfsFail
mov eax, [ebp+NTFS.mft_cluster]
mul [ebp+NTFS.sectors_per_cluster]
cmp eax, [ebp+NTFS.ntfsLastRead]
cmp eax, [ebp+NTFS.LastRead]
jnz ntfsUnsupported ; auxiliary record
mov edi, [ebp+NTFS.mftBitmapBuffer]
mov ecx, [ebp+NTFS.mftBitmapSize]
add edi, ecx
mov eax, ecx
mov edx, [ebp+NTFS.ntfs_attr_offs]
mov edx, [ebp+NTFS.attr_offs]
add ecx, 8
mov [edx+attributeRealSize], ecx
mov [edx+initialDataSize], ecx
2266,7 → 2276,7
mov [ebp+NTFS.newMftRecord], eax
mov dword [edi], 1
mov dword [edi+4], 0
mov [ebp+NTFS.ntfs_cur_attr], 0x80
mov [ebp+NTFS.cur_attr], 0x80
call ntfs_read_attr.newAttribute
jc ntfsFail
mov [ebp+NTFS.mftBitmapSize], ecx
2273,9 → 2283,9
.extendMFT:
mov eax, [ebp+NTFS.mft_cluster]
mul [ebp+NTFS.sectors_per_cluster]
cmp eax, [ebp+NTFS.ntfsLastRead]
cmp eax, [ebp+NTFS.LastRead]
jnz ntfsUnsupported ; auxiliary record
mov ecx, [ebp+NTFS.ntfs_attr_offs]
mov ecx, [ebp+NTFS.attr_offs]
mov eax, [ecx+attributeRealSize]
mov edx, [ecx+attributeRealSize+4]
xor ax, ax
2286,7 → 2296,7
call resizeAttribute
jc ntfsErrorPop2
mov eax, [ebp+NTFS.frs_buffer]
mov [ebp+NTFS.ntfs_cur_buf], eax
mov [ebp+NTFS.cur_buf], eax
call writeRecord ; $MFT
mov eax, [ebp+NTFS.mftmirr_cluster]
mul [ebp+NTFS.sectors_per_cluster]
2342,7 → 2352,7
rep movsd
mov byte [edi+sizeWithHeader], 50h
mov byte [edi+attributeID], 2
cmp [ebp+NTFS.ntfsFolder], 1
cmp [ebp+NTFS.bFolder], 1
jz .indexRoot
; $Data
mov byte [edi+attributeType], 80h
2393,7 → 2403,7
mov byte [edi+attributeOffset], 20h
mov dword[edi+18h], 490024h ; unicode $I30
mov dword[edi+18h+4], 300033h
mov byte [edi+20h+attributeType], 30h
mov byte [edi+20h+indexedAttributesType], 30h
mov byte [edi+20h+collationRule], 1
mov eax, [ebp+NTFS.sectors_per_cluster]
shl eax, 9
2412,7 → 2422,7
mov dword [edi+4], 0
add edi, 8
sub edi, esi
mov [ebp+NTFS.ntfs_cur_buf], esi
mov [ebp+NTFS.cur_buf], esi
mov [esi+recordFlags], al
mov [esi+recordRealSize], edi
call writeRecord
2431,7 → 2441,7
test eax, eax
jnz ntfsDevice
; 5. Write partition bitmap
cmp [ebp+NTFS.ntfsFolder], 1
cmp [ebp+NTFS.bFolder], 1
jz @f
mov eax, [ebp+NTFS.fileDataStart]
mov ecx, [ebp+NTFS.fileDataSize]
2456,9 → 2466,9
mov [edi+fileRecordReference], eax
; 6. Write directory node
mov eax, [ebp+NTFS.nodeLastRead]
mov [ebp+NTFS.ntfsLastRead], eax
mov [ebp+NTFS.LastRead], eax
mov eax, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.ntfs_cur_buf], eax
mov [ebp+NTFS.cur_buf], eax
call writeRecord
mov ebx, [ebp+NTFS.fileRealSize]
ntfsDone:
2471,9 → 2481,9
writeRecord:
; make updateSequence and write to disk
; in:
; [ebp+NTFS.ntfs_cur_buf] -> record
; [ebp+NTFS.ntfsLastRead] = partition sector
mov esi, [ebp+NTFS.ntfs_cur_buf]
; [ebp+NTFS.cur_buf] -> record
; [ebp+NTFS.LastRead] = partition sector
mov esi, [ebp+NTFS.cur_buf]
mov edi, esi
movzx ecx, word [esi+updateSequenceOffset]
add edi, ecx
2489,8 → 2499,8
mov [esi-2], ax
dec ecx
jnz @b
mov eax, [ebp+NTFS.ntfsLastRead]
mov ebx, [ebp+NTFS.ntfs_cur_buf]
mov eax, [ebp+NTFS.LastRead]
mov ebx, [ebp+NTFS.cur_buf]
pop ecx
xor edx, edx
jmp fs_write64_sys
2559,15 → 2569,15
resizeAttribute:
; in:
; [ebp+NTFS.frs_buffer] -> file record
; [ebp+NTFS.ntfs_attr_offs] -> attribute
; [ebp+NTFS.attr_offs] -> attribute
; edx:eax = new size
; out:
; [ebp+NTFS.fileDataSize] = clusters added (positive)
; [ebp+NTFS.fileDataStart] = added block
; CF=1 -> eax = error code
mov esi, [ebp+NTFS.ntfs_attr_offs]
mov dword [ebp+NTFS.ntfs_attr_size], eax
mov dword [ebp+NTFS.ntfs_attr_size+4], edx
mov esi, [ebp+NTFS.attr_offs]
mov dword [ebp+NTFS.attr_size], eax
mov dword [ebp+NTFS.attr_size+4], edx
cmp byte [esi+nonResidentFlag], 0
jz .resident
mov ecx, [ebp+NTFS.sectors_per_cluster]
2609,7 → 2619,7
shr edi, 5
shl edi, 2
push eax
cmp [ebp+NTFS.ntfs_cur_iRecord], 0
cmp [ebp+NTFS.cur_iRecord], 0
jz @f
cmp edi, [ebp+NTFS.BitmapStart]
jc .err1
2636,7 → 2646,7
sub eax, edx
mov [ebp+NTFS.fileDataStart], eax
@@:
mov esi, [ebp+NTFS.ntfs_attr_offs]
mov esi, [ebp+NTFS.attr_offs]
call createMcbEntry
pop ecx
pop eax
2716,7 → 2726,7
pop edi
cmp [ebp+NTFS.fileDataSize], 0
jz @f
mov esi, [ebp+NTFS.ntfs_attr_offs]
mov esi, [ebp+NTFS.attr_offs]
call createMcbEntry
mov [ebp+NTFS.fileDataSize], 0
@@:
2760,9 → 2770,9
xor eax, eax
rep stosd
cld
mov esi, [ebp+NTFS.ntfs_attr_offs]
mov esi, [ebp+NTFS.attr_offs]
@@:
mov eax, dword [ebp+NTFS.ntfs_attr_size]
mov eax, dword [ebp+NTFS.attr_size]
mov [esi+sizeWithoutHeader], eax
mov [ebp+NTFS.fileDataSize], 0
clc
2769,7 → 2779,7
ret
 
.nonResident: ; convert resident to non-resident
mov eax, dword [ebp+NTFS.ntfs_attr_size]
mov eax, dword [ebp+NTFS.attr_size]
sub eax, 1
sbb edx, 0
mov ecx, [ebp+NTFS.sectors_per_cluster]
2783,7 → 2793,7
pop ecx
jc .err10
mov [ebp+NTFS.fileDataStart], eax
mov esi, [ebp+NTFS.ntfs_attr_offs]
mov esi, [ebp+NTFS.attr_offs]
xor eax, eax
xor edx, edx
@@:
2815,21 → 2825,21
call kernel_free
test ebx, ebx
jnz .err4
mov esi, [ebp+NTFS.ntfs_attr_offs]
mov esi, [ebp+NTFS.attr_offs]
add esi, [esi+sizeWithHeader]
mov ecx, [ebp+NTFS.frs_buffer]
add ecx, [ecx+recordRealSize]
sub ecx, esi
shr ecx, 2
lea edi, [ebp+NTFS.ntfs_bitmap_buf]
lea edi, [ebp+NTFS.bitmap_buf]
push ecx
rep movsd
mov edi, [ebp+NTFS.ntfs_attr_offs]
mov edi, [ebp+NTFS.attr_offs]
add edi, 16
mov cl, 6
xor eax, eax
rep stosd
mov edi, [ebp+NTFS.ntfs_attr_offs]
mov edi, [ebp+NTFS.attr_offs]
mov eax, [ebp+NTFS.fileDataSize]
dec eax
mov [edi+lastVCN], eax
2842,8 → 2852,8
mov byte [edi+dataRunsOffset], 40h
mov [edi+attributeAllocatedSize], eax
mov [edi+attributeAllocatedSize+4], edx
mov eax, dword [ebp+NTFS.ntfs_attr_size]
mov edx, dword [ebp+NTFS.ntfs_attr_size+4]
mov eax, dword [ebp+NTFS.attr_size]
mov edx, dword [ebp+NTFS.attr_size+4]
mov [edi+attributeRealSize], eax
mov [edi+attributeRealSize+4], edx
mov [edi+initialDataSize], eax
2852,13 → 2862,13
add edi, 40h
call createMcbEntry
mov eax, edi
mov edi, [ebp+NTFS.ntfs_attr_offs]
mov edi, [ebp+NTFS.attr_offs]
sub eax, edi
add eax, 8
and eax, not 7
mov [edi+sizeWithHeader], eax
pop ecx
lea esi, [ebp+NTFS.ntfs_bitmap_buf]
lea esi, [ebp+NTFS.bitmap_buf]
add edi, eax
rep movsd
mov esi, [ebp+NTFS.frs_buffer]
2918,7 → 2928,7
rep stosd
mov eax, [ebp+NTFS.fileDataStart]
mul [ebp+NTFS.sectors_per_cluster]
mov [ebp+NTFS.ntfsLastRead], eax
mov [ebp+NTFS.LastRead], eax
pop ecx
call fs_write64_app
stdcall kernel_free, ebx
3215,11 → 3225,11
call ntfs_lock
stdcall ntfs_find_lfn, [esp+4]
jc ntfsNotFound
cmp [ebp+NTFS.ntfs_cur_iRecord], 16
cmp [ebp+NTFS.cur_iRecord], 16
jc ntfsDenied
bt dword [eax+fileFlags], 28
jc ntfsDenied
cmp [ebp+NTFS.ntfsFragmentCount], 1
cmp [ebp+NTFS.fragmentCount], 1
jnz ntfsUnsupported ; record fragmented
; edit directory node
mov edi, [ebp+NTFS.cur_index_buf]
3229,7 → 3239,7
mov ecx, [esi+recordRealSize]
shr ecx, 2
rep movsd
mov esi, [ebp+NTFS.ntfs_attr_offs]
mov esi, [ebp+NTFS.attr_offs]
mov cl, [esi+attributeOffset]
sub esi, [ebp+NTFS.frs_buffer]
add eax, ecx
3241,11 → 3251,11
adc edx, 0
mov [eax+fileRealSize], ecx
mov [eax+fileRealSize+4], edx
mov eax, [ebp+NTFS.ntfsLastRead]
mov eax, [ebp+NTFS.LastRead]
mov [ebp+NTFS.nodeLastRead], eax
mov [ebp+NTFS.ntfs_cur_attr], 0x80
mov [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.ntfs_cur_size], 0
mov [ebp+NTFS.cur_attr], 0x80
mov [ebp+NTFS.cur_offs], 0
mov [ebp+NTFS.cur_size], 0
call ntfs_read_attr
jc ntfsFail
mov eax, ecx
3252,7 → 3262,7
mov ecx, [ebp+NTFS.frs_buffer]
cmp word [ecx+baseRecordReuse], 0
jnz ntfsUnsupported ; auxiliary record
mov ecx, [ebp+NTFS.ntfs_attr_offs]
mov ecx, [ebp+NTFS.attr_offs]
cmp word [ecx+attributeFlags], 0
jnz ntfsUnsupported
push ebx
3266,7 → 3276,7
.resizeAttribute:
call resizeAttribute
jc ntfsErrorPop
mov ecx, [ebp+NTFS.ntfs_attr_offs]
mov ecx, [ebp+NTFS.attr_offs]
cmp byte [ecx+nonResidentFlag], 1
jz @f
mov ebx, [esp]
3278,18 → 3288,18
rep movsb
@@:
mov eax, [ebp+NTFS.frs_buffer]
mov [ebp+NTFS.ntfs_cur_buf], eax
mov [ebp+NTFS.cur_buf], eax
call writeRecord ; file
mov ebx, [ebp+NTFS.frs_buffer]
call ntfs_restore_usa_frs
.writeNode:
mov eax, [ebp+NTFS.nodeLastRead]
mov [ebp+NTFS.ntfsLastRead], eax
mov [ebp+NTFS.LastRead], eax
mov eax, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.ntfs_cur_buf], eax
mov [ebp+NTFS.cur_buf], eax
call writeRecord ; directory
pop ebx
mov ecx, [ebp+NTFS.ntfs_attr_offs]
mov ecx, [ebp+NTFS.attr_offs]
cmp byte [ecx+nonResidentFlag], 0
jz .done
mov ecx, [ebx+12]
3301,16 → 3311,16
shrd eax, edx, 9
test dword[ebx+4], 1FFh
jz .aligned
mov [ebp+NTFS.ntfs_cur_offs], eax
mov [ebp+NTFS.ntfs_cur_size], 1
lea edi, [ebp+NTFS.ntfs_bitmap_buf]
mov [ebp+NTFS.ntfs_cur_buf], edi
mov [ebp+NTFS.cur_offs], eax
mov [ebp+NTFS.cur_size], 1
lea edi, [ebp+NTFS.bitmap_buf]
mov [ebp+NTFS.cur_buf], edi
call ntfs_read_attr.continue
jc ntfsDevice
mov eax, [ebx+4]
and eax, 1FFh
add edi, eax
sub eax, [ebp+NTFS.ntfs_cur_read]
sub eax, [ebp+NTFS.cur_read]
neg eax
push ecx
cmp ecx, eax
3320,8 → 3330,8
sub [esp], ecx
rep movsb
push ebx
mov eax, [ebp+NTFS.ntfsLastRead]
lea ebx, [ebp+NTFS.ntfs_bitmap_buf]
mov eax, [ebp+NTFS.LastRead]
lea ebx, [ebp+NTFS.bitmap_buf]
mov ecx, 1
xor edx, edx
call fs_write64_app
3336,29 → 3346,29
.aligned:
push ecx
shr ecx, 9
mov [ebp+NTFS.ntfs_cur_offs], eax
mov [ebp+NTFS.ntfs_cur_size], ecx
mov [ebp+NTFS.ntfs_cur_buf], esi
mov [ebp+NTFS.cur_offs], eax
mov [ebp+NTFS.cur_size], ecx
mov [ebp+NTFS.cur_buf], esi
add eax, ecx
push eax
mov [ebp+NTFS.ntfsWriteAttr], 1
mov [ebp+NTFS.bWriteAttr], 1
call ntfs_read_attr.continue
mov [ebp+NTFS.ntfsWriteAttr], 0
pop [ebp+NTFS.ntfs_cur_offs]
mov [ebp+NTFS.bWriteAttr], 0
pop [ebp+NTFS.cur_offs]
pop ecx
jc ntfsDevice
and ecx, 1FFh
jz .done
add esi, [ebp+NTFS.ntfs_cur_read]
mov [ebp+NTFS.ntfs_cur_size], 1
lea edi, [ebp+NTFS.ntfs_bitmap_buf]
mov [ebp+NTFS.ntfs_cur_buf], edi
add esi, [ebp+NTFS.cur_read]
mov [ebp+NTFS.cur_size], 1
lea edi, [ebp+NTFS.bitmap_buf]
mov [ebp+NTFS.cur_buf], edi
call ntfs_read_attr.continue
jc ntfsDevice
rep movsb
push ebx
mov eax, [ebp+NTFS.ntfsLastRead]
lea ebx, [ebp+NTFS.ntfs_bitmap_buf]
mov eax, [ebp+NTFS.LastRead]
lea ebx, [ebp+NTFS.bitmap_buf]
mov ecx, 1
xor edx, edx
call fs_write64_app
3378,13 → 3388,13
call ntfs_lock
stdcall ntfs_find_lfn, [esp+4]
jc ntfsNotFound
cmp [ebp+NTFS.ntfs_cur_iRecord], 16
cmp [ebp+NTFS.cur_iRecord], 16
jc ntfsDenied
cmp [ebp+NTFS.ntfsFragmentCount], 1
cmp [ebp+NTFS.fragmentCount], 1
jnz ntfsUnsupported ; record fragmented
test byte [eax+indexFlags], 1
jnz ntfsUnsupported ; index has a subnode
mov edx, [ebp+NTFS.ntfs_cur_iRecord]
mov edx, [ebp+NTFS.cur_iRecord]
shr edx, 3
cmp edx, [ebp+NTFS.mftBitmapSize]
jnc ntfsUnsupported
3403,7 → 3413,7
shr ecx, 2
rep movsd
mov esi, [ebp+NTFS.cur_index_buf]
mov edi, [ebp+NTFS.ntfs_attr_offs]
mov edi, [ebp+NTFS.attr_offs]
sub edi, [ebp+NTFS.frs_buffer]
add edi, esi
sub [edi+sizeWithHeader], edx
3410,8 → 3420,8
sub [edi+sizeWithoutHeader], edx
mov cl, [edi+attributeOffset]
add edi, ecx
sub [edi+16+nodeRealSize], edx
sub [edi+16+nodeAllocatedSize], edx
sub [edi+rootNode+nodeRealSize], edx
sub [edi+rootNode+nodeAllocatedSize], edx
sub eax, esi
add eax, edi
sub [esi+recordRealSize], edx
3419,9 → 3429,10
jmp @f
 
.indexRecord:
sub [edi+28], edx
mov ecx, [edi+28]
add ecx, 24
add edi, recordNode+nodeRealSize
sub [edi], edx
mov ecx, [edi]
add ecx, recordNode
@@:
add ecx, [ebp+NTFS.cur_index_buf]
sub ecx, eax
3430,18 → 3441,18
add esi, edx
mov edi, eax
rep movsd
mov eax, [ebp+NTFS.ntfsLastRead]
mov eax, [ebp+NTFS.LastRead]
mov [ebp+NTFS.nodeLastRead], eax
; examine file record
mov [ebp+NTFS.ntfs_cur_attr], 0x80
mov [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.ntfs_cur_size], 0
mov [ebp+NTFS.cur_attr], 0x80
mov [ebp+NTFS.cur_offs], 0
mov [ebp+NTFS.cur_size], 0
call ntfs_read_attr
jc .folder
mov esi, [ebp+NTFS.frs_buffer]
cmp word [esi+baseRecordReuse], 0
jnz ntfsUnsupported ; auxiliary record
mov esi, [ebp+NTFS.ntfs_attr_offs]
mov esi, [ebp+NTFS.attr_offs]
cmp byte [esi+nonResidentFlag], 0
jz .writeBitmapMFT
movzx eax, byte [esi+dataRunsOffset]
3462,18 → 3473,18
jmp .writeBitmapMFT
 
.folder: ; empty?
lea esi, [ebp+NTFS.ntfs_bitmap_buf]
mov [ebp+NTFS.ntfs_cur_buf], esi
mov [ebp+NTFS.ntfs_cur_attr], 0x90
mov [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.ntfs_cur_size], 1
lea esi, [ebp+NTFS.bitmap_buf]
mov [ebp+NTFS.cur_buf], esi
mov [ebp+NTFS.cur_attr], 0x90
mov [ebp+NTFS.cur_offs], 0
mov [ebp+NTFS.cur_size], 1
call ntfs_read_attr
cmp [ebp+NTFS.ntfs_cur_read], 48
cmp [ebp+NTFS.cur_read], 48
jnz ntfsDenied
test byte [esi+32+indexFlags], 1
jnz ntfsDenied
.writeBitmapMFT: ; "delete" file record
mov eax, [ebp+NTFS.ntfs_cur_iRecord]
mov eax, [ebp+NTFS.cur_iRecord]
mov ecx, eax
shr eax, 3
and ecx, 7
3488,14 → 3499,14
xor edx, edx
call fs_write64_sys
mov esi, [ebp+NTFS.frs_buffer]
mov [ebp+NTFS.ntfs_cur_buf], esi
mov [ebp+NTFS.cur_buf], esi
mov byte [esi+recordFlags], 0
call writeRecord
; write directory node
mov eax, [ebp+NTFS.nodeLastRead]
mov [ebp+NTFS.ntfsLastRead], eax
mov [ebp+NTFS.LastRead], eax
mov eax, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.ntfs_cur_buf], eax
mov [ebp+NTFS.cur_buf], eax
call writeRecord
jmp ntfsDone
 
3510,11 → 3521,11
call ntfs_lock
stdcall ntfs_find_lfn, [esp+4]
jc ntfsNotFound
cmp [ebp+NTFS.ntfs_cur_iRecord], 16
cmp [ebp+NTFS.cur_iRecord], 16
jc ntfsDenied
bt dword [eax+fileFlags], 28
jc ntfsDenied
cmp [ebp+NTFS.ntfsFragmentCount], 1
cmp [ebp+NTFS.fragmentCount], 1
jnz ntfsUnsupported ; record fragmented
; edit directory node
mov edi, [ebp+NTFS.cur_index_buf]
3524,7 → 3535,7
mov ecx, [esi+recordRealSize]
shr ecx, 2
rep movsd
mov esi, [ebp+NTFS.ntfs_attr_offs]
mov esi, [ebp+NTFS.attr_offs]
mov cl, [esi+attributeOffset]
sub esi, [ebp+NTFS.frs_buffer]
add eax, ecx
3534,11 → 3545,11
mov edx, [ebx+8]
mov [eax+fileRealSize], ecx
mov [eax+fileRealSize+4], edx
mov eax, [ebp+NTFS.ntfsLastRead]
mov eax, [ebp+NTFS.LastRead]
mov [ebp+NTFS.nodeLastRead], eax
mov [ebp+NTFS.ntfs_cur_attr], 0x80
mov [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.ntfs_cur_size], 0
mov [ebp+NTFS.cur_attr], 0x80
mov [ebp+NTFS.cur_offs], 0
mov [ebp+NTFS.cur_size], 0
call ntfs_read_attr
jc ntfsFail
mov eax, ecx
3545,7 → 3556,7
mov ecx, [ebp+NTFS.frs_buffer]
cmp word [ecx+baseRecordReuse], 0
jnz ntfsUnsupported ; auxiliary record
mov ecx, [ebp+NTFS.ntfs_attr_offs]
mov ecx, [ebp+NTFS.attr_offs]
cmp word [ecx+attributeFlags], 0
jnz ntfsUnsupported
cmp byte [ecx+nonResidentFlag], 0
3556,7 → 3567,7
jnc .resizeAttribute
mov eax, [ecx+attributeRealSize]
mov ecx, [ebp+NTFS.sectors_per_cluster]
mov [ebp+NTFS.ntfs_cur_size], ecx
mov [ebp+NTFS.cur_size], ecx
shl ecx, 9
div ecx
test edx, edx
3564,28 → 3575,28
push edx
push ecx
mul [ebp+NTFS.sectors_per_cluster]
mov [ebp+NTFS.ntfs_cur_offs], eax
mov [ebp+NTFS.cur_offs], eax
stdcall kernel_alloc, ecx
pop ecx
pop edi
sub ecx, edi
add edi, eax
mov [ebp+NTFS.ntfs_cur_buf], eax
push [ebp+NTFS.ntfsLastRead]
mov [ebp+NTFS.cur_buf], eax
push [ebp+NTFS.LastRead]
call ntfs_read_attr.continue
jc @f
xor eax, eax
rep stosb
push ebx
mov eax, [ebp+NTFS.ntfsLastRead]
mov ebx, [ebp+NTFS.ntfs_cur_buf]
mov eax, [ebp+NTFS.LastRead]
mov ebx, [ebp+NTFS.cur_buf]
mov ecx, [ebp+NTFS.sectors_per_cluster]
xor edx, edx
call fs_write64_app
pop ebx
@@:
pop [ebp+NTFS.ntfsLastRead]
stdcall kernel_free, [ebp+NTFS.ntfs_cur_buf]
pop [ebp+NTFS.LastRead]
stdcall kernel_free, [ebp+NTFS.cur_buf]
.aligned:
mov eax, [ebx+4]
mov edx, [ebx+8]
3593,12 → 3604,12
call resizeAttribute
jc ntfsError
mov eax, [ebp+NTFS.frs_buffer]
mov [ebp+NTFS.ntfs_cur_buf], eax
mov [ebp+NTFS.cur_buf], eax
call writeRecord ; file
mov eax, [ebp+NTFS.nodeLastRead]
mov [ebp+NTFS.ntfsLastRead], eax
mov [ebp+NTFS.LastRead], eax
mov eax, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.ntfs_cur_buf], eax
mov [ebp+NTFS.cur_buf], eax
call writeRecord ; directory
call ntfsSpaceClean
jmp ntfsDone