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