Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 6296 → Rev 6297

/kernel/trunk/fs/ntfs.inc
83,10 → 83,16
indexFlags = 12
directoryRecordReference = 16
directoryReferenceReuse = 16h
fileCreated = 18h
fileModified = 20h
recordModified = 28h
fileAccessed = 30h
fileAllocatedSize = 38h
fileRealSize = 40h
fileFlags = 48h
fileNameLength = 50h
namespace = 51h
fileName = 52h
 
struct NTFS PARTITION
Lock MUTEX ? ; Currently operations with one partition
275,6 → 281,7
.nope:
xor eax, eax
jmp .exit
 
; By given bootsector, initialize some NTFS variables
.ntfs_setup:
movi eax, sizeof.NTFS
309,6 → 316,7
mul [ebp+NTFS.sectors_per_cluster]
shl eax, 9
jmp .1
 
@@:
neg eax
mov ecx, eax
364,6 → 372,7
@@:
add eax, [eax+4]
jmp .scandata
 
.founddata:
cmp byte [eax+8], 0
jz .fail_free_mft
384,6 → 393,7
mov [eax+4], edx
inc [ebp+NTFS.mft_retrieval_size]
jmp .scanmcb
 
.scanmcbend:
add esp, 10h
; there may be other portions of $DATA attribute in auxiliary records;
498,6 → 508,7
popad
add esp, 14h
jmp .fail_free_mft
 
@@:
mov esi, [ebp+NTFS.mft_retrieval]
mov edi, eax
601,6 → 612,7
pop eax
jnz .mftscan
jmp .nomft
 
@@:
push ecx
add ecx, eax
649,16 → 661,20
pop eax
jz .nomft
jmp .mftscan
@@:
popad
ret
 
.errret2_pop:
xor eax, eax
.errret_pop:
pop ecx
.errread:
pop ecx
.errret:
mov [esp+28], eax
stc
@@:
popad
ret
 
.nomft:
; 1. Read file record.
; N.B. This will do recursive call of read_attr for $MFT::$Data.
675,20 → 691,22
; a) For auxiliary records, read base record.
; If base record is present, base iRecord may be 0 (for $Mft),
; but SequenceNumber is nonzero.
cmp dword [eax+24h], 0
cmp word [eax+baseRecordReuse], 0
jz @f
mov eax, [eax+20h]
mov eax, [eax+baseRecordReference]
.beginfindattr:
mov [ebp+NTFS.attr_iRecord], eax
call ntfs_read_file_record
jc .errret
jmp @f
 
.newAttribute:
pushad
and [ebp+NTFS.cur_read], 0
@@:
; b) Scan for required attribute and for $ATTR_LIST
mov eax, [ebp+NTFS.frs_buffer]
movzx ecx, word [eax+14h]
movzx ecx, word [eax+attributeOffset]
add eax, ecx
mov ecx, [ebp+NTFS.cur_attr]
and [ebp+NTFS.attr_offs], 0
703,17 → 721,19
jnz .scancont
mov [ebp+NTFS.attr_list], eax
jmp .scancont
 
.okattr:
; ignore named $DATA attributes (aka NTFS streams)
cmp ecx, 0x80
jnz @f
cmp byte [eax+9], 0
cmp byte [eax+nameLength], 0
jnz .scancont
@@:
mov [ebp+NTFS.attr_offs], eax
.scancont:
add eax, [eax+4]
add eax, [eax+sizeWithHeader]
jmp .scanattr
 
.continue:
pushad
and [ebp+NTFS.cur_read], 0
726,20 → 746,16
call .doreadattr
pop edx
pop ecx
jc @f
jc .ret
cmp [ebp+NTFS.bCanContinue], 0
jz @f
jz .ret
sub edx, [ebp+NTFS.cur_read]
neg edx
shr edx, 9
sub ecx, edx
mov [ebp+NTFS.cur_size], ecx
jnz .not_in_cur
@@:
popad
ret
jz .ret
.noattr:
.not_in_cur:
cmp [ebp+NTFS.cur_attr], 0x20
jz @f
mov ecx, [ebp+NTFS.attr_list]
747,9 → 763,11
jnz .lookattr
.ret_is_attr:
and dword [esp+28], 0
cmp [ebp+NTFS.attr_offs], 1 ; CF set <=> attr_offs == 0
cmp [ebp+NTFS.attr_offs], 1 ; define CF
.ret:
popad
ret
 
.lookattr:
; required attribute or required offset was not found in base record;
; it may be present in auxiliary records;
804,6 → 822,7
movzx ecx, word [esi+4]
add esi, ecx
jmp .scanlist
 
@@:
; ignore named $DATA attributes (aka NTFS streams)
cmp eax, 0x80
822,14 → 841,7
; if attribute is in auxiliary records, its size is defined only in first
mov eax, [esi+10h]
call ntfs_read_file_record
jnc @f
.errret_pop:
pop ecx ecx
jmp .errret
.errret2_pop:
xor eax, eax
jmp .errret_pop
@@:
jc .errret_pop
mov eax, [ebp+NTFS.frs_buffer]
movzx ecx, word [eax+14h]
add eax, ecx
842,6 → 854,7
.l1:
add eax, [eax+4]
jmp @b
 
@@:
cmp eax, 0x80
jnz @f
854,6 → 867,7
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.attr_size], ecx
868,18 → 882,17
ja @f
mov edi, [esi+10h] ; keep previous iRecord
jmp .scanlistcont
 
@@:
pop ecx
.scanlistfound:
cmp edi, -1
jnz @f
popad
ret
@@:
jz .ret
mov eax, [ebp+NTFS.cur_iRecord]
mov [ebp+NTFS.attr_iBaseRecord], eax
mov eax, edi
jmp .beginfindattr
 
.scanlistdone:
pop ecx
sub ecx, ebp
936,9 → 949,9
 
.doreadattr:
mov [ebp+NTFS.bCanContinue], 0
cmp byte [ecx+8], 0
cmp byte [ecx+nonResidentFlag], 0
jnz .nonresident
mov eax, [ecx+10h] ; length
mov eax, [ecx+sizeWithoutHeader]
mov esi, eax
mov edx, [ebp+NTFS.cur_offs]
shr eax, 9
946,7 → 959,7
jb .okret
shl edx, 9
sub esi, edx
movzx eax, word [ecx+14h]
movzx eax, word [ecx+attributeOffset]
add edx, eax
add edx, ecx ; edx -> data
mov eax, [ebp+NTFS.cur_size]
967,6 → 980,7
call memmove
and [ebp+NTFS.cur_size], 0 ; CF=0
ret
 
.nonresident:
; Not all auxiliary records contain correct FileSize info
mov eax, dword [ebp+NTFS.attr_size]
976,8 → 990,8
cmp eax, -1
pop eax
jnz @f
mov eax, [ecx+30h] ; FileSize
mov edx, [ecx+34h]
mov eax, [ecx+attributeRealSize]
mov edx, [ecx+attributeRealSize+4]
mov dword [ebp+NTFS.attr_size], eax
mov dword [ebp+NTFS.attr_size+4], edx
@@:
991,6 → 1005,7
.okret:
clc
ret
 
@@:
; reduce read length
and [ebp+NTFS.cur_tail], 0
1006,7 → 1021,7
mov eax, [ebp+NTFS.cur_offs]
xor edx, edx
div [ebp+NTFS.sectors_per_cluster]
sub eax, [ecx+10h] ; first_vbo
sub eax, [ecx+firstVCN]
jb .okret
; eax = cluster, edx = starting sector
cmp [ebp+NTFS.cur_attr], 0x80
1018,11 → 1033,12
jnz @f
mov dword[esp], fs_write64_app
jmp @f
 
.sys:
push fs_read64_sys
@@:
sub esp, 10h
movzx esi, word [ecx+20h] ; mcb_info_ofs
movzx esi, word [ecx+dataRunsOffset]
add esi, ecx
xor edi, edi
mov [ebp+NTFS.fragmentCount], 0
1074,11 → 1090,13
@@:
clc
ret
 
.errread2:
pop ecx
add esp, 14h
stc
ret
 
.break:
add esp, 14h ; CF=0
mov [ebp+NTFS.bCanContinue], 1
1142,6 → 1160,7
.ret:
pop edx ecx
ret
 
.errret:
pop edx ecx
xor eax, eax
1158,9 → 1177,9
shr eax, 9
mov ecx, eax
inc eax
cmp [ebx+6], ax
cmp [ebx+updateSequenceSize], ax
jnz .err
movzx eax, word [ebx+4]
movzx eax, word [ebx+updateSequenceOffset]
lea esi, [eax+ebx]
lodsw
mov edx, eax
1175,6 → 1194,7
popad
clc
ret
 
.err:
popad
stc
1245,7 → 1265,7
; [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.cur_iRecord], 5 ; start parse from root cluster
mov [ebp+NTFS.cur_iRecord], 5 ; start from root directory
.doit2:
mov [ebp+NTFS.cur_attr], 0x90 ; $INDEX_ROOT
and [ebp+NTFS.cur_offs], 0
1255,74 → 1275,30
mov [ebp+NTFS.cur_buf], eax
call ntfs_read_attr
mov eax, 0
jnc @f
.ret:
ret 4
@@:
jc .ret
cmp [ebp+NTFS.cur_read], 0x20
jc .ret
pushad
mov esi, [ebp+NTFS.cur_index_buf]
mov eax, [esi+14h]
add eax, 10h
mov edx, [esi+indexRecordSize]
shr edx, 9
cmp [ebp+NTFS.cur_index_size], edx
jc .realloc
add esi, rootNode
mov eax, [esi+nodeRealSize]
add eax, rootNode
cmp [ebp+NTFS.cur_read], eax
jae .readok1
add eax, 1FFh
shr eax, 9
cmp eax, [ebp+NTFS.cur_index_size]
ja @f
.stc_ret:
popad
stc
ret 4
@@:
; reallocate
push eax
stdcall kernel_free, [ebp+NTFS.cur_index_buf]
pop eax
mov [ebp+NTFS.cur_index_size], eax
stdcall kernel_alloc, eax
test eax, eax
jnz @f
and [ebp+NTFS.cur_index_size], 0
and [ebp+NTFS.cur_index_buf], 0
jmp .stc_ret
@@:
mov [ebp+NTFS.cur_index_buf], eax
popad
jmp .doit2
.readok1:
mov edx, [esi+8] ; subnode_size
shr edx, 9
cmp edx, [ebp+NTFS.cur_index_size]
jbe .ok2
push esi edx
stdcall kernel_alloc, edx
pop edx esi
test eax, eax
jz .stc_ret
mov edi, eax
mov ecx, [ebp+NTFS.cur_index_size]
shl ecx, 9-2
rep movsd
mov esi, eax
mov [ebp+NTFS.cur_index_size], edx
push esi edx
stdcall kernel_free, [ebp+NTFS.cur_index_buf]
pop edx esi
mov [ebp+NTFS.cur_index_buf], esi
.ok2:
add esi, 10h
jc .err
mov edi, [esp+4]
; edi -> name, esi -> current index data, edx = subnode size
; edi -> name, esi -> current index node, edx = subnode size
.scanloop:
add esi, [esi]
add esi, [esi+indexOffset]
.scanloopint:
test byte [esi+0Ch], 2
test byte [esi+indexFlags], 2
jnz .subnode
push esi
add esi, 0x52
movzx ecx, byte [esi-2]
movzx ecx, byte [esi+fileNameLength]
add esi, fileName
push edi
@@:
lodsw
1342,17 → 1318,38
pop esi
jb .subnode
.scanloopcont:
movzx eax, word [esi+8]
movzx eax, word [esi+indexAllocatedSize]
add esi, eax
jmp .scanloopint
 
.realloc:
mov edi, edx
stdcall kernel_alloc, [esi+indexRecordSize]
test eax, eax
jz .err
push [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.cur_index_buf], eax
call kernel_free
mov [ebp+NTFS.cur_index_size], edi
popad
jmp .doit2
 
.notfound:
mov [esp+1Ch], esi
.err:
popad
stc
.ret:
ret 4
 
.slash:
pop eax
pop edi
pop esi
.subnode:
test byte [esi+0Ch], 1
test byte [esi+indexFlags], 1
jz .notfound
movzx eax, word [esi+8]
movzx eax, word [esi+indexAllocatedSize]
mov eax, [esi+eax-8]
imul eax, [ebp+NTFS.sectors_per_cluster]
mov [ebp+NTFS.cur_offs], eax
1361,9 → 1358,7
mov eax, [ebp+NTFS.cur_index_buf]
mov esi, eax
mov [ebp+NTFS.cur_buf], eax
push edx
call ntfs_read_attr
pop edx
call ntfs_read_attr.newAttribute
mov eax, edx
shl eax, 9
cmp [ebp+NTFS.cur_read], eax
1374,14 → 1369,9
mov ebx, esi
call ntfs_restore_usa
jc .err
add esi, 0x18
add esi, recordNode
jmp .scanloop
.notfound:
mov [esp+1Ch], esi
.err:
popad
stc
ret 4
 
.found:
cmp byte [edi], 0
jz .done
1390,6 → 1380,7
pop edi
pop esi
jmp .scanloopcont
 
.done:
.next:
pop esi
1403,12 → 1394,10
cmp byte [esi-1], 0
jnz .doit2
cmp dword [esp+4], 0
jz @f
jz .ret
mov esi, [esp+4]
mov dword [esp+4], 0
jmp .doit2
@@:
ret 4
 
;----------------------------------------------------------------
ntfs_ReadFile:
1417,6 → 1406,7
or ebx, -1
movi eax, ERROR_ACCESS_DENIED
ret
 
@@:
call ntfs_lock
stdcall ntfs_find_lfn, [esp+4]
1425,6 → 1415,7
or ebx, -1
movi eax, ERROR_FILE_NOT_FOUND
ret
 
.found:
mov [ebp+NTFS.cur_attr], 0x80 ; $DATA
and [ebp+NTFS.cur_offs], 0
1435,6 → 1426,7
or ebx, -1
movi eax, ERROR_ACCESS_DENIED
ret
 
@@:
pushad
and dword [esp+10h], 0
1445,10 → 1437,10
popad
xor ebx, ebx
.eof:
push ERROR_END_OF_FILE
call ntfs_unlock
pop eax
movi eax, ERROR_END_OF_FILE
ret
 
@@:
mov ecx, [ebx+12]
mov edx, [ebx+16]
1487,6 → 1479,7
call ntfs_unlock
xor eax, eax
ret
 
@@:
cmp [ebp+NTFS.cur_read], 0x200
jz .alignedstart
1493,6 → 1486,7
.eof_ebx:
popad
jmp .eof
 
.alignedstart:
mov eax, [ebx+4]
push edx
1547,21 → 1541,12
;----------------------------------------------------------------
ntfs_ReadFolder:
call ntfs_lock
mov eax, 5 ; root cluster
mov [ebp+NTFS.cur_iRecord], 5 ; root directory
cmp byte [esi], 0
jz .doit
jz @f
stdcall ntfs_find_lfn, [esp+4]
jnc .doit2
.notfound:
or ebx, -1
push ERROR_FILE_NOT_FOUND
.pop_ret:
call ntfs_unlock
pop eax
ret
.doit:
mov [ebp+NTFS.cur_iRecord], eax
.doit2:
jc ntfsNotFound
@@:
mov [ebp+NTFS.cur_attr], 0x10 ; $STANDARD_INFORMATION
and [ebp+NTFS.cur_offs], 0
mov [ebp+NTFS.cur_size], 1
1568,82 → 1553,29
lea eax, [ebp+NTFS.bitmap_buf]
mov [ebp+NTFS.cur_buf], eax
call ntfs_read_attr
jc .notfound
jc ntfsFail
mov [ebp+NTFS.cur_attr], 0x90 ; $INDEX_ROOT
and [ebp+NTFS.cur_offs], 0
.doit:
mov eax, [ebp+NTFS.cur_index_size]
mov [ebp+NTFS.cur_size], eax
mov eax, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.cur_buf], eax
call ntfs_read_attr
jnc .ok
test eax, eax
jz .notfound
or ebx, -1
push ERROR_DEVICE
jmp .pop_ret
.ok:
call ntfs_read_attr.newAttribute
jc ntfsFail
cmp [ebp+NTFS.cur_read], 0x20
jae @f
or ebx, -1
.fserr:
push ERROR_FAT_TABLE
jmp .pop_ret
@@:
jc ntfsFail
pushad
mov esi, [ebp+NTFS.cur_index_buf]
mov eax, [esi+14h]
add eax, 10h
cmp [ebp+NTFS.cur_read], eax
jae .readok1
add eax, 1FFh
shr eax, 9
cmp eax, [ebp+NTFS.cur_index_size]
ja @f
popad
jmp .fserr
@@:
; reallocate
push eax
stdcall kernel_free, [ebp+NTFS.cur_index_buf]
pop eax
mov [ebp+NTFS.cur_index_size], eax
stdcall kernel_alloc, eax
test eax, eax
jnz @f
and [ebp+NTFS.cur_index_size], 0
and [ebp+NTFS.cur_index_buf], 0
.nomem:
call ntfs_unlock
popad
or ebx, -1
movi eax, ERROR_OUT_OF_MEMORY
ret
@@:
mov [ebp+NTFS.cur_index_buf], eax
popad
jmp .doit2
.readok1:
mov edx, [esi+8] ; subnode_size
mov edx, [esi+indexRecordSize]
shr edx, 9
cmp [ebp+NTFS.cur_index_size], edx
jc .realloc
mov [ebp+NTFS.cur_subnode_size], edx
cmp edx, [ebp+NTFS.cur_index_size]
jbe .ok2
push esi edx
stdcall kernel_alloc, edx
pop edx esi
test eax, eax
jz .nomem
mov edi, eax
mov ecx, [ebp+NTFS.cur_index_size]
shl ecx, 9-2
rep movsd
mov esi, eax
mov [ebp+NTFS.cur_index_size], edx
stdcall kernel_free, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.cur_index_buf], esi
.ok2:
add esi, 10h
add esi, rootNode
mov eax, [esi+nodeRealSize]
add eax, rootNode
cmp [ebp+NTFS.cur_read], eax
jc .err
mov edx, [ebx+16]
push dword [ebx+8] ; read ANSI/UNICODE name
; init header
1670,14 → 1602,31
pop esi
.skip_specials:
; at first, dump index root
add esi, [esi]
add esi, [esi+indexOffset]
.dump_root:
test byte [esi+0Ch], 2
test byte [esi+indexFlags], 2
jnz .dump_root_done
call .add_entry
movzx eax, word [esi+8]
movzx eax, word [esi+indexAllocatedSize]
add esi, eax
jmp .dump_root
 
.realloc:
mov edi, edx
stdcall kernel_alloc, [esi+indexRecordSize]
test eax, eax
jz .err
push [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.cur_index_buf], eax
call kernel_free
mov [ebp+NTFS.cur_index_size], edi
popad
jmp .doit
 
.err:
popad
jmp ntfsFail
 
.dump_root_done:
; now dump all subnodes
push ecx edi
1689,7 → 1638,7
mov [ebp+NTFS.cur_attr], 0xB0 ; $BITMAP
and [ebp+NTFS.cur_offs], 0
mov [ebp+NTFS.cur_size], 2
call ntfs_read_attr
call ntfs_read_attr.newAttribute
pop edi ecx
push 0 ; save offset in $BITMAP attribute
and [ebp+NTFS.cur_offs], 0
1697,14 → 1646,13
mov [ebp+NTFS.cur_attr], 0xA0
mov eax, [ebp+NTFS.cur_subnode_size]
mov [ebp+NTFS.cur_size], eax
mov eax, [ebp+NTFS.cur_index_buf]
mov esi, eax
mov [ebp+NTFS.cur_buf], eax
push [ebp+NTFS.cur_offs]
mov esi, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.cur_buf], esi
mov eax, [ebp+NTFS.cur_offs]
push eax
imul eax, [ebp+NTFS.cur_subnode_size]
mov [ebp+NTFS.cur_offs], eax
call ntfs_read_attr
call ntfs_read_attr.newAttribute
pop [ebp+NTFS.cur_offs]
mov eax, [ebp+NTFS.cur_subnode_size]
shl eax, 9
1723,15 → 1671,16
call ntfs_restore_usa
pop ebx
jc .dump_subnode_done
add esi, 0x18
add esi, [esi]
add esi, recordNode
add esi, [esi+indexOffset]
.dump_subnode:
test byte [esi+0Ch], 2
test byte [esi+indexFlags], 2
jnz .dump_subnode_done
call .add_entry
movzx eax, word [esi+8]
movzx eax, word [esi+indexAllocatedSize]
add esi, eax
jmp .dump_subnode
 
