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