NTFS: limited support of deleting files and folders
git-svn-id: svn://kolibrios.org@6019 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
c9cedace09
commit
40159abb43
@ -46,9 +46,10 @@ sizeWithHeader = 4
|
||||
nonResidentFlag = 8
|
||||
nameLength = 9
|
||||
nameOffset = 10
|
||||
attributeFlags = 12
|
||||
attributeID = 14
|
||||
sizeWithoutHeader = 16
|
||||
attributeFlags = 16h
|
||||
indexedFlag = 16h
|
||||
; non resident attribute header
|
||||
lastVCN = 18h
|
||||
dataRunsOffset = 20h
|
||||
@ -272,10 +273,6 @@ ntfs_create_partition:
|
||||
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
|
||||
@ -1165,6 +1162,14 @@ ntfs_restore_usa:
|
||||
ret
|
||||
|
||||
ntfs_decode_mcb_entry:
|
||||
; in:
|
||||
; esi -> mcb entry
|
||||
; esp -> buffer (16 bytes)
|
||||
; out:
|
||||
; esi -> next mcb entry
|
||||
; esp -> data run size
|
||||
; esp+8 -> cluster (delta)
|
||||
; CF=0 -> mcb end
|
||||
push eax ecx edi
|
||||
lea edi, [esp+16]
|
||||
xor eax, eax
|
||||
@ -1989,64 +1994,57 @@ ntfs_CreateFile:
|
||||
cmp byte [esi], 0
|
||||
jnz @f
|
||||
xor ebx, ebx
|
||||
movi eax, ERROR_ACCESS_DENIED ; root directory itself
|
||||
movi eax, ERROR_ACCESS_DENIED
|
||||
ret
|
||||
@@: ; 1. Search file
|
||||
call ntfs_lock
|
||||
stdcall ntfs_find_lfn, [esp+4]
|
||||
jnc .found
|
||||
cmp [ebp+NTFS.ntfsFragmentCount], 1
|
||||
jnz @f ; record fragmented
|
||||
jnz ntfsUnsupported ; record fragmented
|
||||
test eax, eax
|
||||
jnz .notFound
|
||||
push ERROR_FS_FAIL
|
||||
jmp ntfsError
|
||||
@@:
|
||||
push ERROR_UNSUPPORTED_FS
|
||||
jmp ntfsError
|
||||
jz ntfsFail
|
||||
jmp .notFound
|
||||
|
||||
.found: ; rewrite
|
||||
cmp [ebp+NTFS.ntfs_cur_iRecord], 16
|
||||
jc ntfsDenied
|
||||
cmp [ebp+NTFS.ntfsFolder], 1
|
||||
jz ntfsDenied
|
||||
mov [ebp+NTFS.ntfs_cur_attr], 0x80
|
||||
mov [ebp+NTFS.ntfs_cur_offs], 0
|
||||
mov [ebp+NTFS.ntfs_cur_size], 0
|
||||
call ntfs_read_attr
|
||||
jnc @f
|
||||
push ERROR_ACCESS_DENIED
|
||||
jmp ntfsError
|
||||
@@:
|
||||
push ERROR_UNSUPPORTED_FS
|
||||
jc ntfsDenied
|
||||
mov eax, [ebp+NTFS.frs_buffer]
|
||||
cmp word [eax+baseRecordReuse], 0
|
||||
jnz ntfsError ; auxiliary record
|
||||
jnz ntfsUnsupported ; auxiliary record
|
||||
cmp byte [eax+hardLinkCounter], 1
|
||||
jnz ntfsError ; file copying required
|
||||
jnz ntfsUnsupported ; file copying required
|
||||
mov ecx, [ebp+NTFS.ntfs_attr_offs]
|
||||
cmp byte [ecx+nonResidentFlag], 1
|
||||
jnz ntfsError ; resident $DATA
|
||||
jnz ntfsUnsupported ; resident $DATA
|
||||
mov eax, [ebx+4]
|
||||
mov edx, [ebx+8]
|
||||
add eax, [ebx+12]
|
||||
adc edx, 0
|
||||
cmp edx, [ecx+attributeRealSize+4]
|
||||
jnz ntfsError
|
||||
jnz ntfsUnsupported
|
||||
cmp [ecx+attributeRealSize], eax
|
||||
jnz ntfsError
|
||||
jnz ntfsUnsupported
|
||||
jmp ntfs_WriteFile.write
|
||||
|
||||
.notFound: ; create; check name
|
||||
.notFound: ; create; check path folders
|
||||
cmp dword [esp+4], 0
|
||||
jnz .bad
|
||||
jnz ntfsNotFound
|
||||
cmp byte [esi], 0
|
||||
jnz @f
|
||||
.bad: ; path folder not found
|
||||
push ERROR_FILE_NOT_FOUND
|
||||
jmp ntfsError
|
||||
@@: ; 2. Prepair directory record
|
||||
jz ntfsNotFound
|
||||
; 2. Prepare directory record
|
||||
mov ecx, esi
|
||||
@@: ; count characters
|
||||
inc ecx
|
||||
cmp byte [ecx], '/'
|
||||
jz .bad
|
||||
jz ntfsNotFound
|
||||
cmp byte [ecx], 0
|
||||
jnz @b
|
||||
sub ecx, esi
|
||||
@ -2057,16 +2055,15 @@ ntfs_CreateFile:
|
||||
mov edi, [ebp+NTFS.cur_index_buf]
|
||||
push esi
|
||||
push ecx
|
||||
cmp dword [edi], 'INDX' ; where are we?
|
||||
cmp dword [edi], 'INDX'
|
||||
jz .indexRecord
|
||||
mov esi, [ebp+NTFS.frs_buffer] ; mftRecord
|
||||
mov esi, [ebp+NTFS.frs_buffer] ; indexRoot
|
||||
mov edx, [esi+recordRealSize]
|
||||
add edx, ecx
|
||||
cmp [esi+recordAllocatedSize], edx
|
||||
jnc @f
|
||||
add esp, 12
|
||||
push ERROR_UNSUPPORTED_FS ; indexAllocation required
|
||||
jmp ntfsError
|
||||
jmp ntfsUnsupported ; indexAllocation required
|
||||
@@: ; index fits in the indexRoot
|
||||
mov [esi+recordRealSize], edx
|
||||
mov ecx, edx
|
||||
@ -2078,7 +2075,7 @@ ntfs_CreateFile:
|
||||
mov esi, [esp]
|
||||
add [edi+sizeWithHeader], esi
|
||||
add [edi+sizeWithoutHeader], esi
|
||||
mov cx, [edi+attributeOffset]
|
||||
mov cl, [edi+attributeOffset]
|
||||
add edi, ecx
|
||||
add [edi+16+nodeRealSize], esi
|
||||
add [edi+16+nodeAllocatedSize], esi
|
||||
@ -2090,16 +2087,15 @@ ntfs_CreateFile:
|
||||
jmp .common
|
||||
|
||||
.indexRecord:
|
||||
mov edx, [edi+1ch]
|
||||
mov edx, [edi+28]
|
||||
add edx, ecx
|
||||
cmp [edi+20h], edx
|
||||
cmp [edi+32], edx
|
||||
jnc @f
|
||||
add esp, 12
|
||||
push ERROR_UNSUPPORTED_FS ; new node required
|
||||
jmp ntfsError
|
||||
jmp ntfsUnsupported ; new node required
|
||||
@@: ; index fits in the node
|
||||
mov [edi+1ch], edx
|
||||
lea edi, [edi+edx+14h]
|
||||
mov [edi+28], edx
|
||||
lea edi, [edi+edx+24-4]
|
||||
.common:
|
||||
mov esi, edi
|
||||
sub esi, [esp]
|
||||
@ -2159,7 +2155,7 @@ ntfs_CreateFile:
|
||||
@@: ; 3. File data
|
||||
cmp [ebp+NTFS.fileRealSize], 0
|
||||
jz .mftBitmap
|
||||
; One piece free space bitmap search engine
|
||||
; One piece free space bitmap search engine
|
||||
mov edi, [ebp+NTFS.BitmapBuffer]
|
||||
add edi, [ebp+NTFS.BitmapStart]
|
||||
mov eax, [ebp+NTFS.fileDataSize]
|
||||
@ -2167,12 +2163,10 @@ ntfs_CreateFile:
|
||||
jz .small
|
||||
push eax ; bitmap dwords
|
||||
add edi, 4
|
||||
xor edx, edx
|
||||
.start:
|
||||
mov ecx, [ebp+NTFS.BitmapSize]
|
||||
mov eax, edi
|
||||
sub eax, [ebp+NTFS.BitmapBuffer]
|
||||
sub ecx, eax
|
||||
add ecx, [ebp+NTFS.BitmapBuffer]
|
||||
sub ecx, edi
|
||||
shr ecx, 2
|
||||
@@:
|
||||
xor eax, eax
|
||||
@ -2194,6 +2188,7 @@ ntfs_CreateFile:
|
||||
jnz .start
|
||||
sub esi, 4
|
||||
mov eax, [esi]
|
||||
xor edx, edx
|
||||
bsr edx, eax
|
||||
inc edx
|
||||
push edx ; starting bit
|
||||
@ -2274,36 +2269,34 @@ ntfs_CreateFile:
|
||||
mov [esp+4], ecx
|
||||
@@:
|
||||
mov edi, [esp]
|
||||
mov esi, [ebp+NTFS.fileDataSize]
|
||||
mov edx, [edi]
|
||||
ror edx, cl
|
||||
xor eax, eax
|
||||
dec eax
|
||||
shr eax, cl
|
||||
shl eax, cl
|
||||
neg ecx
|
||||
add ecx, 32
|
||||
mov eax, -1
|
||||
sub esi, ecx
|
||||
jnc @f
|
||||
mov esi, ecx ; fits inside
|
||||
mov ecx, [ebp+NTFS.fileDataSize]
|
||||
shrd edx, eax, cl
|
||||
sub esi, ecx
|
||||
mov ecx, esi
|
||||
ror edx, cl
|
||||
mov [edi], edx
|
||||
sub ecx, [ebp+NTFS.fileDataSize]
|
||||
jc @f
|
||||
shl eax, cl ; fits inside dword
|
||||
shr eax, cl
|
||||
or [edi], eax
|
||||
jmp .writeData
|
||||
|
||||
@@:
|
||||
shrd edx, eax, cl
|
||||
mov [edi], edx
|
||||
mov ecx, esi
|
||||
or [edi], eax
|
||||
neg ecx
|
||||
push ecx
|
||||
shr ecx, 5
|
||||
add edi, 4
|
||||
xor eax, eax
|
||||
dec eax
|
||||
rep stosd
|
||||
mov ecx, esi
|
||||
pop ecx
|
||||
and ecx, 31
|
||||
mov edx, [edi]
|
||||
shr edx, cl
|
||||
shld edx, eax, cl
|
||||
mov [edi], edx
|
||||
shr eax, cl
|
||||
shl eax, cl
|
||||
not eax
|
||||
or [edi], eax
|
||||
.writeData:
|
||||
pop edx
|
||||
sub edx, [ebp+NTFS.BitmapBuffer]
|
||||
@ -2319,10 +2312,7 @@ ntfs_CreateFile:
|
||||
mov ebx, [ebx+16]
|
||||
call fs_write64_app
|
||||
test eax, eax
|
||||
jz .mftBitmap
|
||||
push ERROR_DEVICE
|
||||
jmp ntfsError
|
||||
|
||||
jnz ntfsDevice
|
||||
; 4. MFT record
|
||||
.mftBitmap: ; search for free record
|
||||
mov edi, [ebp+NTFS.mftBitmapBuffer]
|
||||
@ -2335,14 +2325,9 @@ ntfs_CreateFile:
|
||||
movzx eax, byte [edi]
|
||||
not al
|
||||
bsf ecx, eax
|
||||
jnz @f
|
||||
push ERROR_UNSUPPORTED_FS ; no free records
|
||||
jmp ntfsError
|
||||
@@: ; mark record
|
||||
mov al, [edi]
|
||||
bts eax, ecx
|
||||
mov [edi], al
|
||||
; get record location
|
||||
jz ntfsUnsupported ; no free records
|
||||
bts [edi], ecx
|
||||
; get record location
|
||||
sub edi, [ebp+NTFS.mftBitmapBuffer]
|
||||
shl edi, 3
|
||||
add edi, ecx
|
||||
@ -2359,12 +2344,11 @@ ntfs_CreateFile:
|
||||
call ntfs_read_attr
|
||||
cmp [ebp+NTFS.ntfs_cur_read], 0
|
||||
jnz .mftRecord
|
||||
; extend MFT $DATA
|
||||
; extend MFT $DATA
|
||||
mov eax, [ebp+NTFS.mft_cluster]
|
||||
mul [ebp+NTFS.sectors_per_cluster]
|
||||
push ERROR_UNSUPPORTED_FS
|
||||
cmp eax, [ebp+NTFS.ntfsLastRead]
|
||||
jnz ntfsError ; auxiliary record
|
||||
jnz ntfsUnsupported ; auxiliary record
|
||||
mov edi, [ebp+NTFS.ntfs_attr_offs]
|
||||
mov ebx, [ebp+NTFS.sectors_per_cluster]
|
||||
shl ebx, 9+3
|
||||
@ -2375,8 +2359,9 @@ ntfs_CreateFile:
|
||||
adc byte [edi+attributeRealSize+4], 0
|
||||
add [edi+initialDataSize], ebx
|
||||
adc byte [edi+initialDataSize+4], 0
|
||||
add edi, [edi+dataRunsOffset]
|
||||
movzx eax, byte [edi]
|
||||
movzx eax, byte [edi+dataRunsOffset]
|
||||
add edi, eax
|
||||
mov al, [edi]
|
||||
inc edi
|
||||
shl eax, 4
|
||||
shr al, 4
|
||||
@ -2386,13 +2371,13 @@ ntfs_CreateFile:
|
||||
add ah, al
|
||||
shr eax, 8
|
||||
cmp byte [edi+eax], 0
|
||||
jnz ntfsError ; $MFT fragmented
|
||||
jnz ntfsUnsupported ; $MFT fragmented
|
||||
mov al, 8
|
||||
mov edx, [edi]
|
||||
rol eax, cl
|
||||
rol edx, cl
|
||||
add eax, edx
|
||||
jc ntfsError
|
||||
jc ntfsUnsupported
|
||||
ror eax, cl
|
||||
shr edx, cl
|
||||
mov [edi], eax
|
||||
@ -2405,15 +2390,13 @@ ntfs_CreateFile:
|
||||
mov ax, [edx]
|
||||
shr ax, cl
|
||||
test al, al
|
||||
jnz ntfsError
|
||||
jnz ntfsUnsupported
|
||||
dec al
|
||||
xchg [edx], al
|
||||
mov [edx+1], al
|
||||
pop eax
|
||||
push ERROR_OUT_OF_MEMORY
|
||||
stdcall kernel_alloc, ebx
|
||||
test eax, eax
|
||||
jz ntfsError
|
||||
jz ntfsNoMemory
|
||||
mov ecx, ebx
|
||||
shr ecx, 2
|
||||
mov edi, eax
|
||||
@ -2427,8 +2410,6 @@ ntfs_CreateFile:
|
||||
shr ecx, 9
|
||||
call fs_write64_sys ; clear new records
|
||||
stdcall kernel_free, ebx
|
||||
pop eax
|
||||
push ERROR_DEVICE
|
||||
mov eax, esi
|
||||
shr eax, 3+9
|
||||
mov ebx, eax
|
||||
@ -2439,12 +2420,12 @@ ntfs_CreateFile:
|
||||
xor edx, edx
|
||||
call fs_write64_app ; partition bitmap
|
||||
test eax, eax
|
||||
jnz ntfsError
|
||||
jnz ntfsDevice
|
||||
mov eax, [ebp+NTFS.frs_buffer]
|
||||
mov [ebp+NTFS.ntfs_cur_buf], eax
|
||||
call writeRecord ; $MFT
|
||||
test eax, eax
|
||||
jnz ntfsError
|
||||
jnz ntfsDevice
|
||||
mov eax, [ebp+NTFS.mftmirr_cluster]
|
||||
mul [ebp+NTFS.sectors_per_cluster]
|
||||
mov ebx, [ebp+NTFS.frs_buffer]
|
||||
@ -2452,8 +2433,7 @@ ntfs_CreateFile:
|
||||
dec ecx
|
||||
call fs_write64_sys ; $MFTMirr
|
||||
test eax, eax
|
||||
jnz ntfsError
|
||||
pop eax
|
||||
jnz ntfsDevice
|
||||
mov eax, [ebp+NTFS.ntfs_cur_offs]
|
||||
add [ebp+NTFS.ntfsLastRead], eax
|
||||
.mftRecord:
|
||||
@ -2466,7 +2446,7 @@ ntfs_CreateFile:
|
||||
shr ecx, 2
|
||||
rep stosd
|
||||
mov edi, [ebp+NTFS.frs_buffer]
|
||||
; record header
|
||||
; record header
|
||||
mov dword[edi], 'FILE'
|
||||
mov byte [edi+updateSequenceOffset], 2ah
|
||||
mov byte [edi+updateSequenceSize], 3
|
||||
@ -2478,13 +2458,13 @@ ntfs_CreateFile:
|
||||
rdtsc
|
||||
mov [edi+2ah], ax
|
||||
add edi, 30h
|
||||
; $StandardInformation
|
||||
; $StandardInformation
|
||||
mov byte [edi+attributeType], 10h
|
||||
mov byte [edi+sizeWithHeader], 48h
|
||||
mov byte [edi+sizeWithoutHeader], 30h
|
||||
mov byte [edi+attributeOffset], 18h
|
||||
add edi, 48h
|
||||
; $FileName
|
||||
; $FileName
|
||||
mov byte [edi+attributeType], 30h
|
||||
mov byte [edi+attributeID], 1
|
||||
mov cx, [esi+indexRawSize]
|
||||
@ -2493,7 +2473,7 @@ ntfs_CreateFile:
|
||||
add ecx, 8
|
||||
mov [edi+sizeWithHeader], ecx
|
||||
mov byte [edi+attributeOffset], 18h
|
||||
mov byte [edi+attributeFlags], 1
|
||||
mov byte [edi+indexedFlag], 1
|
||||
add edi, 18h
|
||||
add esi, 16
|
||||
sub ecx, 18h
|
||||
@ -2501,7 +2481,7 @@ ntfs_CreateFile:
|
||||
rep movsd
|
||||
cmp [ebp+NTFS.ntfsFolder], 0
|
||||
jnz @f
|
||||
; $Data
|
||||
; $Data
|
||||
mov byte [edi+attributeType], 80h
|
||||
cmp [ebp+NTFS.fileRealSize], 0
|
||||
jz .zeroSize
|
||||
@ -2536,19 +2516,17 @@ ntfs_CreateFile:
|
||||
mov byte [edi+attributeOffset], 20h
|
||||
mov dword[edi+18h], 490024h ; unicode $I30
|
||||
mov dword[edi+18h+4], 300033h
|
||||
add edi, 20h
|
||||
mov byte [edi+attributeType], 30h
|
||||
mov byte [edi+collationRule], 1
|
||||
mov byte [edi+20h+attributeType], 30h
|
||||
mov byte [edi+20h+collationRule], 1
|
||||
mov eax, [ebp+NTFS.sectors_per_cluster]
|
||||
shl eax, 9
|
||||
mov [edi+indexRecordSize], eax
|
||||
mov byte [edi+indexRecordSizeClus], 1
|
||||
mov byte [edi+16+indexOffset], 16
|
||||
mov byte [edi+16+nodeRealSize], 32
|
||||
mov byte [edi+16+nodeAllocatedSize], 32
|
||||
mov byte [edi+32+indexAllocatedSize], 16
|
||||
mov byte [edi+32+indexFlags], 2
|
||||
sub edi, 20h
|
||||
mov [edi+20h+indexRecordSize], eax
|
||||
mov byte [edi+20h+indexRecordSizeClus], 1
|
||||
mov byte [edi+30h+indexOffset], 16
|
||||
mov byte [edi+30h+nodeRealSize], 32
|
||||
mov byte [edi+30h+nodeAllocatedSize], 32
|
||||
mov byte [edi+40h+indexAllocatedSize], 16
|
||||
mov byte [edi+40h+indexFlags], 2
|
||||
mov al, 3
|
||||
.writeMftRecord:
|
||||
mov byte [edi+sizeWithHeader], 50h
|
||||
@ -2559,13 +2537,10 @@ ntfs_CreateFile:
|
||||
mov [ebp+NTFS.ntfs_cur_buf], edi
|
||||
call writeRecord
|
||||
test eax, eax
|
||||
jz @f
|
||||
push ERROR_DEVICE
|
||||
jmp ntfsError
|
||||
@@:
|
||||
jnz ntfsDevice
|
||||
mov esi, [ebp+PARTITION.Disk]
|
||||
call disk_sync
|
||||
; write MFT bitmap
|
||||
; write MFT bitmap
|
||||
mov eax, [ebp+NTFS.newMftRecord]
|
||||
shr eax, 3+9
|
||||
mov ebx, eax
|
||||
@ -2576,10 +2551,8 @@ ntfs_CreateFile:
|
||||
xor edx, edx
|
||||
call fs_write64_sys
|
||||
test eax, eax
|
||||
jz @f
|
||||
push ERROR_DEVICE
|
||||
jmp ntfsError
|
||||
@@: ; 5. Write partition bitmap
|
||||
jnz ntfsDevice
|
||||
; 5. Write partition bitmap
|
||||
cmp [ebp+NTFS.ntfsFolder], 0
|
||||
jnz @f
|
||||
cmp [ebp+NTFS.fileRealSize], 0
|
||||
@ -2598,27 +2571,27 @@ ntfs_CreateFile:
|
||||
xor edx, edx
|
||||
call fs_write64_app
|
||||
test eax, eax
|
||||
jz @f
|
||||
push ERROR_DEVICE
|
||||
jmp ntfsError
|
||||
jnz ntfsDevice
|
||||
@@:
|
||||
mov esi, [ebp+PARTITION.Disk]
|
||||
call disk_sync
|
||||
mov edi, [ebp+NTFS.indexOffset]
|
||||
mov eax, [ebp+NTFS.newMftRecord]
|
||||
mov [edi+fileRecordReference], eax
|
||||
; 6. Write directory node
|
||||
; 6. Write directory node
|
||||
mov eax, [ebp+NTFS.nodeLastRead]
|
||||
mov [ebp+NTFS.ntfsLastRead], eax
|
||||
mov eax, [ebp+NTFS.cur_index_buf]
|
||||
mov [ebp+NTFS.ntfs_cur_buf], eax
|
||||
call writeRecord
|
||||
push eax
|
||||
test eax, eax
|
||||
jnz ntfsDevice
|
||||
mov ebx, [ebp+NTFS.fileRealSize]
|
||||
ntfsDone:
|
||||
mov esi, [ebp+PARTITION.Disk]
|
||||
call disk_sync
|
||||
call ntfs_unlock
|
||||
pop eax
|
||||
mov ebx, [ebp+NTFS.fileRealSize]
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
writeRecord:
|
||||
@ -2641,7 +2614,7 @@ writeRecord:
|
||||
mov [esi-2], ax
|
||||
dec ecx
|
||||
jnz @b
|
||||
; writing to disk
|
||||
; writing to disk
|
||||
mov eax, [ebp+NTFS.ntfsLastRead]
|
||||
mov ebx, [ebp+NTFS.ntfs_cur_buf]
|
||||
pop ecx
|
||||
@ -2651,6 +2624,8 @@ writeRecord:
|
||||
bitmapBuffering:
|
||||
; Extend BitmapBuffer and read next 32kb of bitmap
|
||||
; Warning: $Bitmap fragmentation is not foreseen
|
||||
; if edi -> position in bitmap buffer,
|
||||
; then ecx = number of buffered dwords left
|
||||
push ebx
|
||||
mov eax, [ebp+NTFS.BitmapTotalSize]
|
||||
cmp eax, [ebp+NTFS.BitmapSize]
|
||||
@ -2680,9 +2655,8 @@ bitmapBuffering:
|
||||
mov [ebp+NTFS.BitmapSize], eax
|
||||
@@:
|
||||
mov ecx, [ebp+NTFS.BitmapSize]
|
||||
mov eax, edi
|
||||
sub eax, [ebp+NTFS.BitmapBuffer]
|
||||
sub ecx, eax
|
||||
add ecx, [ebp+NTFS.BitmapBuffer]
|
||||
sub ecx, edi
|
||||
shr ecx, 2
|
||||
pop ebx
|
||||
ret
|
||||
@ -2695,7 +2669,7 @@ bitmapBuffering:
|
||||
.end:
|
||||
add esp, 12 ; double ret
|
||||
push ERROR_DISK_FULL
|
||||
jmp ntfsError
|
||||
jmp ntfsOut
|
||||
|
||||
;----------------------------------------------------------------
|
||||
ntfs_WriteFile:
|
||||
@ -2707,39 +2681,34 @@ ntfs_WriteFile:
|
||||
@@:
|
||||
call ntfs_lock
|
||||
stdcall ntfs_find_lfn, [esp+4]
|
||||
jnc .found
|
||||
push ERROR_FILE_NOT_FOUND
|
||||
jmp ntfsError
|
||||
.found:
|
||||
jc ntfsNotFound
|
||||
cmp [ebp+NTFS.ntfs_cur_iRecord], 16
|
||||
jc ntfsDenied
|
||||
mov [ebp+NTFS.ntfs_cur_attr], 0x80
|
||||
mov [ebp+NTFS.ntfs_cur_offs], 0
|
||||
mov [ebp+NTFS.ntfs_cur_size], 0
|
||||
call ntfs_read_attr
|
||||
jnc @f
|
||||
push ERROR_ACCESS_DENIED
|
||||
jmp ntfsError
|
||||
@@:
|
||||
push ERROR_UNSUPPORTED_FS
|
||||
jc ntfsDenied
|
||||
mov eax, [ebp+NTFS.frs_buffer]
|
||||
cmp word [eax+baseRecordReuse], 0
|
||||
jnz ntfsError ; auxiliary record
|
||||
jnz ntfsUnsupported ; auxiliary record
|
||||
cmp byte [eax+hardLinkCounter], 1
|
||||
jnz ntfsError ; file copying required
|
||||
jnz ntfsUnsupported ; file copying required
|
||||
mov ecx, [ebp+NTFS.ntfs_attr_offs]
|
||||
cmp byte [ecx+nonResidentFlag], 1
|
||||
jnz ntfsError ; resident $DATA
|
||||
jnz ntfsUnsupported ; resident $DATA
|
||||
cmp word [ecx+attributeFlags], 0
|
||||
jnz ntfsUnsupported
|
||||
mov eax, [ebx+4]
|
||||
mov edx, [ebx+8]
|
||||
add eax, [ebx+12]
|
||||
adc edx, 0
|
||||
cmp edx, [ecx+attributeRealSize+4]
|
||||
jc .write
|
||||
jnz ntfsError ; end of file
|
||||
jnz ntfsUnsupported ; end of file
|
||||
cmp [ecx+attributeRealSize], eax
|
||||
jc ntfsError
|
||||
jc ntfsUnsupported
|
||||
.write:
|
||||
pop eax
|
||||
push ERROR_DEVICE
|
||||
mov eax, [ebx+4]
|
||||
mov edx, [ebx+8]
|
||||
mov ecx, [ebx+12]
|
||||
@ -2752,7 +2721,7 @@ ntfs_WriteFile:
|
||||
lea edi, [ebp+NTFS.ntfs_bitmap_buf]
|
||||
mov [ebp+NTFS.ntfs_cur_buf], edi
|
||||
call ntfs_read_attr.continue
|
||||
jc ntfsError
|
||||
jc ntfsDevice
|
||||
mov eax, [ebx+4]
|
||||
and eax, 1FFh
|
||||
add edi, eax
|
||||
@ -2774,7 +2743,7 @@ ntfs_WriteFile:
|
||||
pop ebx
|
||||
pop ecx
|
||||
test eax, eax
|
||||
jnz ntfsError
|
||||
jnz ntfsDevice
|
||||
test ecx, ecx
|
||||
jz @f
|
||||
mov eax, [ebx+4]
|
||||
@ -2794,7 +2763,7 @@ ntfs_WriteFile:
|
||||
mov [ebp+NTFS.ntfsWriteAttr], 0
|
||||
pop [ebp+NTFS.ntfs_cur_offs]
|
||||
pop ecx
|
||||
jc ntfsError
|
||||
jc ntfsDevice
|
||||
and ecx, 1FFh
|
||||
jz @f
|
||||
add esi, [ebp+NTFS.ntfs_cur_read]
|
||||
@ -2802,7 +2771,7 @@ ntfs_WriteFile:
|
||||
lea edi, [ebp+NTFS.ntfs_bitmap_buf]
|
||||
mov [ebp+NTFS.ntfs_cur_buf], edi
|
||||
call ntfs_read_attr.continue
|
||||
jc ntfsError
|
||||
jc ntfsDevice
|
||||
rep movsb
|
||||
push ebx
|
||||
mov eax, [ebp+NTFS.ntfsLastRead]
|
||||
@ -2811,20 +2780,216 @@ ntfs_WriteFile:
|
||||
xor edx, edx
|
||||
call fs_write64_app
|
||||
pop ebx
|
||||
test eax, eax
|
||||
jnz ntfsDevice
|
||||
@@:
|
||||
mov esi, [ebp+PARTITION.Disk]
|
||||
call disk_sync
|
||||
call ntfs_unlock
|
||||
pop eax
|
||||
xor eax, eax
|
||||
mov ebx, [ebx+12]
|
||||
jmp ntfsDone
|
||||
|
||||
;----------------------------------------------------------------
|
||||
ntfs_Delete:
|
||||
cmp byte [esi], 0
|
||||
jnz @f
|
||||
xor ebx, ebx
|
||||
movi eax, ERROR_ACCESS_DENIED
|
||||
ret
|
||||
@@:
|
||||
call ntfs_lock
|
||||
stdcall ntfs_find_lfn, [esp+4]
|
||||
jc ntfsNotFound
|
||||
cmp [ebp+NTFS.ntfs_cur_iRecord], 16
|
||||
jc ntfsDenied
|
||||
cmp [ebp+NTFS.ntfsFragmentCount], 1
|
||||
jnz ntfsUnsupported ; record fragmented
|
||||
test byte [eax+indexFlags], 1
|
||||
jnz ntfsUnsupported ; index has a subnode
|
||||
mov edx, [ebp+NTFS.ntfs_cur_iRecord]
|
||||
shr edx, 3
|
||||
cmp edx, [ebp+NTFS.mftBitmapSize]
|
||||
jnc ntfsUnsupported
|
||||
; delete index from the node
|
||||
movzx edx, word [eax+indexAllocatedSize]
|
||||
mov edi, [ebp+NTFS.cur_index_buf]
|
||||
cmp dword [edi], 'INDX'
|
||||
jz .indexRecord
|
||||
mov esi, [ebp+NTFS.frs_buffer] ; indexRoot
|
||||
mov ecx, [esi+recordRealSize]
|
||||
shr ecx, 2
|
||||
rep movsd
|
||||
mov esi, [ebp+NTFS.cur_index_buf]
|
||||
mov edi, [ebp+NTFS.ntfs_attr_offs]
|
||||
sub edi, [ebp+NTFS.frs_buffer]
|
||||
add edi, esi
|
||||
sub [edi+sizeWithHeader], edx
|
||||
sub [edi+sizeWithoutHeader], edx
|
||||
mov cl, [edi+attributeOffset]
|
||||
add edi, ecx
|
||||
sub [edi+16+nodeRealSize], edx
|
||||
sub [edi+16+nodeAllocatedSize], edx
|
||||
sub eax, esi
|
||||
add eax, edi
|
||||
sub [esi+recordRealSize], edx
|
||||
mov ecx, [esi+recordRealSize]
|
||||
jmp @f
|
||||
|
||||
.indexRecord:
|
||||
sub [edi+28], edx
|
||||
mov ecx, [edi+28]
|
||||
add ecx, 24
|
||||
@@:
|
||||
add ecx, [ebp+NTFS.cur_index_buf]
|
||||
sub ecx, eax
|
||||
shr ecx, 2
|
||||
mov esi, eax
|
||||
add esi, edx
|
||||
mov edi, eax
|
||||
rep movsd
|
||||
mov eax, [ebp+NTFS.ntfsLastRead]
|
||||
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
|
||||
call ntfs_read_attr
|
||||
jc .folder
|
||||
mov esi, [ebp+NTFS.frs_buffer]
|
||||
cmp word [esi+baseRecordReuse], 0
|
||||
jnz ntfsUnsupported ; auxiliary record
|
||||
cmp byte [esi+hardLinkCounter], 2
|
||||
jnc .writeFileRecord ; delete hard link
|
||||
mov esi, [ebp+NTFS.ntfs_attr_offs]
|
||||
cmp byte [esi+nonResidentFlag], 0
|
||||
jz .writeBitmapMFT
|
||||
movzx eax, byte [esi+dataRunsOffset]
|
||||
add esi, eax
|
||||
xor edi, edi
|
||||
sub esp, 16
|
||||
.clearBitmap: ; "delete" file data
|
||||
call ntfs_decode_mcb_entry
|
||||
jnc .mcbEnd
|
||||
cmp dword[esp+8], 0
|
||||
jz .clearBitmap
|
||||
add edi, [esp+8]
|
||||
mov ebx, [esp]
|
||||
mov eax, edi
|
||||
add eax, ebx
|
||||
shr eax, 3
|
||||
inc eax
|
||||
cmp eax, [ebp+NTFS.BitmapSize]
|
||||
jc .buffered
|
||||
add eax, [ebp+NTFS.BitmapBuffer]
|
||||
add esp, 16
|
||||
push edi
|
||||
mov edi, eax
|
||||
@@:
|
||||
call bitmapBuffering
|
||||
shl ecx, 2
|
||||
js @b
|
||||
pop edi
|
||||
sub esp, 16
|
||||
.buffered:
|
||||
push edi
|
||||
mov ecx, edi
|
||||
shr edi, 5
|
||||
shl edi, 2
|
||||
add edi, [ebp+NTFS.BitmapBuffer]
|
||||
and ecx, 31
|
||||
xor eax, eax
|
||||
dec eax
|
||||
shr eax, cl
|
||||
shl eax, cl
|
||||
neg ecx
|
||||
add ecx, 32
|
||||
sub ecx, ebx
|
||||
jc @f
|
||||
shl eax, cl ; fits inside dword
|
||||
shr eax, cl
|
||||
not eax
|
||||
and [edi], eax
|
||||
jmp .writeBitmap
|
||||
|
||||
@@:
|
||||
not eax
|
||||
and [edi], eax
|
||||
neg ecx
|
||||
push ecx
|
||||
shr ecx, 5
|
||||
add edi, 4
|
||||
xor eax, eax
|
||||
rep stosd
|
||||
pop ecx
|
||||
and ecx, 31
|
||||
dec eax
|
||||
shr eax, cl
|
||||
shl eax, cl
|
||||
and [edi], eax
|
||||
.writeBitmap:
|
||||
pop edi
|
||||
mov ecx, edi
|
||||
add ecx, ebx
|
||||
add ecx, 4095
|
||||
shr ecx, 3+9
|
||||
mov eax, edi
|
||||
shr eax, 3+9
|
||||
sub ecx, eax
|
||||
mov ebx, eax
|
||||
shl ebx, 9
|
||||
add eax, [ebp+NTFS.BitmapLocation]
|
||||
add ebx, [ebp+NTFS.BitmapBuffer]
|
||||
xor edx, edx
|
||||
call fs_write64_app
|
||||
jmp .clearBitmap
|
||||
|
||||
.mcbEnd:
|
||||
add esp, 16
|
||||
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
|
||||
call ntfs_read_attr
|
||||
cmp [ebp+NTFS.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 ecx, eax
|
||||
shr eax, 3
|
||||
and ecx, 7
|
||||
mov edi, [ebp+NTFS.mftBitmapBuffer]
|
||||
btr [edi+eax], ecx
|
||||
shr eax, 9
|
||||
mov ebx, eax
|
||||
shl ebx, 9
|
||||
add eax, [ebp+NTFS.mftBitmapLocation]
|
||||
add ebx, edi
|
||||
mov ecx, 1
|
||||
xor edx, edx
|
||||
call fs_write64_sys
|
||||
mov esi, [ebp+NTFS.frs_buffer]
|
||||
mov byte [esi+recordFlags], 0
|
||||
.writeFileRecord:
|
||||
dec byte [esi+hardLinkCounter]
|
||||
mov [ebp+NTFS.ntfs_cur_buf], esi
|
||||
call writeRecord
|
||||
; write directory node
|
||||
mov eax, [ebp+NTFS.nodeLastRead]
|
||||
mov [ebp+NTFS.ntfsLastRead], eax
|
||||
mov eax, [ebp+NTFS.cur_index_buf]
|
||||
mov [ebp+NTFS.ntfs_cur_buf], eax
|
||||
call writeRecord
|
||||
test eax, eax
|
||||
jz ntfsDone
|
||||
jmp ntfsDevice
|
||||
|
||||
;----------------------------------------------------------------
|
||||
ntfs_SetFileEnd:
|
||||
ntfs_SetFileInfo:
|
||||
ntfs_Delete:
|
||||
mov eax, ERROR_UNSUPPORTED_FS
|
||||
movi eax, ERROR_UNSUPPORTED_FS
|
||||
ret
|
||||
|
||||
;----------------------------------------------------------------
|
||||
@ -2837,12 +3002,9 @@ ntfs_GetFileInfo:
|
||||
call ntfs_lock
|
||||
stdcall ntfs_find_lfn, [esp+4]
|
||||
jnc .found
|
||||
push ERROR_FILE_NOT_FOUND
|
||||
test eax, eax
|
||||
jnz ntfsError
|
||||
pop eax
|
||||
push ERROR_FS_FAIL
|
||||
jmp ntfsError
|
||||
jz ntfsFail
|
||||
jmp ntfsNotFound
|
||||
.found:
|
||||
push esi edi
|
||||
mov esi, eax
|
||||
@ -2854,8 +3016,25 @@ ntfs_GetFileInfo:
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
ntfsError:
|
||||
ntfsUnsupported:
|
||||
push ERROR_UNSUPPORTED_FS
|
||||
ntfsOut:
|
||||
call ntfs_unlock
|
||||
xor ebx, ebx
|
||||
pop eax
|
||||
ret
|
||||
ntfsDevice:
|
||||
push ERROR_DEVICE
|
||||
jmp ntfsOut
|
||||
ntfsNotFound:
|
||||
push ERROR_FILE_NOT_FOUND
|
||||
jmp ntfsOut
|
||||
ntfsDenied:
|
||||
push ERROR_ACCESS_DENIED
|
||||
jmp ntfsOut
|
||||
ntfsFail:
|
||||
push ERROR_FS_FAIL
|
||||
jmp ntfsOut
|
||||
ntfsNoMemory:
|
||||
push ERROR_OUT_OF_MEMORY
|
||||
jmp ntfsOut
|
||||
|
Loading…
Reference in New Issue
Block a user