.dump_subnode_done:
inc [ebp+NTFS.cur_offs]
test [ebp+NTFS.cur_offs], 0x400*8-1
1750,11 → 1699,12
mov [ebp+NTFS.cur_offs], eax
mov [ebp+NTFS.cur_size], 2
push eax
call ntfs_read_attr
call ntfs_read_attr.newAttribute
pop eax
pop [ebp+NTFS.cur_offs]
push eax
jmp .dumploop
 
.done:
pop eax
pop edx
1781,8 → 1731,6
inc dword [eax+4] ; new file block copied
mov eax, [edx+4]
mov [edi+4], eax
; mov eax, dword [bitmap_buf+0x20]
; or al, 0x10
mov eax, 0x10
stosd
scasd
1812,6 → 1760,7
pop edi
add edi, 520
ret
 
@@:
rep stosb
pop ecx
1824,11 → 1773,11
 
.add_entry:
; do not return DOS 8.3 names
cmp byte [esi+0x51], 2
cmp byte [esi+namespace], 2
jz .ret
; do not return system files
; ... note that there will be no bad effects if system files also were reported ...
cmp dword [esi], 0x10
cmp dword [esi+fileRecordReference], 0x10
jb .ret
mov eax, [edx]
inc dword [eax+8] ; new file found
1840,8 → 1789,8
mov eax, [edx+4] ; flags
call ntfs_direntry_to_bdfe
push ecx esi edi
movzx ecx, byte [esi+0x50]
add esi, 0x52
movzx ecx, byte [esi+fileNameLength]
add esi, fileName
test byte [edi-0x24], 1
jz .ansi
shr ecx, 1
1853,6 → 1802,7
add edi, 520
pop esi ecx
ret
 
.ansi:
jecxz .skip
@@:
1870,7 → 1820,7
 
ntfs_direntry_to_bdfe:
mov [edi+4], eax ; ANSI/UNICODE name
mov eax, [esi+48h]
mov eax, [esi+fileFlags]
test eax, 0x10000000
jz @f
and eax, not 0x10000000
1879,129 → 1829,101
stosd
scasd
push edx
mov eax, [esi+0x18]
mov edx, [esi+0x1C]
mov eax, [esi+fileCreated]
mov edx, [esi+fileCreated+4]
call ntfs_datetime_to_bdfe
mov eax, [esi+0x30]
mov edx, [esi+0x34]
mov eax, [esi+fileAccessed]
mov edx, [esi+fileAccessed+4]
call ntfs_datetime_to_bdfe
mov eax, [esi+0x20]
mov edx, [esi+0x24]
mov eax, [esi+fileModified]
mov edx, [esi+fileModified+4]
call ntfs_datetime_to_bdfe
pop edx
mov eax, [esi+0x40]
mov eax, [esi+fileRealSize]
stosd
mov eax, [esi+0x44]
mov eax, [esi+fileRealSize+4]
stosd
ret
 
iglobal
_24 dd 24
_60 dd 60
_10000000 dd 10000000
days400year dd 365*400+100-4+1
days100year dd 365*100+25-1
days4year dd 365*4+1
days1year dd 365
months dd 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
months2 dd 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
_400 dd 400
_100 dd 100
months db 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
months2 db 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
endg
 
ntfs_datetime_to_bdfe:
; edx:eax = number of 100-nanosecond intervals since January 1, 1601, in UTC
push eax
push ebx ecx
mov ebx, eax
mov eax, edx
xor edx, edx
div [_10000000]
xchg eax, [esp]
div [_10000000]
pop edx
.sec:
; edx:eax = number of seconds since January 1, 1601
push eax
mov eax, edx
mov ecx, 10000000
div ecx
xchg eax, ebx
div ecx
.forEXT:
xchg eax, ebx
xor edx, edx
div [_60]
xchg eax, [esp]
div [_60]
mov ecx, 60
div ecx
xchg eax, ebx
div ecx
mov [edi], dl
pop edx
mov edx, ebx
; edx:eax = number of minutes
div [_60]
div ecx
mov [edi+1], dl
; eax = number of hours (note that 2^64/(10^7*60*60) < 2^32)
; eax = number of hours
xor edx, edx
div [_24]
mov [edi+2], dl
mov [edi+3], byte 0
mov cl, 24
div ecx
mov [edi+2], dx
; eax = number of days since January 1, 1601
xor edx, edx
div [days400year]
imul eax, 400
add eax, 1601
mov [edi+6], ax
mov eax, edx
xor edx, edx
div [days100year]
cmp al, 4
mov cx, 365
div ecx
mov ebx, eax
add ebx, 1601
shr eax, 2
sub edx, eax
mov cl, 25
div cl
xor ah, ah
add edx, eax
shr eax, 2
sub edx, eax
jns @f
dec ebx
add edx, 365
test bl, 3
jnz @f
dec eax
add edx, [days100year]
inc edx
@@:
imul eax, 100
add [edi+6], ax
mov eax, edx
xor edx, edx
div [days4year]
shl eax, 2
add [edi+6], ax
mov eax, edx
xor edx, edx
div [days1year]
cmp al, 4
xor eax, eax
mov ecx, months-1
test bl, 3
jnz @f
dec eax
add edx, [days1year]
add ecx, 12
@@:
add [edi+6], ax
push esi edx
mov esi, months
movzx eax, word [edi+6]
test al, 3
jnz .noleap
xor edx, edx
push eax
div [_400]
pop eax
test edx, edx
jz .leap
xor edx, edx
div [_100]
test edx, edx
jz .noleap
.leap:
mov esi, months2
.noleap:
pop edx
xor eax, eax
inc ecx
inc eax
@@:
sub edx, [esi]
jb @f
add esi, 4
inc eax
jmp @b
@@:
add edx, [esi]
pop esi
sub dl, [ecx]
jnc @b
dec dh
jns @b
add dl, [ecx]
inc edx
mov [edi+4], dl
mov [edi+5], al
mov [edi+6], bx
add edi, 8
pop ecx ebx
ret
 
.sec:
push ebx ecx
mov ebx, edx
jmp .forEXT
 
;----------------------------------------------------------------
ntfs_CreateFolder:
mov [ebp+NTFS.bFolder], 1
2015,6 → 1937,7
xor ebx, ebx
movi eax, ERROR_ACCESS_DENIED
ret
 
@@: ; 1. Search file
call ntfs_lock
stdcall ntfs_find_lfn, [esp+4]
2088,16 → 2011,17
cmp byte [ecx], 0
jnz @b
sub ecx, esi
push ecx
lea ecx, [ecx*2+52h+7] ; precalculate index length
and ecx, not 7 ; align 8
push ecx ; name length
shl ecx, 1
add ecx, fileName+7
and ecx, not 7
mov edi, [ebp+NTFS.cur_index_buf]
push esi
push ecx
mov edx, [ebx+12]
mov [ebp+NTFS.fileRealSize], edx
mov edx, [ebx+16]
mov [ebp+NTFS.fileDataBuffer], edx
push esi
push ecx ; index length
mov edx, ecx
cmp dword [edi], 'INDX'
jz .indexRecord
2142,7 → 2066,7
mov cl, [esi+attributeOffset]
add esi, ecx
mov eax, [esi+indexRecordSizeClus]
cmp eax, 128
cmp eax, 129
jnc @b
mov [ebp+NTFS.fileDataSize], eax
mov eax, [esi+indexRecordSize]
2328,7 → 2252,7
pop ecx
mov [ebp+NTFS.indexOffset], edi
mov [edi+fileNameLength], cl
add edi, 52h
add edi, fileName
@@: ; record filename
lodsb
call ansi2uni_char