NTFS: much more files in folders

git-svn-id: svn://kolibrios.org@6340 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
pathoswithin 2016-03-15 06:18:38 +00:00
parent 03c7eb4fa9
commit 8182b75b0e

View File

@ -65,7 +65,7 @@ initialDataSize = 38h
indexedAttributesType = 0
collationRule = 4
indexRecordSize = 8
indexRecordSizeClus = 12
indexRecordSizeClus = 12 ; in sectors if less than one cluster
rootNode = 16
; IndexRecord header
recordVCN = 16
@ -108,6 +108,7 @@ mft_retrieval_alloc dd ?
mft_retrieval_end dd ?
cur_index_size dd ? ; in sectors
cur_index_buf dd ? ; index node buffer
secondIndexBuffer dd ?
BitmapBuffer dd ?
BitmapTotalSize dd ? ; bytes reserved
BitmapSize dd ? ; bytes readen
@ -124,13 +125,16 @@ 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
rootLastRead dd ?
nodeLastRead dd ?
indexRoot dd ?
pointingIndex dd ?
newRecord dd ?
fileDataStart dd ? ; starting cluster
fileDataSize dd ? ; in clusters
fileDataBuffer dd ?
fileRealSize dd ? ; in bytes
indexOffset dd ?
nodeLastRead dd ?
fragmentCount db ?
bCanContinue db ?
bFolder db ?
@ -398,11 +402,13 @@ ntfs_create_partition:
add esp, 10h
; there may be other portions of $DATA attribute in auxiliary records;
; if they will be needed, they will be loaded later
mov [ebp+NTFS.cur_index_size], 0x1000/0x200
stdcall kernel_alloc, 0x1000
stdcall kernel_alloc, 2000h
test eax, eax
jz .fail_free_mft
mov [ebp+NTFS.cur_index_buf], eax
add eax, 1000h
mov [ebp+NTFS.secondIndexBuffer], eax
mov [ebp+NTFS.cur_index_size], 8
; reserve adress space for bitmap buffer and load some part of bitmap
mov eax, dword [ebp+NTFS.Length]
xor edx, edx
@ -484,6 +490,7 @@ ntfs_create_partition:
stdcall kernel_free, [ebx+NTFS.BitmapBuffer]
.failFreeIndex:
stdcall kernel_free, [ebp+NTFS.cur_index_buf]
stdcall kernel_free, [ebp+NTFS.secondIndexBuffer]
.fail_free_mft:
stdcall kernel_free, [ebp+NTFS.mft_retrieval]
.fail_free_frs:
@ -532,6 +539,7 @@ ntfs_free:
stdcall kernel_free, [ebx+NTFS.frs_buffer]
stdcall kernel_free, [ebx+NTFS.mft_retrieval]
stdcall kernel_free, [ebx+NTFS.cur_index_buf]
stdcall kernel_free, [ebp+NTFS.secondIndexBuffer]
stdcall kernel_free, [ebx+NTFS.mftBitmapBuffer]
stdcall kernel_free, [ebx+NTFS.BitmapBuffer]
mov eax, ebx
@ -1280,17 +1288,24 @@ ntfs_find_lfn:
jc .ret
pushad
mov esi, [ebp+NTFS.cur_index_buf]
mov edx, [esi+indexRecordSize]
shr edx, 9
cmp [ebp+NTFS.cur_index_size], edx
mov eax, [esi+indexRecordSize]
shr eax, 9
cmp [ebp+NTFS.cur_index_size], eax
jc .realloc
mov [ebp+NTFS.cur_size], eax
mov al, [esi+indexRecordSizeClus]
mov [ebp+NTFS.cur_subnode_size], eax
add esi, rootNode
mov eax, [esi+nodeRealSize]
add eax, rootNode
cmp [ebp+NTFS.cur_read], eax
jc .err
mov edi, [esp+4]
; edi -> name, esi -> current index node, edx = subnode size
mov eax, [ebp+NTFS.LastRead]
mov [ebp+NTFS.rootLastRead], eax
mov eax, [ebp+NTFS.attr_offs]
mov [ebp+NTFS.indexRoot], eax
; edi -> name, esi -> current index node
.scanloop:
add esi, [esi+indexOffset]
.scanloopint:
@ -1323,14 +1338,20 @@ ntfs_find_lfn:
jmp .scanloopint
.realloc:
mov edi, edx
stdcall kernel_alloc, [esi+indexRecordSize]
mov edi, eax
mov eax, [esi+indexRecordSize]
shl eax, 1
stdcall kernel_alloc, eax
test eax, eax
jz .err
push [ebp+NTFS.secondIndexBuffer]
push [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.cur_index_buf], eax
call kernel_free
add eax, [esi+indexRecordSize]
mov [ebp+NTFS.secondIndexBuffer], eax
mov [ebp+NTFS.cur_index_size], edi
call kernel_free
call kernel_free
popad
jmp .doit2
@ -1351,21 +1372,27 @@ ntfs_find_lfn:
jz .notfound
movzx eax, word [esi+indexAllocatedSize]
mov eax, [esi+eax-8]
imul eax, [ebp+NTFS.sectors_per_cluster]
mov [ebp+NTFS.cur_offs], eax
mov edx, [ebp+NTFS.cur_size]
push edx
cmp edx, [ebp+NTFS.cur_subnode_size]
jz @f
mul [ebp+NTFS.sectors_per_cluster]
@@:
mov [ebp+NTFS.pointingIndex], esi
mov esi, [ebp+NTFS.cur_index_buf]
xchg [ebp+NTFS.secondIndexBuffer], esi
mov [ebp+NTFS.cur_index_buf], esi
mov [ebp+NTFS.cur_buf], esi
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.cur_buf], eax
mov [ebp+NTFS.cur_offs], eax
call ntfs_read_attr.newAttribute
mov eax, edx
pop eax
mov [ebp+NTFS.cur_size], eax
shl eax, 9
cmp [ebp+NTFS.cur_read], eax
jnz .err
cmp dword [esi], 'INDX'
jnz .err
mov [ebp+NTFS.cur_buf], esi
mov ebx, esi
call ntfs_restore_usa
jc .err
@ -1566,11 +1593,11 @@ ntfs_ReadFolder:
jc ntfsFail
pushad
mov esi, [ebp+NTFS.cur_index_buf]
mov edx, [esi+indexRecordSize]
shr edx, 9
cmp [ebp+NTFS.cur_index_size], edx
mov eax, [esi+indexRecordSize]
shr eax, 9
cmp [ebp+NTFS.cur_index_size], eax
jc .realloc
mov [ebp+NTFS.cur_subnode_size], edx
mov [ebp+NTFS.cur_subnode_size], eax
add esi, rootNode
mov eax, [esi+nodeRealSize]
add eax, rootNode
@ -1612,14 +1639,20 @@ ntfs_ReadFolder:
jmp .dump_root
.realloc:
mov edi, edx
stdcall kernel_alloc, [esi+indexRecordSize]
mov edi, eax
mov eax, [esi+indexRecordSize]
shl eax, 1
stdcall kernel_alloc, eax
test eax, eax
jz .err
push [ebp+NTFS.secondIndexBuffer]
push [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.cur_index_buf], eax
call kernel_free
add eax, [esi+indexRecordSize]
mov [ebp+NTFS.secondIndexBuffer], eax
mov [ebp+NTFS.cur_index_size], edi
call kernel_free
call kernel_free
popad
jmp .doit
@ -2048,30 +2081,27 @@ ntfs_CreateFile:
mov edi, [ebp+NTFS.cur_index_buf]
jmp .common
@@:
add esp, 16
jmp ntfsUnsupported
.growTree:
sub eax, edi
sub eax, rootNode
sub eax, [edi+rootNode+indexOffset]
push eax
xchg [ebp+NTFS.secondIndexBuffer], edi
mov [ebp+NTFS.cur_index_buf], edi
; create indexRecord
mov ecx, 10
xor eax, eax
rep stosd
mov esi, [ebp+NTFS.attr_offs]
mov al, [esi+attributeOffset]
add esi, eax
mov al, [esi+indexRecordSizeClus]
mov [ebp+NTFS.fileDataSize], eax
rdtsc
stosw
mov esi, [ebp+NTFS.attr_offs]
mov cl, [esi+attributeOffset]
add esi, ecx
mov eax, [esi+indexRecordSizeClus]
cmp eax, 129
jnc @b
mov [ebp+NTFS.fileDataSize], eax
mov eax, [esi+indexRecordSize]
cmp eax, [ebp+NTFS.frs_size]
jc @b
jc .errorPop4
shr eax, 9
inc eax
mov edi, [ebp+NTFS.cur_index_buf]
@ -2115,7 +2145,7 @@ ntfs_CreateFile:
mov word [esi+sizeWithoutHeader], 38h
xchg [esi+sizeWithHeader], eax
cmp byte [esi+eax], -1
jnz @b
jnz .errorPop4
mov cl, 32
xor eax, eax
push edi
@ -2128,6 +2158,7 @@ ntfs_CreateFile:
@@: ; create $IndexAllocation
pop edi
mov [ebp+NTFS.attr_offs], edi
mov byte [edi+attributeType], 0xA0
mov byte [edi+nonResidentFlag], 1
mov byte [edi+nameLength], 4
@ -2181,25 +2212,171 @@ ntfs_CreateFile:
mov [ebp+NTFS.cur_buf], eax
call writeRecord ; indexRecord
mov ebx, [ebp+NTFS.cur_index_buf]
mov ax, [ebx+6]
mov ax, [ebx+updateSequenceSize]
dec eax
shl eax, 9
call ntfs_restore_usa
mov edi, [ebp+NTFS.cur_index_buf]
pop eax
add eax, recordNode
add eax, edi
add eax, [edi+recordNode+indexOffset]
mov edx, [esp]
.indexRecord:
add edi, recordNode
add edx, [edi+nodeRealSize]
cmp [edi+nodeAllocatedSize], edx
jnc @f
add esp, 12
jmp ntfsUnsupported ; new node required
@@: ; index fits in the node
jc .arborizeTree
mov [edi+nodeRealSize], edx
jmp .common
.errorPop4:
pop eax
.errorPop3:
add esp, 12
jmp ntfsUnsupported
.arborizeTree:
; directory bitmap
mov esi, [ebp+NTFS.attr_offs]
add esi, [esi+sizeWithHeader]
cmp byte [esi], 0xB0
jnz .errorPop3
movzx eax, byte [esi+attributeOffset]
add esi, eax
mov eax, [esi]
not eax
bsf eax, eax
jz .errorPop3
bts [esi], eax
mul [ebp+NTFS.cur_subnode_size]
mov [ebp+NTFS.newRecord], eax
; find median index
mov ecx, [edi+nodeRealSize]
sub ecx, [edi+indexOffset]
shr ecx, 1
add edi, [edi+indexOffset]
xor eax, eax
@@:
add edi, eax
mov ax, [edi+indexAllocatedSize]
sub ecx, eax
jnc @b
mov esi, [ebp+NTFS.secondIndexBuffer]
cmp dword [esi], 'INDX'
jz .errorPop3 ; move index to the branch node
; move index to the root node
mov esi, [ebp+NTFS.frs_buffer]
mov ecx, [esi+recordRealSize]
add eax, 8
add ecx, eax
cmp [esi+recordAllocatedSize], ecx
jc .errorPop3 ; tree grow required
mov [esi+recordRealSize], ecx
add esi, ecx
push edi
mov edi, [ebp+NTFS.indexRoot]
add [ebp+NTFS.attr_offs], eax
add [edi+sizeWithHeader], eax
add [edi+sizeWithoutHeader], eax
movzx ecx, byte [edi+attributeOffset]
add ecx, edi
add [ecx+rootNode+nodeRealSize], eax
add [ecx+rootNode+nodeAllocatedSize], eax
add ecx, [ebp+NTFS.pointingIndex]
sub ecx, [ebp+NTFS.secondIndexBuffer]
mov edi, esi
sub esi, eax
neg ecx
add ecx, esi
shr ecx, 2
sub esi, 4
sub edi, 4
std
rep movsd ; make space
mov [edi], ecx
mov edi, esi
add edi, 4
mov esi, [esp]
add word [esi+indexAllocatedSize], 8
mov byte [esi+indexFlags], 1
mov ecx, eax
sub ecx, 8
shr ecx, 2
cld
rep movsd ; insert index
mov eax, [ebp+NTFS.newRecord]
stosd
; split node
mov edi, [ebp+NTFS.cur_index_buf]
mov eax, edi
add eax, recordNode
add eax, [edi+recordNode+nodeRealSize]
sub eax, esi
push eax
mov ecx, [edi+recordNode+indexOffset]
add eax, ecx
add ecx, recordNode
shr ecx, 2
push esi
mov esi, edi
mov edi, [ebp+NTFS.secondIndexBuffer]
rep movsd
pop esi
pop ecx
shr ecx, 2
rep movsd
mov edi, [ebp+NTFS.secondIndexBuffer]
mov [edi+recordNode+nodeRealSize], eax
pop edi
mov cl, 4
xor eax, eax
mov esi, edi
rep stosd
mov byte [esi+indexAllocatedSize], 16
mov byte [esi+indexFlags], 2
mov esi, [ebp+NTFS.cur_index_buf]
mov eax, [ebp+NTFS.newRecord]
movzx edx, word [esi+updateSequenceSize]
dec edx
mov [esi+recordVCN], eax
add esi, recordNode
sub edi, esi
mov [esi+nodeRealSize], edi
; allocate new node
add eax, [ebp+NTFS.cur_subnode_size]
cmp edx, [ebp+NTFS.cur_subnode_size]
jz @f
mul [ebp+NTFS.sectors_per_cluster]
@@:
shl eax, 9
mov esi, [ebp+NTFS.attr_offs]
cmp [esi+attributeAllocatedSize], eax
jnc .errorPop3
call resizeAttribute
jc ntfsErrorPop3
mov eax, [ebp+NTFS.secondIndexBuffer]
mov [ebp+NTFS.cur_buf], eax
call writeRecord
mov eax, [ebp+NTFS.fileDataStart]
mul [ebp+NTFS.sectors_per_cluster]
mov [ebp+NTFS.LastRead], eax
mov eax, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.cur_buf], eax
call writeRecord
mov eax, [ebp+NTFS.rootLastRead]
mov [ebp+NTFS.LastRead], eax
mov eax, [ebp+NTFS.frs_buffer]
mov [ebp+NTFS.cur_buf], eax
call writeRecord
mov esi, [esp+4]
stdcall ntfs_find_lfn.doit2, 0
test eax, eax
jz .errorPop3
mov edi, [ebp+NTFS.cur_index_buf]
mov edx, [esp]
jmp .indexRecord
.common:
add edi, edx
sub edi, 4
@ -2300,7 +2477,7 @@ ntfs_CreateFile:
sub edi, [ebp+NTFS.mftBitmapBuffer]
shl edi, 3
add edi, ecx
mov [ebp+NTFS.newMftRecord], edi
mov [ebp+NTFS.newRecord], edi
mov eax, [ebp+NTFS.frs_size]
shr eax, 9
mul edi
@ -2339,7 +2516,7 @@ ntfs_CreateFile:
mov [edx+attributeRealSize], ecx
mov [edx+initialDataSize], ecx
shl eax, 3
mov [ebp+NTFS.newMftRecord], eax
mov [ebp+NTFS.newRecord], eax
mov dword [edi], 1
mov dword [edi+4], 0
mov [ebp+NTFS.cur_attr], 0x80
@ -2503,7 +2680,7 @@ ntfs_CreateFile:
mov [esi+recordRealSize], edi
call writeRecord
; write MFT bitmap
mov eax, [ebp+NTFS.newMftRecord]
mov eax, [ebp+NTFS.newRecord]
shr eax, 3+9
mov ebx, eax
shl ebx, 9
@ -2513,7 +2690,7 @@ ntfs_CreateFile:
xor edx, edx
call fs_write64_sys
mov edi, [ebp+NTFS.indexOffset]
mov eax, [ebp+NTFS.newMftRecord]
mov eax, [ebp+NTFS.newRecord]
mov [edi+fileRecordReference], eax
; 5. Write directory node
mov eax, [ebp+NTFS.nodeLastRead]
@ -3687,6 +3864,8 @@ ntfsFail:
ntfsDiskFull:
push ERROR_DISK_FULL
jmp ntfsOut
ntfsErrorPop3:
pop ebx
ntfsErrorPop2:
pop ebx
ntfsErrorPop: