102,10 → 102,8 |
mftmirr_cluster dd ? ; location |
frs_size dd ? ; in bytes |
frs_buffer dd ? ; MFT fileRecord buffer |
mft_retrieval dd ? |
mft_retrieval_size dd ? |
mft_retrieval_alloc dd ? |
mft_retrieval_end dd ? |
mftSize dd ? ; in sectors |
cur_index_size dd ? ; in sectors |
cur_index_buf dd ? ; index node buffer |
secondIndexBuffer dd ? |
118,6 → 116,11 |
mftBitmapSize dd ? ; bytes readen |
mftBitmapLocation dd ? ; starting sector |
|
attr_size dq ? |
attr_offs dd ? |
attr_list dd ? |
attr_iRecord dd ? |
attr_iBaseRecord dd ? |
cur_attr dd ? ; attribute type |
cur_iRecord dd ? ; number of fileRecord in MFT |
cur_offs dd ? ; attribute VCN in sectors |
124,33 → 127,28 |
cur_size dd ? ; max sectors to read |
cur_buf dd ? |
cur_read dd ? ; bytes readen |
cur_tail dd ? |
cur_subnode_size dd ? |
LastRead dd ? ; last readen block of sectors |
rootLastRead dd ? |
nodeLastRead dd ? |
indexRoot dd ? |
pointingIndex dd ? |
indexPointer dd ? |
newRecord dd ? |
fileDataStart dd ? ; starting cluster |
fileDataSize dd ? ; in clusters |
fileDataBuffer dd ? |
fileRealSize dd ? ; in bytes |
indexOffset dd ? |
fragmentCount db ? |
bCanContinue db ? |
bFolder db ? |
bWriteAttr db ? ; Warning: Don't forget to turn off!!! |
|
cur_subnode_size dd ? |
attr_iRecord dd ? |
attr_iBaseRecord dd ? |
attr_offs dd ? |
attr_list dd ? |
attr_size dq ? |
cur_tail dd ? |
|
attrlist_buf rb 0x400 |
attrlist_mft_buf rb 0x400 |
bitmap_buf rb 0x400 |
align 256 |
mft_retrieval rb 768 |
attrlist_buf rb 1024 |
attrlist_mft_buf rb 1024 |
bitmap_buf rb 1024 |
ends |
|
; NTFS external functions |
286,10 → 284,8 |
xor eax, eax |
jmp .exit |
|
; By given bootsector, initialize some NTFS variables |
.ntfs_setup: |
movi eax, sizeof.NTFS |
call malloc |
.ntfs_setup: ; By given bootsector, initialize some NTFS variables |
stdcall kernel_alloc, 1000h |
test eax, eax |
jz .exit |
mov ecx, dword [ebp+PARTITION.FirstSector] |
335,7 → 331,10 |
; read $MFT disposition |
mov eax, [ebp+NTFS.mft_cluster] |
mul [ebp+NTFS.sectors_per_cluster] |
call ntfs_read_frs_sector |
mov ecx, [ebp+NTFS.frs_size] |
shr ecx, 9 |
mov ebx, [ebp+NTFS.frs_buffer] |
call fs_read64_sys |
test eax, eax |
jnz .usemirr |
cmp dword [ebx], 'FILE' |
345,7 → 344,10 |
.usemirr: |
mov eax, [ebp+NTFS.mftmirr_cluster] |
mul [ebp+NTFS.sectors_per_cluster] |
call ntfs_read_frs_sector |
mov ecx, [ebp+NTFS.frs_size] |
shr ecx, 9 |
mov ebx, [ebp+NTFS.frs_buffer] |
call fs_read64_sys |
test eax, eax |
jnz .fail_free_frs |
cmp dword [ebx], 'FILE' |
352,59 → 354,55 |
jnz .fail_free_frs |
call ntfs_restore_usa_frs |
jc .fail_free_frs |
.mftok: |
; read $MFT table retrieval information |
; start with one page, increase if not enough (when MFT too fragmented) |
push ebx |
stdcall kernel_alloc, 0x1000 |
pop ebx |
test eax, eax |
jz .fail_free_frs |
mov [ebp+NTFS.mft_retrieval], eax |
and [ebp+NTFS.mft_retrieval_size], 0 |
mov [ebp+NTFS.mft_retrieval_alloc], 0x1000/8 |
; $MFT base record must contain unnamed non-resident $DATA attribute |
movzx eax, word [ebx+14h] |
.mftok: ; prepare $MFT retrieval information |
; search for unnamed non-resident $DATA attribute |
movzx eax, word [ebx+attributeOffset] |
add eax, ebx |
.scandata: |
cmp dword [eax], -1 |
jz .fail_free_mft |
jz .fail_free_frs |
cmp dword [eax], 0x80 |
jnz @f |
cmp byte [eax+9], 0 |
cmp byte [eax+nameLength], 0 |
jz .founddata |
@@: |
add eax, [eax+4] |
add eax, [eax+sizeWithHeader] |
jmp .scandata |
|
.founddata: |
cmp byte [eax+8], 0 |
jz .fail_free_mft |
; load first portion of $DATA attribute retrieval information |
mov edx, [eax+0x18] |
mov [ebp+NTFS.mft_retrieval_end], edx |
mov esi, eax |
movzx eax, word [eax+0x20] |
cmp byte [eax+nonResidentFlag], 0 |
jz .fail_free_frs |
movzx esi, word [eax+dataRunsOffset] |
add esi, eax |
mov edx, [eax+attributeAllocatedSize+4] |
mov eax, [eax+attributeAllocatedSize] |
shrd eax, edx, 9 |
mov [ebp+NTFS.mftSize], eax |
sub esp, 10h |
.scanmcb: |
lea ecx, [ebp+NTFS.mft_retrieval] |
xor edx, edx |
.scanmcb: ; load descriptions of fragments |
call ntfs_decode_mcb_entry |
jnc .scanmcbend |
call .get_mft_retrieval_ptr |
mov edx, [esp] ; block length |
mov [eax], edx |
mov edx, [esp+8] ; block addr (relative) |
mov [eax+4], edx |
inc [ebp+NTFS.mft_retrieval_size] |
mov eax, [esp] ; block length |
mov [ecx], eax |
add edx, [esp+8] ; block addr |
mov [ecx+4], edx |
add ecx, 8 |
jmp .scanmcb |
|
.scanmcbend: |
add esp, 10h |
; there may be other portions of $DATA attribute in auxiliary records; |
; if they will be needed, they will be loaded later |
lea eax, [ebp+NTFS.attrlist_buf] |
cmp eax, ecx |
jc @f |
mov eax, ecx |
@@: |
mov [ebp+NTFS.mft_retrieval_end], eax |
; allocate index buffers |
stdcall kernel_alloc, 2000h |
test eax, eax |
jz .fail_free_mft |
jz .fail_free_frs |
mov [ebp+NTFS.cur_index_buf], eax |
add eax, 1000h |
mov [ebp+NTFS.secondIndexBuffer], eax |
485,66 → 483,38 |
ret |
|
.failFreeBitmapMFT: |
stdcall kernel_free, [ebx+NTFS.mftBitmapBuffer] |
stdcall kernel_free, [ebp+NTFS.mftBitmapBuffer] |
.failFreeBitmap: |
stdcall kernel_free, [ebx+NTFS.BitmapBuffer] |
stdcall kernel_free, [ebp+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] |
mov eax, [ebp+NTFS.cur_index_buf] |
cmp eax, [ebp+NTFS.secondIndexBuffer] |
jc @f |
mov eax, [ebp+NTFS.secondIndexBuffer] |
@@: |
stdcall kernel_free, eax |
.fail_free_frs: |
stdcall kernel_free, [ebp+NTFS.frs_buffer] |
.fail_free: |
mov eax, ebp |
call free |
stdcall kernel_free, ebp |
xor eax, eax |
jmp .pop_exit |
|
.get_mft_retrieval_ptr: |
pushad |
mov eax, [ebp+NTFS.mft_retrieval_size] |
cmp eax, [ebp+NTFS.mft_retrieval_alloc] |
jnz .ok |
add eax, 0x1000/8 |
mov [ebp+NTFS.mft_retrieval_alloc], eax |
shl eax, 3 |
stdcall kernel_alloc, eax |
test eax, eax |
jnz @f |
popad |
add esp, 14h |
jmp .fail_free_mft |
|
@@: |
mov esi, [ebp+NTFS.mft_retrieval] |
mov edi, eax |
mov ecx, [ebp+NTFS.mft_retrieval_size] |
add ecx, ecx |
rep movsd |
push [ebp+NTFS.mft_retrieval] |
mov [ebp+NTFS.mft_retrieval], eax |
call kernel_free |
mov eax, [ebp+NTFS.mft_retrieval_size] |
.ok: |
shl eax, 3 |
add eax, [ebp+NTFS.mft_retrieval] |
mov [esp+28], eax |
popad |
ret |
|
ntfs_free: |
push ebx |
mov ebx, eax |
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 |
mov eax, [ebx+NTFS.cur_index_buf] |
cmp eax, [ebx+NTFS.secondIndexBuffer] |
jc @f |
mov eax, [ebx+NTFS.secondIndexBuffer] |
@@: |
stdcall kernel_free, eax |
stdcall kernel_free, ebx |
pop ebx |
jmp free |
ret |
|
ntfs_lock: |
lea ecx, [ebp+NTFS.Lock] |
554,29 → 524,6 |
lea ecx, [ebp+NTFS.Lock] |
jmp mutex_unlock |
|
ntfs_read_frs_sector: |
push ecx |
mov ebx, [ebp+NTFS.frs_buffer] |
push ebx |
mov ecx, [ebp+NTFS.frs_size] |
shr ecx, 9 |
push ecx |
mov ecx, eax |
@@: |
mov eax, ecx |
call fs_read32_sys |
test eax, eax |
jnz .fail |
add ebx, 0x200 |
inc ecx |
dec dword [esp] |
jnz @b |
pop eax |
.fail: |
pop ebx |
pop ecx |
ret |
|
ntfs_read_attr: |
; [ebp+NTFS.bWriteAttr]=1 -> write attribute |
; in: |
595,79 → 542,48 |
jnz .nomft |
cmp [ebp+NTFS.cur_attr], 0x80 |
jnz .nomft |
mov eax, [ebp+NTFS.mft_retrieval_end] |
inc eax |
mul [ebp+NTFS.sectors_per_cluster] |
cmp eax, [ebp+NTFS.cur_offs] |
jbe .nomft |
; precalculated part of $Mft $DATA |
mov esi, [ebp+NTFS.mft_retrieval] |
mov eax, [ebp+NTFS.cur_offs] |
xor edx, edx |
div [ebp+NTFS.sectors_per_cluster] |
; eax = VCN, edx = offset in sectors from beginning of cluster |
xor ecx, ecx ; ecx will contain LCN |
mov ebx, edx |
; eax = VCN, ebx = offset in sectors from beginning of cluster |
lea esi, [ebp+NTFS.mft_retrieval] |
sub esi, 8 |
.mftscan: |
add ecx, [esi+4] |
add esi, 8 |
cmp esi, [ebp+NTFS.mft_retrieval_end] |
jz .nomft |
mov ecx, [esi+4] |
sub eax, [esi] |
jb @f |
add esi, 8 |
push eax |
mov eax, [ebp+NTFS.mft_retrieval_end] |
shl eax, 3 |
add eax, [ebp+NTFS.mft_retrieval] |
cmp eax, esi |
pop eax |
jnz .mftscan |
jmp .nomft |
|
@@: |
push ecx |
jnc .mftscan |
add ecx, eax |
add ecx, [esi] |
push eax |
push edx |
mov eax, [ebp+NTFS.sectors_per_cluster] |
mul ecx |
; eax = sector on partition |
pop edx |
add eax, edx |
neg eax |
mul [ebp+NTFS.sectors_per_cluster] |
xchg eax, ecx |
mul [ebp+NTFS.sectors_per_cluster] |
sub ecx, ebx |
add eax, ebx |
mov ebx, [ebp+NTFS.cur_buf] |
pop ecx |
neg ecx |
imul ecx, [ebp+NTFS.sectors_per_cluster] |
sub ecx, edx |
mov [ebp+NTFS.LastRead], eax |
cmp ecx, [ebp+NTFS.cur_size] |
jb @f |
mov ecx, [ebp+NTFS.cur_size] |
@@: |
; ecx = number of sequential sectors to read |
push eax |
call fs_read32_sys |
pop edx |
mov [ebp+NTFS.LastRead], eax |
mov edi, ecx |
call fs_read64_sys |
test eax, eax |
jnz .errread |
add [ebp+NTFS.cur_read], 0x200 |
dec [ebp+NTFS.cur_size] |
inc [ebp+NTFS.cur_offs] |
add ebx, 0x200 |
mov [ebp+NTFS.cur_buf], ebx |
lea eax, [edx+1] |
loop @b |
pop ecx |
jnz .errret |
sub [ebp+NTFS.cur_size], edi |
add [ebp+NTFS.cur_offs], edi |
shl edi, 9 |
add [ebp+NTFS.cur_read], edi |
add [ebp+NTFS.cur_buf], edi |
xor eax, eax |
xor edx, edx |
xor ebx, ebx |
cmp [ebp+NTFS.cur_size], eax |
jz @f |
add esi, 8 |
push eax |
mov eax, [ebp+NTFS.mft_retrieval_end] |
shl eax, 3 |
add eax, [ebp+NTFS.mft_retrieval] |
cmp eax, esi |
pop eax |
jz .nomft |
jmp .mftscan |
|
.errret2_pop: |
674,7 → 590,6 |
xor eax, eax |
.errret_pop: |
pop ecx |
.errread: |
pop ecx |
.errret: |
mov [esp+28], eax |
769,7 → 684,6 |
mov ecx, [ebp+NTFS.attr_list] |
test ecx, ecx |
jnz .lookattr |
.ret_is_attr: |
and dword [esp+28], 0 |
cmp [ebp+NTFS.attr_offs], 1 ; define CF |
.ret: |
1024,14 → 938,13 |
and eax, 0x1FF |
mov [ebp+NTFS.cur_tail], eax |
@@: |
cmp [ebp+NTFS.cur_size], 0 |
jz .okret |
mov eax, [ebp+NTFS.cur_offs] |
xor edx, edx |
div [ebp+NTFS.sectors_per_cluster] |
sub eax, [ecx+firstVCN] |
jb .okret |
; eax = cluster, edx = starting sector |
mov ebx, edx |
; eax = starting cluster, ebx = sector in the cluster |
cmp [ebp+NTFS.cur_attr], 0x80 |
jnz .sys |
cmp [ebp+NTFS.cur_iRecord], 0 |
1056,25 → 969,23 |
add edi, [esp+8] |
sub eax, [esp] |
jae .readloop |
push ecx |
push eax |
add eax, [esp+8] |
add eax, edi |
imul eax, [ebp+NTFS.sectors_per_cluster] |
add eax, edx |
pop ecx |
neg ecx |
imul ecx, [ebp+NTFS.sectors_per_cluster] |
sub ecx, edx |
mov ecx, edi |
add ecx, eax |
add ecx, [esp] |
neg eax |
mul [ebp+NTFS.sectors_per_cluster] |
xchg eax, ecx |
mul [ebp+NTFS.sectors_per_cluster] |
sub ecx, ebx |
add eax, ebx |
mov ebx, [ebp+NTFS.cur_buf] |
cmp ecx, [ebp+NTFS.cur_size] |
jb @f |
mov ecx, [ebp+NTFS.cur_size] |
@@: |
mov ebx, [ebp+NTFS.cur_buf] |
mov [ebp+NTFS.LastRead], eax |
push ecx |
xor edx, edx |
call dword[esp+18h] |
call dword[esp+14h] |
pop ecx |
test eax, eax |
jnz .errread2 |
1084,9 → 995,8 |
add [ebp+NTFS.cur_read], ecx |
add [ebp+NTFS.cur_buf], ecx |
inc [ebp+NTFS.fragmentCount] |
pop ecx |
xor eax, eax |
xor edx, edx |
xor ebx, ebx |
cmp [ebp+NTFS.cur_size], 0 |
jnz .readloop |
add esp, 14h |
1100,7 → 1010,6 |
ret |
|
.errread2: |
pop ecx |
add esp, 14h |
stc |
ret |
1270,8 → 1179,13 |
ntfs_find_lfn: |
; in: [esi]+[esp+4] = name |
; out: |
; [ebp+NTFS.cur_iRecord] = number of MFT fileRecord |
; eax -> index in the parent index node |
; [ebp+NTFS.cur_iRecord] = target fileRecord |
; eax -> index in the target node |
; [ebp+NTFS.indexPointer] -> index, that points the target subnode |
; [ebp+NTFS.indexRoot] -> attribute |
; [ebp+NTFS.cur_size] = index record size in sectors |
; [ebp+NTFS.cur_subnode_size] = index record size in clusters or sectors |
; [ebp+NTFS.rootLastRead] = directory fileRecord sector |
; CF=1 -> file not found, eax=0 -> error |
mov [ebp+NTFS.cur_iRecord], 5 ; start from root directory |
.doit2: |
1344,14 → 1258,16 |
stdcall kernel_alloc, eax |
test eax, eax |
jz .err |
push [ebp+NTFS.secondIndexBuffer] |
push [ebp+NTFS.cur_index_buf] |
mov edx, [ebp+NTFS.cur_index_buf] |
cmp edx, [ebp+NTFS.secondIndexBuffer] |
jc @f |
mov edx, [ebp+NTFS.secondIndexBuffer] |
@@: |
mov [ebp+NTFS.cur_index_buf], eax |
add eax, [esi+indexRecordSize] |
mov [ebp+NTFS.secondIndexBuffer], eax |
mov [ebp+NTFS.cur_index_size], edi |
call kernel_free |
call kernel_free |
stdcall kernel_free, edx |
popad |
jmp .doit2 |
|
1378,7 → 1294,7 |
jz @f |
mul [ebp+NTFS.sectors_per_cluster] |
@@: |
mov [ebp+NTFS.pointingIndex], esi |
mov [ebp+NTFS.indexPointer], esi |
mov esi, [ebp+NTFS.cur_index_buf] |
xchg [ebp+NTFS.secondIndexBuffer], esi |
mov [ebp+NTFS.cur_index_buf], esi |
1645,14 → 1561,16 |
stdcall kernel_alloc, eax |
test eax, eax |
jz .err |
push [ebp+NTFS.secondIndexBuffer] |
push [ebp+NTFS.cur_index_buf] |
mov edx, [ebp+NTFS.cur_index_buf] |
cmp edx, [ebp+NTFS.secondIndexBuffer] |
jc @f |
mov edx, [ebp+NTFS.secondIndexBuffer] |
@@: |
mov [ebp+NTFS.cur_index_buf], eax |
add eax, [esi+indexRecordSize] |
mov [ebp+NTFS.secondIndexBuffer], eax |
mov [ebp+NTFS.cur_index_size], edi |
call kernel_free |
call kernel_free |
stdcall kernel_free, edx |
popad |
jmp .doit |
|
2283,7 → 2201,7 |
add ecx, edi |
add [ecx+rootNode+nodeRealSize], eax |
add [ecx+rootNode+nodeAllocatedSize], eax |
add ecx, [ebp+NTFS.pointingIndex] |
add ecx, [ebp+NTFS.indexPointer] |
sub ecx, [ebp+NTFS.secondIndexBuffer] |
mov edi, esi |
sub esi, eax |
2427,7 → 2345,7 |
mul ecx |
mov [edi+fileAllocatedSize], eax |
pop ecx |
mov [ebp+NTFS.indexOffset], edi |
mov [ebp+NTFS.indexPointer], edi |
mov [edi+fileNameLength], cl |
add edi, fileName |
@@: ; record filename |
2440,7 → 2358,7 |
mov [ebp+NTFS.nodeLastRead], eax |
cmp [ebp+NTFS.bFolder], 0 |
jz @f |
mov edi, [ebp+NTFS.indexOffset] |
mov edi, [ebp+NTFS.indexPointer] |
bts dword [edi+fileFlags], 28 |
jmp .mftBitmap |
|
2484,22 → 2402,25 |
mov [ebp+NTFS.cur_iRecord], 0 |
mov [ebp+NTFS.cur_attr], 0x80 |
mov [ebp+NTFS.cur_offs], eax |
mov [ebp+NTFS.cur_size], 1 |
push eax |
mov [ebp+NTFS.cur_size], 0 |
mov eax, [ebp+NTFS.frs_buffer] |
mov [ebp+NTFS.cur_buf], eax |
call ntfs_read_attr |
cmp [ebp+NTFS.cur_read], 0 |
jz .extendMFT |
pop eax |
jc ntfsFail |
cmp eax, [ebp+NTFS.mftSize] |
jnc .extendMFT |
jmp .mftRecord |
|
.extendBitmapMFT: |
mov eax, [ebp+NTFS.sectors_per_cluster] |
mov [ebp+NTFS.cur_offs], eax |
shl eax, 9 |
cmp [ebp+NTFS.mftBitmapSize], eax |
jnc ntfsUnsupported |
mov [ebp+NTFS.cur_iRecord], 0 |
mov [ebp+NTFS.cur_attr], 0xB0 |
mov [ebp+NTFS.cur_offs], 0 |
mov [ebp+NTFS.cur_size], 0 |
call ntfs_read_attr |
jc ntfsFail |
2520,6 → 2441,7 |
mov dword [edi], 1 |
mov dword [edi+4], 0 |
mov [ebp+NTFS.cur_attr], 0x80 |
mov [ebp+NTFS.cur_offs], 0 |
call ntfs_read_attr.newAttribute |
jc ntfsFail |
mov [ebp+NTFS.mftBitmapSize], ecx |
2547,6 → 2469,27 |
movzx ecx, word [ebx+updateSequenceSize] |
dec ecx |
call fs_write64_sys ; $MFTMirr |
; update $MFT retrieval information |
mov edi, [ebp+NTFS.mft_retrieval_end] |
mov eax, [edi-4] |
add eax, [edi-8] |
mov edx, [ebp+NTFS.fileDataSize] |
cmp eax, [ebp+NTFS.fileDataStart] |
jnz .newFragment |
add [edi-8], edx |
jmp @f |
.newFragment: |
lea eax, [ebp+NTFS.attrlist_buf] |
cmp eax, edi |
jz @f |
mov [edi], edx |
mov eax, [ebp+NTFS.fileDataStart] |
mov [edi+4], eax |
add [ebp+NTFS.mft_retrieval_end], 8 |
@@: |
mov eax, [ebp+NTFS.fileDataSize] |
mul [ebp+NTFS.sectors_per_cluster] |
add [ebp+NTFS.mftSize], eax |
call ntfsSpaceClean |
pop [ebp+NTFS.fileDataSize] |
pop [ebp+NTFS.fileDataStart] |
2581,7 → 2524,7 |
mov byte [edi+attributeOffset], 18h |
add edi, 48h |
; $FileName |
mov esi, [ebp+NTFS.indexOffset] |
mov esi, [ebp+NTFS.indexPointer] |
mov byte [edi+attributeType], 30h |
mov byte [edi+attributeID], 1 |
mov byte [edi+attributeOffset], 18h |
2605,7 → 2548,7 |
mov eax, [ebp+NTFS.fileDataSize] |
test eax, eax |
jz .resident |
mov esi, [ebp+NTFS.indexOffset] |
mov esi, [ebp+NTFS.indexPointer] |
dec eax |
mov [edi+lastVCN], eax |
mov byte [edi+nonResidentFlag], 1 |
2689,7 → 2632,7 |
mov ecx, 1 |
xor edx, edx |
call fs_write64_sys |
mov edi, [ebp+NTFS.indexOffset] |
mov edi, [ebp+NTFS.indexPointer] |
mov eax, [ebp+NTFS.newRecord] |
mov [edi+fileRecordReference], eax |
; 5. Write directory node |
3901,6 → 3844,7 |
stdcall kernel_alloc, ecx |
pop ecx |
pop edi |
mov esi, eax |
sub ecx, edi |
add edi, eax |
mov [ebp+NTFS.cur_buf], eax |
3911,7 → 3855,7 |
rep stosb |
push ebx |
mov eax, [ebp+NTFS.LastRead] |
mov ebx, [ebp+NTFS.cur_buf] |
mov ebx, esi |
mov ecx, [ebp+NTFS.sectors_per_cluster] |
xor edx, edx |
call fs_write64_app |
3918,7 → 3862,7 |
pop ebx |
@@: |
pop [ebp+NTFS.LastRead] |
stdcall kernel_free, [ebp+NTFS.cur_buf] |
stdcall kernel_free, esi |
.aligned: |
mov eax, [ebx+4] |
mov edx, [ebx+8] |