Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 6311 → Rev 6310

/kernel/branches/Kolibri-acpi/kernel.asm
1100,6 → 1100,9
 
first_app_found:
 
mov ecx, bios_fb
call set_framebuffer
 
; START MULTITASKING
 
; A 'All set - press ESC to start' messages if need
1629,13 → 1632,9
add eax, [edi+SLOT_BASE+APPDATA.wnd_clientbox.top]
add ebx, eax
mov ecx, [esp+64+32-12+4]
and ecx, not 0x80000000 ; force counted string
mov eax, [esp+64+8] ; background color (if given)
mov edi, [esp+64+4]
and ecx, 5FFFFFFFh
bt ecx, 27
jnc @f
mov edi, eax
@@:
jmp dtext
;-----------------------------------------------------------------------------
iglobal
/kernel/branches/Kolibri-acpi/video/framebuffer.inc
127,9 → 127,8
jnc .create_page_tables
 
mov edx, 0x00400000
or esi, PG_GLOBAL+PAT_WC+PG_UWR
or esi, PG_GLOBAL+PDE_LARGE+PAT_WC+PG_UWR
and esi, [pte_valid_mask]
or esi, PDE_LARGE
mov [ebp+FRB.pde], esi
add esi, edx
mov [ebp+FRB.pde+4], esi
189,8 → 188,6
lea edx, [eax+PG_UWR]
mov [ebp+FRB.pde], edx
 
stdcall map_page, edi, eax, PG_SWR
 
; max VGA=640*480*4=1228800 bytes
; + 32*640*4=81920 bytes for mouse pointer
stdcall alloc_pages, ((1228800+81920)/4096)
/kernel/branches/Kolibri-acpi/data32.inc
173,6 → 173,7
vmode db '/sys/drivers/VMODE.MDR',0
;vrr_m db 'VRR_M',0
kernel_file_load:
 
; load kernel.mnt to _CLEAN_ZONE
dd 0 ; subfunction
dq 0 ; offset in file
/kernel/branches/Kolibri-acpi/docs/sysfuncr.txt
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2016. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2104,16 → 2104,12
* бит 31 установлен = не выводить ведущие нули числа
* ecx = число (при bl=0) или указатель (при bl=1)
* edx = [координата по оси x]*65536 + [координата по оси y]
* esi = 0xXXRRGGBB, где
* RR, GG, BB задают цвет текста
* XX=0B0FCSSS (биты):
* B=1 - закрашивать фон (цвет = edi)
* F задает шрифт:
0 = 6x9
1 = 8x16
* C=0 - рисовать в окно,
С=1 - рисовать в буфер (edi)
* SSS = (множитель размера)-1, то-есть 0 = x1, 7 = x8
* esi = 0xX0RRGGBB:
* RR, GG, BB задают цвет
* X = ABnn (биты)
* nn = шрифт (0/1)
* A игнорируется
* B=1 - закрашивать фон цветом edi
Возвращаемое значение:
* функция не возвращает значения
Замечания:
2122,6 → 2118,7
может быть записано меньшим количеством цифр, оно дополняется
ведущими нулями; если число велико и не может быть записано
таким количеством цифр, "лишние" ведущие цифры обрезаются.
* Параметры шрифтов указаны в описании функции 4 (вывода текста).
 
---------------------- Константы для регистров: ----------------------
eax - SF_DRAW_NUMBER (47)
/kernel/branches/Kolibri-acpi/docs/sysfuncs.txt
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2016. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2081,16 → 2081,12
* bit 31 set = do not display leading zeroes of the number
* ecx = number (if bl=0) or pointer (if bl=1)
* edx = [coordinate on axis x]*65536 + [coordinate on axis y]
* esi = 0xXXRRGGBB, where
* RR, GG, BB specify text color
* XX = 0B0FCSSS (bits):
* B=1 - fill background (color = edi)
* F specifies the font:
0 = 6x9
1 = 8x16
* C=0 - draw to the window,
C=1 - draw to the user buffer (edi)
* SSS = (size multiplier)-1, so 0 = x1, 7 = x8
* esi = 0xX0RRGGBB:
* RR, GG, BB specify the color
* X = ABnn (bits)
* nn = font (0/1)
* A is ignored
* B=1 - fill background with the color edi
Returned value:
* function does not return value
Remarks:
2099,6 → 2095,8
and can be written by smaller amount of digits, it is supplemented
by leading zeroes; if the number is big and can not be written by
given amount of digits, extra digits are not drawn.
* Parameters of fonts are shown in the description of function 4
(text output).
 
---------------------- Constants for registers: ----------------------
eax - SF_DRAW_NUMBER (47)
/kernel/branches/Kolibri-acpi/fs/ntfs.inc
29,10 → 29,8
 
; Offsets:
; record header
magic = 0
updateSequenceOffset = 4
updateSequenceSize = 6
; FileRecord header
reuseCounter = 16
hardLinkCounter = 12h
attributeOffset = 14h
52,7 → 50,7
attributeID = 14
; resident attribute header
sizeWithoutHeader = 10h
attributeOffset = 14h
; attributeOffset = 14h
indexedFlag = 16h
; non resident attribute header
firstVCN = 10h
62,19 → 60,13
attributeRealSize = 30h
initialDataSize = 38h
; $IndexRoot
indexedAttributesType = 0
collationRule = 4
indexRecordSize = 8
indexRecordSizeClus = 12
rootNode = 16
; IndexRecord header
recordVCN = 16
recordNode = 18h
; node header
indexOffset = 0
nodeRealSize = 4
nodeAllocatedSize = 8
nonLeafFlag = 12
; $Filename index
fileRecordReference = 0
fileReferenceReuse = 6
83,16 → 75,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
117,36 → 103,35
mftBitmapSize dd ? ; bytes readen
mftBitmapLocation dd ? ; starting sector
 
cur_attr dd ? ; attribute type
cur_iRecord dd ? ; number of fileRecord in MFT
cur_offs dd ? ; attribute VCN in sectors
cur_size dd ? ; max sectors to read
cur_buf dd ?
cur_read dd ? ; bytes readen
LastRead dd ? ; last readen block of sectors
ntfs_cur_attr dd ? ; attribute type
ntfs_cur_iRecord dd ? ; number of fileRecord in MFT
ntfs_cur_offs dd ? ; attribute VCN in sectors
ntfs_cur_size dd ? ; max sectors to read
ntfs_cur_buf dd ?
ntfs_cur_read dd ? ; bytes readen
ntfsLastRead dd ? ; last readen block of sectors
newMftRecord dd ? ; number of fileRecord in MFT
fileDataStart dd ? ; starting cluster
fileDataSize dd ? ; in clusters
fileDataBuffer dd ?
fileRealSize dd ? ; in bytes
indexOffset dd ?
nodeLastRead dd ?
fragmentCount db ?
bCanContinue db ?
bFolder db ?
bWriteAttr db ? ; Warning: Don't forget to turn off!!!
ntfs_bCanContinue db ?
ntfsFolder db ?
ntfsWriteAttr db ? ; Warning: Don't forget to turn off!!!
ntfsFragmentCount db ?
 
cur_subnode_size dd ?
attr_iRecord dd ?
attr_iBaseRecord dd ?
attr_offs dd ?
attr_list dd ?
attr_size dq ?
cur_tail dd ?
ntfs_attr_iRecord dd ?
ntfs_attr_iBaseRecord dd ?
ntfs_attr_offs dd ?
ntfs_attr_list dd ?
ntfs_attr_size dq ?
ntfs_cur_tail dd ?
 
attrlist_buf rb 0x400
attrlist_mft_buf rb 0x400
bitmap_buf rb 0x400
ntfs_attrlist_buf rb 0x400
ntfs_attrlist_mft_buf rb 0x400
ntfs_bitmap_buf rb 0x400
ends
 
; NTFS external functions
281,7 → 266,6
.nope:
xor eax, eax
jmp .exit
 
; By given bootsector, initialize some NTFS variables
.ntfs_setup:
movi eax, sizeof.NTFS
295,7 → 279,7
mov ecx, [ebp+PARTITION.Disk]
mov [eax+NTFS.Disk], ecx
mov [eax+NTFS.FSUserFunctions], ntfs_user_functions
mov [eax+NTFS.bWriteAttr], 0
mov [eax+NTFS.ntfsWriteAttr], 0
 
push ebx ebp esi
mov ebp, eax
316,7 → 300,6
mul [ebp+NTFS.sectors_per_cluster]
shl eax, 9
jmp .1
 
@@:
neg eax
mov ecx, eax
372,7 → 355,6
@@:
add eax, [eax+4]
jmp .scandata
 
.founddata:
cmp byte [eax+8], 0
jz .fail_free_mft
393,7 → 375,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;
416,7 → 397,7
test eax, eax
jz .failFreeIndex
mov [ebp+NTFS.BitmapBuffer], eax
mov [ebp+NTFS.cur_buf], eax
mov [ebp+NTFS.ntfs_cur_buf], eax
mov eax, [ebp+NTFS.BitmapTotalSize]
add eax, [ebp+NTFS.mft_cluster]
shr eax, 3+2 ; reserve 1/8 of partition for $MFT
428,7 → 409,7
push eax
push eax
shl eax, 3
mov [ebp+NTFS.cur_size], eax
mov [ebp+NTFS.ntfs_cur_size], eax
call alloc_pages
test eax, eax
pop ecx
436,36 → 417,36
add eax, 3
mov ebx, [ebp+NTFS.BitmapBuffer]
call commit_pages
mov [ebp+NTFS.cur_iRecord], 6
mov [ebp+NTFS.cur_attr], 0x80
mov [ebp+NTFS.cur_offs], 0
mov [ebp+NTFS.ntfs_cur_iRecord], 6
mov [ebp+NTFS.ntfs_cur_attr], 0x80
mov [ebp+NTFS.ntfs_cur_offs], 0
call ntfs_read_attr
jc .failFreeBitmap
mov eax, [ebp+NTFS.cur_read]
mov eax, [ebp+NTFS.ntfs_cur_read]
mov [ebp+NTFS.BitmapSize], eax
mov eax, [ebp+NTFS.LastRead]
mov eax, [ebp+NTFS.ntfsLastRead]
mov [ebp+NTFS.BitmapLocation], eax
; read MFT $BITMAP attribute
mov eax, [ebp+NTFS.sectors_per_cluster]
mov [ebp+NTFS.cur_size], eax
mov [ebp+NTFS.ntfs_cur_size], eax
shl eax, 9
stdcall kernel_alloc, eax
test eax, eax
jz .failFreeBitmap
mov [ebp+NTFS.mftBitmapBuffer], eax
mov [ebp+NTFS.cur_buf], eax
mov [ebp+NTFS.cur_iRecord], 0
mov [ebp+NTFS.cur_attr], 0xB0
mov [ebp+NTFS.cur_offs], 0
mov [ebp+NTFS.ntfs_cur_buf], eax
mov [ebp+NTFS.ntfs_cur_iRecord], 0
mov [ebp+NTFS.ntfs_cur_attr], 0xB0
mov [ebp+NTFS.ntfs_cur_offs], 0
call ntfs_read_attr
mov eax, [ebp+NTFS.cur_read]
mov eax, [ebp+NTFS.ntfs_cur_read]
cmp eax, 4
jc .failFreeBitmapMFT
mov ecx, [ebp+NTFS.attr_offs]
mov ecx, [ebp+NTFS.ntfs_attr_offs]
cmp byte [ecx+nonResidentFlag], 1
jnz .failFreeBitmapMFT
mov [ebp+NTFS.mftBitmapSize], eax
mov eax, [ebp+NTFS.LastRead]
mov eax, [ebp+NTFS.ntfsLastRead]
mov [ebp+NTFS.mftBitmapLocation], eax
 
mov eax, ebp
508,7 → 489,6
popad
add esp, 14h
jmp .fail_free_mft
 
@@:
mov esi, [ebp+NTFS.mft_retrieval]
mov edi, eax
570,31 → 550,31
ret
 
ntfs_read_attr:
; [ebp+NTFS.bWriteAttr]=1 -> write attribute
; [ebp+NTFS.ntfsWriteAttr]=1 -> write attribute
; in:
; [ebp+NTFS.cur_iRecord] = number of fileRecord
; [ebp+NTFS.cur_attr] = attribute type
; [ebp+NTFS.cur_offs] = attribute VCN in sectors
; [ebp+NTFS.cur_buf] -> buffer for data
; [ebp+NTFS.cur_size] = max sectors to read
; [ebp+NTFS.ntfs_cur_iRecord] = number of fileRecord
; [ebp+NTFS.ntfs_cur_attr] = attribute type
; [ebp+NTFS.ntfs_cur_offs] = attribute VCN in sectors
; [ebp+NTFS.ntfs_cur_buf] -> buffer for data
; [ebp+NTFS.ntfs_cur_size] = max sectors to read
; out:
; [ebp+NTFS.cur_read] = bytes readen
; [ebp+NTFS.ntfs_cur_read] = bytes readen
; CF=1 -> failed, eax = disk error code, eax=0 -> something with FS
xor eax, eax
pushad
and [ebp+NTFS.cur_read], 0
cmp [ebp+NTFS.cur_iRecord], 0
and [ebp+NTFS.ntfs_cur_read], 0
cmp [ebp+NTFS.ntfs_cur_iRecord], 0
jnz .nomft
cmp [ebp+NTFS.cur_attr], 0x80
cmp [ebp+NTFS.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]
cmp eax, [ebp+NTFS.ntfs_cur_offs]
jbe .nomft
; precalculated part of $Mft $DATA
mov esi, [ebp+NTFS.mft_retrieval]
mov eax, [ebp+NTFS.cur_offs]
mov eax, [ebp+NTFS.ntfs_cur_offs]
xor edx, edx
div [ebp+NTFS.sectors_per_cluster]
; eax = VCN, edx = offset in sectors from beginning of cluster
612,7 → 592,6
pop eax
jnz .mftscan
jmp .nomft
 
@@:
push ecx
add ecx, eax
624,15 → 603,15
; eax = sector on partition
pop edx
add eax, edx
mov ebx, [ebp+NTFS.cur_buf]
mov ebx, [ebp+NTFS.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]
mov [ebp+NTFS.ntfsLastRead], eax
cmp ecx, [ebp+NTFS.ntfs_cur_size]
jb @f
mov ecx, [ebp+NTFS.cur_size]
mov ecx, [ebp+NTFS.ntfs_cur_size]
@@:
; ecx = number of sequential sectors to read
push eax
640,17 → 619,17
pop edx
test eax, eax
jnz .errread
add [ebp+NTFS.cur_read], 0x200
dec [ebp+NTFS.cur_size]
inc [ebp+NTFS.cur_offs]
add [ebp+NTFS.ntfs_cur_read], 0x200
dec [ebp+NTFS.ntfs_cur_size]
inc [ebp+NTFS.ntfs_cur_offs]
add ebx, 0x200
mov [ebp+NTFS.cur_buf], ebx
mov [ebp+NTFS.ntfs_cur_buf], ebx
lea eax, [edx+1]
loop @b
pop ecx
xor eax, eax
xor edx, edx
cmp [ebp+NTFS.cur_size], eax
cmp [ebp+NTFS.ntfs_cur_size], eax
jz @f
add esi, 8
push eax
661,29 → 640,25
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.
mov eax, [ebp+NTFS.cur_iRecord]
mov [ebp+NTFS.attr_iRecord], eax
and [ebp+NTFS.attr_list], 0
or dword [ebp+NTFS.attr_size], -1
or dword [ebp+NTFS.attr_size+4], -1
or [ebp+NTFS.attr_iBaseRecord], -1
mov eax, [ebp+NTFS.ntfs_cur_iRecord]
mov [ebp+NTFS.ntfs_attr_iRecord], eax
and [ebp+NTFS.ntfs_attr_list], 0
or dword [ebp+NTFS.ntfs_attr_size], -1
or dword [ebp+NTFS.ntfs_attr_size+4], -1
or [ebp+NTFS.ntfs_attr_iBaseRecord], -1
call ntfs_read_file_record
jc .errret
; 2. Find required attribute.
691,128 → 666,126
; 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
mov [ebp+NTFS.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
mov ecx, [ebp+NTFS.ntfs_cur_attr]
and [ebp+NTFS.ntfs_attr_offs], 0
.scanattr:
cmp dword [eax], -1
jz .scandone
cmp dword [eax], ecx
jz .okattr
cmp [ebp+NTFS.attr_iBaseRecord], -1
cmp [ebp+NTFS.ntfs_attr_iBaseRecord], -1
jnz .scancont
cmp dword [eax], 0x20 ; $ATTR_LIST
jnz .scancont
mov [ebp+NTFS.attr_list], eax
mov [ebp+NTFS.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
mov [ebp+NTFS.ntfs_attr_offs], eax
.scancont:
add eax, [eax+sizeWithHeader]
add eax, [eax+4]
jmp .scanattr
 
.continue:
pushad
and [ebp+NTFS.cur_read], 0
and [ebp+NTFS.ntfs_cur_read], 0
.scandone:
; c) Check for required offset and length
mov ecx, [ebp+NTFS.attr_offs]
mov ecx, [ebp+NTFS.ntfs_attr_offs]
jecxz .noattr
push [ebp+NTFS.cur_size]
push [ebp+NTFS.cur_read]
push [ebp+NTFS.ntfs_cur_size]
push [ebp+NTFS.ntfs_cur_read]
call .doreadattr
pop edx
pop ecx
jc .ret
cmp [ebp+NTFS.bCanContinue], 0
jz .ret
sub edx, [ebp+NTFS.cur_read]
jc @f
cmp [ebp+NTFS.ntfs_bCanContinue], 0
jz @f
sub edx, [ebp+NTFS.ntfs_cur_read]
neg edx
shr edx, 9
sub ecx, edx
mov [ebp+NTFS.cur_size], ecx
jz .ret
mov [ebp+NTFS.ntfs_cur_size], ecx
jnz .not_in_cur
@@:
popad
ret
.noattr:
cmp [ebp+NTFS.cur_attr], 0x20
.not_in_cur:
cmp [ebp+NTFS.ntfs_cur_attr], 0x20
jz @f
mov ecx, [ebp+NTFS.attr_list]
mov ecx, [ebp+NTFS.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:
cmp [ebp+NTFS.ntfs_attr_offs], 1 ; CF set <=> ntfs_attr_offs == 0
popad
ret
 
.lookattr:
; required attribute or required offset was not found in base record;
; it may be present in auxiliary records;
; scan $ATTR_LIST
mov eax, [ebp+NTFS.attr_iBaseRecord]
mov eax, [ebp+NTFS.ntfs_attr_iBaseRecord]
cmp eax, -1
jz @f
call ntfs_read_file_record
jc .errret
or [ebp+NTFS.attr_iBaseRecord], -1
or [ebp+NTFS.ntfs_attr_iBaseRecord], -1
@@:
push [ebp+NTFS.cur_offs]
push [ebp+NTFS.cur_size]
push [ebp+NTFS.cur_read]
push [ebp+NTFS.cur_buf]
push dword [ebp+NTFS.attr_size]
push dword [ebp+NTFS.attr_size+4]
or dword [ebp+NTFS.attr_size], -1
or dword [ebp+NTFS.attr_size+4], -1
and [ebp+NTFS.cur_offs], 0
mov [ebp+NTFS.cur_size], 2
and [ebp+NTFS.cur_read], 0
lea eax, [ebp+NTFS.attrlist_buf]
cmp [ebp+NTFS.cur_iRecord], 0
push [ebp+NTFS.ntfs_cur_offs]
push [ebp+NTFS.ntfs_cur_size]
push [ebp+NTFS.ntfs_cur_read]
push [ebp+NTFS.ntfs_cur_buf]
push dword [ebp+NTFS.ntfs_attr_size]
push dword [ebp+NTFS.ntfs_attr_size+4]
or dword [ebp+NTFS.ntfs_attr_size], -1
or dword [ebp+NTFS.ntfs_attr_size+4], -1
and [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.ntfs_cur_size], 2
and [ebp+NTFS.ntfs_cur_read], 0
lea eax, [ebp+NTFS.ntfs_attrlist_buf]
cmp [ebp+NTFS.ntfs_cur_iRecord], 0
jnz @f
lea eax, [ebp+NTFS.attrlist_mft_buf]
lea eax, [ebp+NTFS.ntfs_attrlist_mft_buf]
@@:
mov [ebp+NTFS.cur_buf], eax
mov [ebp+NTFS.ntfs_cur_buf], eax
push eax
call .doreadattr
pop esi
mov edx, 1
pop dword [ebp+NTFS.attr_size+4]
pop dword [ebp+NTFS.attr_size]
mov ecx, [ebp+NTFS.cur_read]
pop [ebp+NTFS.cur_buf]
pop [ebp+NTFS.cur_read]
pop [ebp+NTFS.cur_size]
pop [ebp+NTFS.cur_offs]
pop dword [ebp+NTFS.ntfs_attr_size+4]
pop dword [ebp+NTFS.ntfs_attr_size]
mov ecx, [ebp+NTFS.ntfs_cur_read]
pop [ebp+NTFS.ntfs_cur_buf]
pop [ebp+NTFS.ntfs_cur_read]
pop [ebp+NTFS.ntfs_cur_size]
pop [ebp+NTFS.ntfs_cur_offs]
jc .errret
or edi, -1
lea ecx, [ecx+esi-1Ah]
.scanliststart:
push ecx
mov eax, [ebp+NTFS.cur_attr]
mov eax, [ebp+NTFS.ntfs_cur_attr]
.scanlist:
cmp esi, [esp]
jae .scanlistdone
822,7 → 795,6
movzx ecx, word [esi+4]
add esi, ecx
jmp .scanlist
 
@@:
; ignore named $DATA attributes (aka NTFS streams)
cmp eax, 0x80
834,18 → 806,25
mov eax, [esi+8]
test eax, eax
jnz .testf
mov eax, dword [ebp+NTFS.attr_size]
and eax, dword [ebp+NTFS.attr_size+4]
mov eax, dword [ebp+NTFS.ntfs_attr_size]
and eax, dword [ebp+NTFS.ntfs_attr_size+4]
cmp eax, -1
jnz .testfz
; 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
mov ecx, [ebp+NTFS.cur_attr]
mov ecx, [ebp+NTFS.ntfs_cur_attr]
@@:
cmp dword [eax], -1
jz .errret2_pop
854,7 → 833,6
.l1:
add eax, [eax+4]
jmp @b
 
@@:
cmp eax, 0x80
jnz @f
864,53 → 842,53
cmp byte [eax+8], 0
jnz .sdnores
mov eax, [eax+10h]
mov dword [ebp+NTFS.attr_size], eax
and dword [ebp+NTFS.attr_size+4], 0
mov dword [ebp+NTFS.ntfs_attr_size], eax
and dword [ebp+NTFS.ntfs_attr_size+4], 0
jmp .testfz
 
.sdnores:
mov ecx, [eax+30h]
mov dword [ebp+NTFS.attr_size], ecx
mov dword [ebp+NTFS.ntfs_attr_size], ecx
mov ecx, [eax+34h]
mov dword [ebp+NTFS.attr_size+4], ecx
mov dword [ebp+NTFS.ntfs_attr_size+4], ecx
.testfz:
xor eax, eax
.testf:
imul eax, [ebp+NTFS.sectors_per_cluster]
cmp eax, [ebp+NTFS.cur_offs]
cmp eax, [ebp+NTFS.ntfs_cur_offs]
pop eax
ja @f
mov edi, [esi+10h] ; keep previous iRecord
jmp .scanlistcont
 
@@:
pop ecx
.scanlistfound:
cmp edi, -1
jz .ret
mov eax, [ebp+NTFS.cur_iRecord]
mov [ebp+NTFS.attr_iBaseRecord], eax
jnz @f
popad
ret
@@:
mov eax, [ebp+NTFS.ntfs_cur_iRecord]
mov [ebp+NTFS.ntfs_attr_iBaseRecord], eax
mov eax, edi
jmp .beginfindattr
 
.scanlistdone:
pop ecx
sub ecx, ebp
sub ecx, NTFS.attrlist_buf-1Ah
cmp [ebp+NTFS.cur_iRecord], 0
sub ecx, NTFS.ntfs_attrlist_buf-1Ah
cmp [ebp+NTFS.ntfs_cur_iRecord], 0
jnz @f
sub ecx, NTFS.attrlist_mft_buf-NTFS.attrlist_buf
sub ecx, NTFS.ntfs_attrlist_mft_buf-NTFS.ntfs_attrlist_buf
@@:
cmp ecx, 0x400
jnz .scanlistfound
inc edx
push esi edi
lea esi, [ebp+NTFS.attrlist_buf+0x200]
lea edi, [ebp+NTFS.attrlist_buf]
cmp [ebp+NTFS.cur_iRecord], 0
lea esi, [ebp+NTFS.ntfs_attrlist_buf+0x200]
lea edi, [ebp+NTFS.ntfs_attrlist_buf]
cmp [ebp+NTFS.ntfs_cur_iRecord], 0
jnz @f
lea esi, [ebp+NTFS.attrlist_mft_buf+0x200]
lea edi, [ebp+NTFS.attrlist_mft_buf]
lea esi, [ebp+NTFS.ntfs_attrlist_mft_buf+0x200]
lea edi, [ebp+NTFS.ntfs_attrlist_mft_buf]
@@:
mov ecx, 0x200/4
rep movsd
917,52 → 895,52
mov eax, edi
pop edi esi
sub esi, 0x200
push [ebp+NTFS.cur_offs]
push [ebp+NTFS.cur_size]
push [ebp+NTFS.cur_read]
push [ebp+NTFS.cur_buf]
push dword [ebp+NTFS.attr_size]
push dword [ebp+NTFS.attr_size+4]
or dword [ebp+NTFS.attr_size], -1
or dword [ebp+NTFS.attr_size+4], -1
mov [ebp+NTFS.cur_offs], edx
mov [ebp+NTFS.cur_size], 1
and [ebp+NTFS.cur_read], 0
mov [ebp+NTFS.cur_buf], eax
mov ecx, [ebp+NTFS.attr_list]
push [ebp+NTFS.ntfs_cur_offs]
push [ebp+NTFS.ntfs_cur_size]
push [ebp+NTFS.ntfs_cur_read]
push [ebp+NTFS.ntfs_cur_buf]
push dword [ebp+NTFS.ntfs_attr_size]
push dword [ebp+NTFS.ntfs_attr_size+4]
or dword [ebp+NTFS.ntfs_attr_size], -1
or dword [ebp+NTFS.ntfs_attr_size+4], -1
mov [ebp+NTFS.ntfs_cur_offs], edx
mov [ebp+NTFS.ntfs_cur_size], 1
and [ebp+NTFS.ntfs_cur_read], 0
mov [ebp+NTFS.ntfs_cur_buf], eax
mov ecx, [ebp+NTFS.ntfs_attr_list]
push esi edx edi
call .doreadattr
pop edi edx esi
mov ecx, [ebp+NTFS.cur_read]
pop dword [ebp+NTFS.attr_size+4]
pop dword [ebp+NTFS.attr_size]
pop [ebp+NTFS.cur_buf]
pop [ebp+NTFS.cur_read]
pop [ebp+NTFS.cur_size]
pop [ebp+NTFS.cur_offs]
mov ecx, [ebp+NTFS.ntfs_cur_read]
pop dword [ebp+NTFS.ntfs_attr_size+4]
pop dword [ebp+NTFS.ntfs_attr_size]
pop [ebp+NTFS.ntfs_cur_buf]
pop [ebp+NTFS.ntfs_cur_read]
pop [ebp+NTFS.ntfs_cur_size]
pop [ebp+NTFS.ntfs_cur_offs]
jc .errret
lea ecx, [ecx+ebp+NTFS.attrlist_buf+0x200-0x1A]
cmp [ebp+NTFS.cur_iRecord], 0
lea ecx, [ecx+ebp+NTFS.ntfs_attrlist_buf+0x200-0x1A]
cmp [ebp+NTFS.ntfs_cur_iRecord], 0
jnz .scanliststart
add ecx, NTFS.attrlist_mft_buf-NTFS.attrlist_buf
add ecx, NTFS.ntfs_attrlist_mft_buf-NTFS.ntfs_attrlist_buf
jmp .scanliststart
 
.doreadattr:
mov [ebp+NTFS.bCanContinue], 0
cmp byte [ecx+nonResidentFlag], 0
mov [ebp+NTFS.ntfs_bCanContinue], 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]
mov edx, [ebp+NTFS.ntfs_cur_offs]
shr eax, 9
cmp eax, edx
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]
mov eax, [ebp+NTFS.ntfs_cur_size]
cmp eax, (0xFFFFFFFF shr 9)+1
jbe @f
mov eax, (0xFFFFFFFF shr 9)+1
973,75 → 951,72
mov eax, esi
@@:
; eax = length, edx -> data
mov [ebp+NTFS.cur_read], eax
mov [ebp+NTFS.ntfs_cur_read], eax
mov ecx, eax
mov eax, edx
mov ebx, [ebp+NTFS.cur_buf]
mov ebx, [ebp+NTFS.ntfs_cur_buf]
call memmove
and [ebp+NTFS.cur_size], 0 ; CF=0
and [ebp+NTFS.ntfs_cur_size], 0 ; CF=0
ret
 
.nonresident:
; Not all auxiliary records contain correct FileSize info
mov eax, dword [ebp+NTFS.attr_size]
mov edx, dword [ebp+NTFS.attr_size+4]
mov eax, dword [ebp+NTFS.ntfs_attr_size]
mov edx, dword [ebp+NTFS.ntfs_attr_size+4]
push eax
and eax, edx
cmp eax, -1
pop eax
jnz @f
mov eax, [ecx+attributeRealSize]
mov edx, [ecx+attributeRealSize+4]
mov dword [ebp+NTFS.attr_size], eax
mov dword [ebp+NTFS.attr_size+4], edx
mov eax, [ecx+30h] ; FileSize
mov edx, [ecx+34h]
mov dword [ebp+NTFS.ntfs_attr_size], eax
mov dword [ebp+NTFS.ntfs_attr_size+4], edx
@@:
add eax, 0x1FF
adc edx, 0
shrd eax, edx, 9
sub eax, [ebp+NTFS.cur_offs]
sub eax, [ebp+NTFS.ntfs_cur_offs]
ja @f
; return with nothing read
and [ebp+NTFS.cur_size], 0
and [ebp+NTFS.ntfs_cur_size], 0
.okret:
clc
ret
 
@@:
; reduce read length
and [ebp+NTFS.cur_tail], 0
cmp [ebp+NTFS.cur_size], eax
and [ebp+NTFS.ntfs_cur_tail], 0
cmp [ebp+NTFS.ntfs_cur_size], eax
jb @f
mov [ebp+NTFS.cur_size], eax
mov eax, dword [ebp+NTFS.attr_size]
mov [ebp+NTFS.ntfs_cur_size], eax
mov eax, dword [ebp+NTFS.ntfs_attr_size]
and eax, 0x1FF
mov [ebp+NTFS.cur_tail], eax
mov [ebp+NTFS.ntfs_cur_tail], eax
@@:
cmp [ebp+NTFS.cur_size], 0
cmp [ebp+NTFS.ntfs_cur_size], 0
jz .okret
mov eax, [ebp+NTFS.cur_offs]
mov eax, [ebp+NTFS.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
cmp [ebp+NTFS.ntfs_cur_attr], 0x80
jnz .sys
cmp [ebp+NTFS.cur_iRecord], 0
cmp [ebp+NTFS.ntfs_cur_iRecord], 0
jz .sys
push fs_read64_app
cmp [ebp+NTFS.bWriteAttr], 1
cmp [ebp+NTFS.ntfsWriteAttr], 1
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
mov [ebp+NTFS.ntfsFragmentCount], 0
.readloop:
call ntfs_decode_mcb_entry
jnc .break
1058,12 → 1033,12
neg ecx
imul ecx, [ebp+NTFS.sectors_per_cluster]
sub ecx, edx
cmp ecx, [ebp+NTFS.cur_size]
cmp ecx, [ebp+NTFS.ntfs_cur_size]
jb @f
mov ecx, [ebp+NTFS.cur_size]
mov ecx, [ebp+NTFS.ntfs_cur_size]
@@:
mov ebx, [ebp+NTFS.cur_buf]
mov [ebp+NTFS.LastRead], eax
mov ebx, [ebp+NTFS.ntfs_cur_buf]
mov [ebp+NTFS.ntfsLastRead], eax
push ecx
xor edx, edx
call dword[esp+18h]
1070,36 → 1045,34
pop ecx
test eax, eax
jnz .errread2
sub [ebp+NTFS.cur_size], ecx
add [ebp+NTFS.cur_offs], ecx
sub [ebp+NTFS.ntfs_cur_size], ecx
add [ebp+NTFS.ntfs_cur_offs], ecx
shl ecx, 9
add [ebp+NTFS.cur_read], ecx
add [ebp+NTFS.cur_buf], ecx
inc [ebp+NTFS.fragmentCount]
add [ebp+NTFS.ntfs_cur_read], ecx
add [ebp+NTFS.ntfs_cur_buf], ecx
inc [ebp+NTFS.ntfsFragmentCount]
pop ecx
xor eax, eax
xor edx, edx
cmp [ebp+NTFS.cur_size], 0
cmp [ebp+NTFS.ntfs_cur_size], 0
jnz .readloop
add esp, 14h
mov eax, [ebp+NTFS.cur_tail]
mov eax, [ebp+NTFS.ntfs_cur_tail]
test eax, eax
jz @f
sub eax, 0x200
add [ebp+NTFS.cur_read], eax
add [ebp+NTFS.ntfs_cur_read], eax
@@:
clc
ret
 
.errread2:
pop ecx
add esp, 14h
stc
ret
 
.break:
add esp, 14h ; CF=0
mov [ebp+NTFS.bCanContinue], 1
mov [ebp+NTFS.ntfs_bCanContinue], 1
ret
 
ntfs_read_file_record:
1113,39 → 1086,39
shrd eax, edx, 9
shr edx, 9
jnz .errret
push [ebp+NTFS.attr_iRecord]
push [ebp+NTFS.attr_iBaseRecord]
push [ebp+NTFS.attr_offs]
push [ebp+NTFS.attr_list]
push dword [ebp+NTFS.attr_size+4]
push dword [ebp+NTFS.attr_size]
push [ebp+NTFS.cur_iRecord]
push [ebp+NTFS.cur_attr]
push [ebp+NTFS.cur_offs]
push [ebp+NTFS.cur_size]
push [ebp+NTFS.cur_buf]
push [ebp+NTFS.cur_read]
mov [ebp+NTFS.cur_attr], 0x80 ; $DATA
and [ebp+NTFS.cur_iRecord], 0 ; $Mft
mov [ebp+NTFS.cur_offs], eax
push [ebp+NTFS.ntfs_attr_iRecord]
push [ebp+NTFS.ntfs_attr_iBaseRecord]
push [ebp+NTFS.ntfs_attr_offs]
push [ebp+NTFS.ntfs_attr_list]
push dword [ebp+NTFS.ntfs_attr_size+4]
push dword [ebp+NTFS.ntfs_attr_size]
push [ebp+NTFS.ntfs_cur_iRecord]
push [ebp+NTFS.ntfs_cur_attr]
push [ebp+NTFS.ntfs_cur_offs]
push [ebp+NTFS.ntfs_cur_size]
push [ebp+NTFS.ntfs_cur_buf]
push [ebp+NTFS.ntfs_cur_read]
mov [ebp+NTFS.ntfs_cur_attr], 0x80 ; $DATA
and [ebp+NTFS.ntfs_cur_iRecord], 0 ; $Mft
mov [ebp+NTFS.ntfs_cur_offs], eax
shr ecx, 9
mov [ebp+NTFS.cur_size], ecx
mov [ebp+NTFS.ntfs_cur_size], ecx
mov eax, [ebp+NTFS.frs_buffer]
mov [ebp+NTFS.cur_buf], eax
mov [ebp+NTFS.ntfs_cur_buf], eax
call ntfs_read_attr
mov edx, [ebp+NTFS.cur_read]
pop [ebp+NTFS.cur_read]
pop [ebp+NTFS.cur_buf]
pop [ebp+NTFS.cur_size]
pop [ebp+NTFS.cur_offs]
pop [ebp+NTFS.cur_attr]
pop [ebp+NTFS.cur_iRecord]
pop dword [ebp+NTFS.attr_size]
pop dword [ebp+NTFS.attr_size+4]
pop [ebp+NTFS.attr_list]
pop [ebp+NTFS.attr_offs]
pop [ebp+NTFS.attr_iBaseRecord]
pop [ebp+NTFS.attr_iRecord]
mov edx, [ebp+NTFS.ntfs_cur_read]
pop [ebp+NTFS.ntfs_cur_read]
pop [ebp+NTFS.ntfs_cur_buf]
pop [ebp+NTFS.ntfs_cur_size]
pop [ebp+NTFS.ntfs_cur_offs]
pop [ebp+NTFS.ntfs_cur_attr]
pop [ebp+NTFS.ntfs_cur_iRecord]
pop dword [ebp+NTFS.ntfs_attr_size]
pop dword [ebp+NTFS.ntfs_attr_size+4]
pop [ebp+NTFS.ntfs_attr_list]
pop [ebp+NTFS.ntfs_attr_offs]
pop [ebp+NTFS.ntfs_attr_iBaseRecord]
pop [ebp+NTFS.ntfs_attr_iRecord]
jc .ret
cmp edx, [ebp+NTFS.frs_size]
jnz .errret
1160,7 → 1133,6
.ret:
pop edx ecx
ret
 
.errret:
pop edx ecx
xor eax, eax
1177,9 → 1149,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 → 1166,6
popad
clc
ret
 
.err:
popad
stc
1262,43 → 1233,87
ntfs_find_lfn:
; in: [esi]+[esp+4] = name
; out:
; [ebp+NTFS.cur_iRecord] = number of MFT fileRecord
; [ebp+NTFS.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.ntfs_cur_iRecord], 5 ; start parse from root cluster
.doit2:
mov [ebp+NTFS.cur_attr], 0x90 ; $INDEX_ROOT
and [ebp+NTFS.cur_offs], 0
mov [ebp+NTFS.ntfs_cur_attr], 0x90 ; $INDEX_ROOT
and [ebp+NTFS.ntfs_cur_offs], 0
mov eax, [ebp+NTFS.cur_index_size]
mov [ebp+NTFS.cur_size], eax
mov [ebp+NTFS.ntfs_cur_size], eax
mov eax, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.cur_buf], eax
mov [ebp+NTFS.ntfs_cur_buf], eax
call ntfs_read_attr
mov eax, 0
jnc @f
.ret:
ret 4
@@:
cmp [ebp+NTFS.ntfs_cur_read], 0x20
jc .ret
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.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,60 → 1333,46
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
mov [ebp+NTFS.cur_attr], 0xA0 ; $INDEX_ALLOCATION
mov [ebp+NTFS.cur_size], edx
mov [ebp+NTFS.ntfs_cur_offs], eax
mov [ebp+NTFS.ntfs_cur_attr], 0xA0 ; $INDEX_ALLOCATION
mov [ebp+NTFS.ntfs_cur_size], edx
mov eax, [ebp+NTFS.cur_index_buf]
mov esi, eax
mov [ebp+NTFS.cur_buf], eax
call ntfs_read_attr.newAttribute
mov [ebp+NTFS.ntfs_cur_buf], eax
push edx
call ntfs_read_attr
pop edx
mov eax, edx
shl eax, 9
cmp [ebp+NTFS.cur_read], eax
cmp [ebp+NTFS.ntfs_cur_read], eax
jnz .err
cmp dword [esi], 'INDX'
jnz .err
mov [ebp+NTFS.cur_buf], esi
mov [ebp+NTFS.ntfs_cur_buf], esi
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,13 → 1381,12
pop edi
pop esi
jmp .scanloopcont
 
.done:
.next:
pop esi
pop esi
mov eax, [esi]
mov [ebp+NTFS.cur_iRecord], eax
mov [ebp+NTFS.ntfs_cur_iRecord], eax
mov [esp+1Ch], esi
mov [esp+4], edi
popad
1394,10 → 1394,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 → 1408,6
or ebx, -1
movi eax, ERROR_ACCESS_DENIED
ret
 
@@:
call ntfs_lock
stdcall ntfs_find_lfn, [esp+4]
1415,11 → 1416,10
or ebx, -1
movi eax, ERROR_FILE_NOT_FOUND
ret
 
.found:
mov [ebp+NTFS.cur_attr], 0x80 ; $DATA
and [ebp+NTFS.cur_offs], 0
and [ebp+NTFS.cur_size], 0
mov [ebp+NTFS.ntfs_cur_attr], 0x80 ; $DATA
and [ebp+NTFS.ntfs_cur_offs], 0
and [ebp+NTFS.ntfs_cur_size], 0
call ntfs_read_attr
jnc @f
call ntfs_unlock
1426,7 → 1426,6
or ebx, -1
movi eax, ERROR_ACCESS_DENIED
ret
 
@@:
pushad
and dword [esp+10h], 0
1437,10 → 1436,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]
1451,15 → 1450,15
mov edx, [ebx+8]
shrd eax, edx, 9
pop edx
mov [ebp+NTFS.cur_offs], eax
mov [ebp+NTFS.cur_size], 1
lea eax, [ebp+NTFS.bitmap_buf]
mov [ebp+NTFS.cur_buf], eax
mov [ebp+NTFS.ntfs_cur_offs], eax
mov [ebp+NTFS.ntfs_cur_size], 1
lea eax, [ebp+NTFS.ntfs_bitmap_buf]
mov [ebp+NTFS.ntfs_cur_buf], eax
call ntfs_read_attr.continue
mov eax, [ebx+4]
and eax, 0x1FF
lea esi, [ebp+NTFS.bitmap_buf+eax]
sub eax, [ebp+NTFS.cur_read]
lea esi, [ebp+NTFS.ntfs_bitmap_buf+eax]
sub eax, [ebp+NTFS.ntfs_cur_read]
jae .eof0
neg eax
push ecx
1479,14 → 1478,12
call ntfs_unlock
xor eax, eax
ret
 
@@:
cmp [ebp+NTFS.cur_read], 0x200
cmp [ebp+NTFS.ntfs_cur_read], 0x200
jz .alignedstart
.eof_ebx:
popad
jmp .eof
 
.alignedstart:
mov eax, [ebx+4]
push edx
1495,41 → 1492,41
adc edx, 0
shrd eax, edx, 9
pop edx
mov [ebp+NTFS.cur_offs], eax
mov [ebp+NTFS.cur_buf], edx
mov [ebp+NTFS.ntfs_cur_offs], eax
mov [ebp+NTFS.ntfs_cur_buf], edx
mov eax, ecx
shr eax, 9
mov [ebp+NTFS.cur_size], eax
add eax, [ebp+NTFS.cur_offs]
mov [ebp+NTFS.ntfs_cur_size], eax
add eax, [ebp+NTFS.ntfs_cur_offs]
push eax
call ntfs_read_attr.continue
pop [ebp+NTFS.cur_offs]
mov eax, [ebp+NTFS.cur_read]
pop [ebp+NTFS.ntfs_cur_offs]
mov eax, [ebp+NTFS.ntfs_cur_read]
add [esp+10h], eax
mov eax, ecx
and eax, not 0x1FF
cmp [ebp+NTFS.cur_read], eax
cmp [ebp+NTFS.ntfs_cur_read], eax
jnz .eof_ebx
and ecx, 0x1FF
jz .retok
add edx, [ebp+NTFS.cur_read]
mov [ebp+NTFS.cur_size], 1
lea eax, [ebp+NTFS.bitmap_buf]
mov [ebp+NTFS.cur_buf], eax
add edx, [ebp+NTFS.ntfs_cur_read]
mov [ebp+NTFS.ntfs_cur_size], 1
lea eax, [ebp+NTFS.ntfs_bitmap_buf]
mov [ebp+NTFS.ntfs_cur_buf], eax
call ntfs_read_attr.continue
cmp [ebp+NTFS.cur_read], ecx
cmp [ebp+NTFS.ntfs_cur_read], ecx
jb @f
mov [ebp+NTFS.cur_read], ecx
mov [ebp+NTFS.ntfs_cur_read], ecx
@@:
xchg ecx, [ebp+NTFS.cur_read]
xchg ecx, [ebp+NTFS.ntfs_cur_read]
push ecx
mov edi, edx
lea esi, [ebp+NTFS.bitmap_buf]
lea esi, [ebp+NTFS.ntfs_bitmap_buf]
add [esp+10h+4], ecx
rep movsb
pop ecx
xor eax, eax
cmp ecx, [ebp+NTFS.cur_read]
cmp ecx, [ebp+NTFS.ntfs_cur_read]
jz @f
mov al, ERROR_END_OF_FILE
@@:
1541,41 → 1538,103
;----------------------------------------------------------------
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
@@:
mov [ebp+NTFS.cur_attr], 0x10 ; $STANDARD_INFORMATION
and [ebp+NTFS.cur_offs], 0
mov [ebp+NTFS.cur_size], 1
lea eax, [ebp+NTFS.bitmap_buf]
mov [ebp+NTFS.cur_buf], eax
jnc .doit2
.notfound:
or ebx, -1
push ERROR_FILE_NOT_FOUND
.pop_ret:
call ntfs_unlock
pop eax
ret
.doit:
mov [ebp+NTFS.ntfs_cur_iRecord], eax
.doit2:
mov [ebp+NTFS.ntfs_cur_attr], 0x10 ; $STANDARD_INFORMATION
and [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.ntfs_cur_size], 1
lea eax, [ebp+NTFS.ntfs_bitmap_buf]
mov [ebp+NTFS.ntfs_cur_buf], eax
call ntfs_read_attr
jc ntfsFail
mov [ebp+NTFS.cur_attr], 0x90 ; $INDEX_ROOT
.doit:
jc .notfound
mov [ebp+NTFS.ntfs_cur_attr], 0x90 ; $INDEX_ROOT
and [ebp+NTFS.ntfs_cur_offs], 0
mov eax, [ebp+NTFS.cur_index_size]
mov [ebp+NTFS.cur_size], eax
mov [ebp+NTFS.ntfs_cur_size], eax
mov eax, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.cur_buf], eax
call ntfs_read_attr.newAttribute
jc ntfsFail
cmp [ebp+NTFS.cur_read], 0x20
jc ntfsFail
mov [ebp+NTFS.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:
cmp [ebp+NTFS.ntfs_cur_read], 0x20
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.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
1591,7 → 1650,7
; edi -> BDFE, esi -> current index data, ebx = first wanted block,
; ecx = number of blocks to read
; edx -> parameters block: dd <output>, dd <flags>
cmp [ebp+NTFS.cur_iRecord], 5
cmp [ebp+NTFS.ntfs_cur_iRecord], 5
jz .skip_specials
; dot and dotdot entries
push esi
1602,66 → 1661,50
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
lea edi, [ebp+NTFS.bitmap_buf]
mov [ebp+NTFS.cur_buf], edi
lea edi, [ebp+NTFS.ntfs_bitmap_buf]
mov [ebp+NTFS.ntfs_cur_buf], edi
mov ecx, 0x400/4
xor eax, eax
rep stosd
mov [ebp+NTFS.cur_attr], 0xB0 ; $BITMAP
and [ebp+NTFS.cur_offs], 0
mov [ebp+NTFS.cur_size], 2
call ntfs_read_attr.newAttribute
mov [ebp+NTFS.ntfs_cur_attr], 0xB0 ; $BITMAP
and [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.ntfs_cur_size], 2
call ntfs_read_attr
pop edi ecx
push 0 ; save offset in $BITMAP attribute
and [ebp+NTFS.cur_offs], 0
and [ebp+NTFS.ntfs_cur_offs], 0
.dumploop:
mov [ebp+NTFS.cur_attr], 0xA0
mov [ebp+NTFS.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_offs]
push eax
mov [ebp+NTFS.ntfs_cur_size], eax
mov eax, [ebp+NTFS.cur_index_buf]
mov esi, eax
mov [ebp+NTFS.ntfs_cur_buf], eax
push [ebp+NTFS.ntfs_cur_offs]
mov eax, [ebp+NTFS.ntfs_cur_offs]
imul eax, [ebp+NTFS.cur_subnode_size]
mov [ebp+NTFS.cur_offs], eax
call ntfs_read_attr.newAttribute
pop [ebp+NTFS.cur_offs]
mov [ebp+NTFS.ntfs_cur_offs], eax
call ntfs_read_attr
pop [ebp+NTFS.ntfs_cur_offs]
mov eax, [ebp+NTFS.cur_subnode_size]
shl eax, 9
cmp [ebp+NTFS.cur_read], eax
cmp [ebp+NTFS.ntfs_cur_read], eax
jnz .done
push eax
mov eax, [ebp+NTFS.cur_offs]
mov eax, [ebp+NTFS.ntfs_cur_offs]
and eax, 0x400*8-1
bt dword [ebp+NTFS.bitmap_buf], eax
bt dword [ebp+NTFS.ntfs_bitmap_buf], eax
pop eax
jnc .dump_subnode_done
cmp dword [esi], 'INDX'
1671,40 → 1714,38
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
inc [ebp+NTFS.ntfs_cur_offs]
test [ebp+NTFS.ntfs_cur_offs], 0x400*8-1
jnz .dumploop
mov [ebp+NTFS.cur_attr], 0xB0
mov [ebp+NTFS.ntfs_cur_attr], 0xB0
push ecx edi
lea edi, [ebp+NTFS.bitmap_buf]
mov [ebp+NTFS.cur_buf], edi
lea edi, [ebp+NTFS.ntfs_bitmap_buf]
mov [ebp+NTFS.ntfs_cur_buf], edi
mov ecx, 0x400/4
xor eax, eax
rep stosd
pop edi ecx
pop eax
push [ebp+NTFS.cur_offs]
push [ebp+NTFS.ntfs_cur_offs]
inc eax
mov [ebp+NTFS.cur_offs], eax
mov [ebp+NTFS.cur_size], 2
mov [ebp+NTFS.ntfs_cur_offs], eax
mov [ebp+NTFS.ntfs_cur_size], 2
push eax
call ntfs_read_attr.newAttribute
call ntfs_read_attr
pop eax
pop [ebp+NTFS.cur_offs]
pop [ebp+NTFS.ntfs_cur_offs]
push eax
jmp .dumploop
 
.done:
pop eax
pop edx
1731,18 → 1772,20
inc dword [eax+4] ; new file block copied
mov eax, [edx+4]
mov [edi+4], eax
; mov eax, dword [ntfs_bitmap_buf+0x20]
; or al, 0x10
mov eax, 0x10
stosd
scasd
push edx
mov eax, dword [ebp+NTFS.bitmap_buf]
mov edx, dword [ebp+NTFS.bitmap_buf+4]
mov eax, dword [ebp+NTFS.ntfs_bitmap_buf]
mov edx, dword [ebp+NTFS.ntfs_bitmap_buf+4]
call ntfs_datetime_to_bdfe
mov eax, dword [ebp+NTFS.bitmap_buf+0x18]
mov edx, dword [ebp+NTFS.bitmap_buf+0x1C]
mov eax, dword [ebp+NTFS.ntfs_bitmap_buf+0x18]
mov edx, dword [ebp+NTFS.ntfs_bitmap_buf+0x1C]
call ntfs_datetime_to_bdfe
mov eax, dword [ebp+NTFS.bitmap_buf+8]
mov edx, dword [ebp+NTFS.bitmap_buf+0xC]
mov eax, dword [ebp+NTFS.ntfs_bitmap_buf+8]
mov edx, dword [ebp+NTFS.ntfs_bitmap_buf+0xC]
call ntfs_datetime_to_bdfe
pop edx
xor eax, eax
1760,7 → 1803,6
pop edi
add edi, 520
ret
 
@@:
rep stosb
pop ecx
1773,11 → 1815,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 → 1831,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 → 1844,6
add edi, 520
pop esi ecx
ret
 
.ansi:
jecxz .skip
@@:
1820,7 → 1861,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,108 → 1870,136
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
mov [ebp+NTFS.ntfsFolder], 1
jmp @f
 
ntfs_CreateFile:
mov [ebp+NTFS.bFolder], 0
mov [ebp+NTFS.ntfsFolder], 0
@@:
cmp byte [esi], 0
jnz @f
1937,17 → 2006,16
xor ebx, ebx
movi eax, ERROR_ACCESS_DENIED
ret
 
@@: ; 1. Search file
call ntfs_lock
stdcall ntfs_find_lfn, [esp+4]
jc .notFound
; found, rewrite
cmp [ebp+NTFS.cur_iRecord], 16
cmp [ebp+NTFS.ntfs_cur_iRecord], 16
jc ntfsDenied
cmp [ebp+NTFS.bFolder], 1
cmp [ebp+NTFS.ntfsFolder], 1
jz .folder
cmp [ebp+NTFS.fragmentCount], 1
cmp [ebp+NTFS.ntfsFragmentCount], 1
jnz ntfsUnsupported ; record fragmented
; edit directory node
mov edi, [ebp+NTFS.cur_index_buf]
1957,7 → 2025,7
mov ecx, [esi+recordRealSize]
shr ecx, 2
rep movsd
mov esi, [ebp+NTFS.attr_offs]
mov esi, [ebp+NTFS.ntfs_attr_offs]
mov cl, [esi+attributeOffset]
sub esi, [ebp+NTFS.frs_buffer]
add eax, ecx
1966,11 → 2034,11
mov edx, [ebx+12]
mov [eax+fileRealSize], edx
mov dword [eax+fileRealSize+4], 0
mov eax, [ebp+NTFS.LastRead]
mov eax, [ebp+NTFS.ntfsLastRead]
mov [ebp+NTFS.nodeLastRead], eax
mov [ebp+NTFS.cur_attr], 0x80
mov [ebp+NTFS.cur_offs], 0
mov [ebp+NTFS.cur_size], 0
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 ntfsFail
mov ecx, [ebp+NTFS.frs_buffer]
1978,7 → 2046,7
xor edx, edx
cmp word [ecx+baseRecordReuse], 0
jnz ntfsUnsupported ; auxiliary record
mov ecx, [ebp+NTFS.attr_offs]
mov ecx, [ebp+NTFS.ntfs_attr_offs]
cmp word [ecx+attributeFlags], 0
jnz ntfsUnsupported
push ebx
2000,7 → 2068,7
.notFound: ; create
test eax, eax
jz ntfsFail
cmp [ebp+NTFS.fragmentCount], 1
cmp [ebp+NTFS.ntfsFragmentCount], 1
jnz ntfsUnsupported ; record fragmented
; 2. Prepare directory record
mov ecx, esi
2011,29 → 2079,27
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]
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
push ecx
cmp dword [edi], 'INDX'
jz .indexRecord
mov esi, [ebp+NTFS.frs_buffer] ; indexRoot
mov ecx, [esi+recordRealSize]
mov edx, [esi+recordRealSize]
add edx, ecx
cmp [esi+recordAllocatedSize], edx
jc .growTree
jnc @f
add esp, 12
jmp ntfsUnsupported ; indexAllocation required
@@: ; index fits in the indexRoot
mov [esi+recordRealSize], edx
mov ecx, edx
shr ecx, 2
rep movsd
mov edi, [ebp+NTFS.attr_offs]
mov edi, [ebp+NTFS.ntfs_attr_offs]
sub edi, [ebp+NTFS.frs_buffer]
add edi, [ebp+NTFS.cur_index_buf]
mov esi, [esp]
2041,172 → 2107,30
add [edi+sizeWithoutHeader], esi
mov cl, [edi+attributeOffset]
add edi, ecx
add [edi+rootNode+nodeRealSize], esi
add [edi+rootNode+nodeAllocatedSize], esi
add [edi+16+nodeRealSize], esi
add [edi+16+nodeAllocatedSize], esi
sub eax, [ebp+NTFS.cur_index_buf]
add eax, edi
mov edi, [ebp+NTFS.cur_index_buf]
add edi, edx
sub edi, 4
jmp .common
 
@@:
add esp, 16
jmp ntfsUnsupported
 
.growTree:
sub eax, rootNode
sub eax, [edi+rootNode+indexOffset]
push eax
; create indexRecord
mov ecx, 10
xor eax, eax
rep stosd
rdtsc
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]
cmp eax, [ebp+NTFS.frs_size]
jc @b
shr eax, 9
inc eax
mov edi, [ebp+NTFS.cur_index_buf]
mov dword[edi], 'INDX'
mov byte [edi+updateSequenceOffset], 28h
mov [edi+updateSequenceSize], al
add edi, recordNode
shl eax, 1
add eax, 28h-recordNode+7
and eax, not 7
mov [edi+indexOffset], eax
mov ecx, [esi+indexRecordSize]
sub ecx, recordNode
mov [edi+nodeAllocatedSize], ecx
add esi, rootNode
push esi
mov ecx, [esi+nodeRealSize]
sub ecx, [esi+indexOffset]
add eax, ecx
mov [edi+nodeRealSize], eax
shr ecx, 2
add esi, [esi+indexOffset]
add edi, [edi+indexOffset]
rep movsd ; copy root indexes
; clear root node
mov cl, 10
mov edi, [esp]
xor eax, eax
rep stosd
pop edi
mov byte [edi+indexOffset], 16
mov byte [edi+nodeRealSize], 28h
mov byte [edi+nodeAllocatedSize], 28h
mov byte [edi+nonLeafFlag], 1
mov byte [edi+16+indexAllocatedSize], 18h
mov byte [edi+16+indexFlags], 3
mov esi, [ebp+NTFS.attr_offs]
add edi, 28h
mov eax, edi
sub eax, esi
mov word [esi+sizeWithoutHeader], 38h
xchg [esi+sizeWithHeader], eax
cmp byte [esi+eax], -1
jnz @b
mov cl, 32
xor eax, eax
push edi
rep stosd
mov edi, [ebp+NTFS.BitmapStart]
call ntfsSpaceAlloc
jnc @f
add esp, 20
jmp ntfsDiskFull
 
@@: ; create $IndexAllocation
pop edi
mov byte [edi+attributeType], 0xA0
mov byte [edi+nonResidentFlag], 1
mov byte [edi+nameLength], 4
mov byte [edi+nameOffset], 40h
mov byte [edi+dataRunsOffset], 48h
mov byte [edi+sizeWithHeader], 50h
mov eax, [ebp+NTFS.fileDataSize]
dec eax
mov [edi+lastVCN], eax
inc eax
mul [ebp+NTFS.sectors_per_cluster]
shl eax, 9
mov [edi+attributeAllocatedSize], eax
mov [edi+attributeRealSize], eax
mov [edi+initialDataSize], eax
mov dword[edi+40h], 490024h ; unicode $I30
mov dword[edi+40h+4], 300033h
push edi
mov esi, edi
add edi, 48h
call createMcbEntry
mov esi, [ebp+NTFS.frs_buffer]
pop edi
mov al, [esi+newAttributeID]
mov [edi+attributeID], al
add edi, 50h
inc eax
; create $Bitmap
mov [edi+attributeID], al
inc eax
mov [esi+newAttributeID], al
mov byte [edi+attributeType], 0xB0
mov byte [edi+nameLength], 4
mov byte [edi+nameOffset], 18h
mov byte [edi+attributeOffset], 20h
mov byte [edi+sizeWithoutHeader], 8
mov byte [edi+sizeWithHeader], 28h
mov dword[edi+18h], 490024h ; unicode $I30
mov dword[edi+18h+4], 300033h
mov byte [edi+20h], 1
mov dword[edi+28h], -1
add edi, 30h
sub edi, esi
mov [esi+recordRealSize], edi
mov [ebp+NTFS.cur_buf], esi
call writeRecord ; fileRecord
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 ; indexRecord
mov ebx, [ebp+NTFS.cur_index_buf]
mov ax, [ebx+6]
dec eax
shl eax, 9
call ntfs_restore_usa
mov edi, [ebp+NTFS.cur_index_buf]
pop eax
add eax, recordNode
add eax, [edi+recordNode+indexOffset]
mov edx, [esp]
.indexRecord:
add edi, recordNode
add edx, [edi+nodeRealSize]
cmp [edi+nodeAllocatedSize], edx
mov edx, [edi+28]
add edx, ecx
cmp [edi+32], edx
jnc @f
add esp, 12
jmp ntfsUnsupported ; new node required
 
@@: ; index fits in the node
mov [edi+nodeRealSize], edx
mov [edi+28], edx
lea edi, [edi+edx+24-4]
.common:
add edi, edx
sub edi, 4
mov esi, edi
sub esi, [esp]
mov ecx, esi
sub ecx, eax ; eax = pointer in the record
sub ecx, eax ; eax = pointer in the node
shr ecx, 2
inc ecx
std
2224,20 → 2148,20
shl eax, 1
add eax, 42h
mov [edi+indexRawSize], ax
mov eax, [ebp+NTFS.attr_iRecord]
mov eax, [ebp+NTFS.ntfs_attr_iRecord]
mov [edi+directoryRecordReference], eax
mov eax, [ebp+NTFS.frs_buffer]
mov eax, [eax+reuseCounter]
mov [edi+directoryReferenceReuse], ax
mov eax, [ebp+NTFS.frs_size]
shr eax, 8
mov eax, [ebx+12]
add ecx, 30h+48h+8+18h+8
add ecx, eax
mov eax, [ebp+NTFS.fileRealSize]
add ecx, eax
mov [ebp+NTFS.fileRealSize], eax
mov [edi+fileRealSize], eax
cmp [ebp+NTFS.frs_size], ecx
jc @f
mov eax, [ebx+16]
mov [ebp+NTFS.fileDataStart], eax
xor eax, eax
@@:
mov ecx, [ebp+NTFS.sectors_per_cluster]
2252,7 → 2176,7
pop ecx
mov [ebp+NTFS.indexOffset], edi
mov [edi+fileNameLength], cl
add edi, fileName
add edi, 52h
@@: ; record filename
lodsb
call ansi2uni_char
2259,9 → 2183,9
stosw
dec ecx
jnz @b
mov eax, [ebp+NTFS.LastRead]
mov eax, [ebp+NTFS.ntfsLastRead]
mov [ebp+NTFS.nodeLastRead], eax
cmp [ebp+NTFS.bFolder], 0
cmp [ebp+NTFS.ntfsFolder], 0
jz @f
mov edi, [ebp+NTFS.indexOffset]
bts dword [edi+fileFlags], 28
2273,12 → 2197,12
mov edi, [ebp+NTFS.BitmapStart]
call ntfsSpaceAlloc
jc ntfsDiskFull
mov eax, [ebp+NTFS.fileDataStart]
mov [ebp+NTFS.fileDataStart], eax
mul [ebp+NTFS.sectors_per_cluster]
mov ecx, [ebp+NTFS.fileRealSize]
add ecx, 511
shr ecx, 9
mov ebx, [ebp+NTFS.fileDataBuffer]
mov ebx, [ebx+16]
call fs_write64_app
test eax, eax
jnz ntfsDevice
2304,14 → 2228,14
mov eax, [ebp+NTFS.frs_size]
shr eax, 9
mul edi
mov [ebp+NTFS.cur_iRecord], 0
mov [ebp+NTFS.cur_attr], 0x80
mov [ebp+NTFS.cur_offs], eax
mov [ebp+NTFS.cur_size], 1
mov [ebp+NTFS.ntfs_cur_iRecord], 0
mov [ebp+NTFS.ntfs_cur_attr], 0x80
mov [ebp+NTFS.ntfs_cur_offs], eax
mov [ebp+NTFS.ntfs_cur_size], 1
mov eax, [ebp+NTFS.frs_buffer]
mov [ebp+NTFS.cur_buf], eax
mov [ebp+NTFS.ntfs_cur_buf], eax
call ntfs_read_attr
cmp [ebp+NTFS.cur_read], 0
cmp [ebp+NTFS.ntfs_cur_read], 0
jz .extendMFT
jmp .mftRecord
 
2320,21 → 2244,21
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
mov [ebp+NTFS.ntfs_cur_iRecord], 0
mov [ebp+NTFS.ntfs_cur_attr], 0xB0
mov [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.ntfs_cur_size], 0
call ntfs_read_attr
jc ntfsFail
mov eax, [ebp+NTFS.mft_cluster]
mul [ebp+NTFS.sectors_per_cluster]
cmp eax, [ebp+NTFS.LastRead]
cmp eax, [ebp+NTFS.ntfsLastRead]
jnz ntfsUnsupported ; auxiliary record
mov edi, [ebp+NTFS.mftBitmapBuffer]
mov ecx, [ebp+NTFS.mftBitmapSize]
add edi, ecx
mov eax, ecx
mov edx, [ebp+NTFS.attr_offs]
mov edx, [ebp+NTFS.ntfs_attr_offs]
add ecx, 8
mov [edx+attributeRealSize], ecx
mov [edx+initialDataSize], ecx
2342,7 → 2266,7
mov [ebp+NTFS.newMftRecord], eax
mov dword [edi], 1
mov dword [edi+4], 0
mov [ebp+NTFS.cur_attr], 0x80
mov [ebp+NTFS.ntfs_cur_attr], 0x80
call ntfs_read_attr.newAttribute
jc ntfsFail
mov [ebp+NTFS.mftBitmapSize], ecx
2349,9 → 2273,9
.extendMFT:
mov eax, [ebp+NTFS.mft_cluster]
mul [ebp+NTFS.sectors_per_cluster]
cmp eax, [ebp+NTFS.LastRead]
cmp eax, [ebp+NTFS.ntfsLastRead]
jnz ntfsUnsupported ; auxiliary record
mov ecx, [ebp+NTFS.attr_offs]
mov ecx, [ebp+NTFS.ntfs_attr_offs]
mov eax, [ecx+attributeRealSize]
mov edx, [ecx+attributeRealSize+4]
xor ax, ax
2362,7 → 2286,7
call resizeAttribute
jc ntfsErrorPop2
mov eax, [ebp+NTFS.frs_buffer]
mov [ebp+NTFS.cur_buf], eax
mov [ebp+NTFS.ntfs_cur_buf], eax
call writeRecord ; $MFT
mov eax, [ebp+NTFS.mftmirr_cluster]
mul [ebp+NTFS.sectors_per_cluster]
2381,22 → 2305,19
rep stosd
mov edi, [ebp+NTFS.frs_buffer]
; record header
rdtsc
mov [edi+2ah], ax
mov eax, [ebp+NTFS.frs_size]
mov [edi+recordAllocatedSize], eax
shr eax, 9
inc eax
mov [edi+updateSequenceSize], al
shl eax, 1
add eax, 2ah+7
and eax, not 7
mov dword[edi], 'FILE'
mov byte [edi+updateSequenceOffset], 2ah
mov byte [edi+hardLinkCounter], 1
mov byte [edi+attributeOffset], 30h
mov byte [edi+newAttributeID], 3
mov [edi+attributeOffset], al
add edi, eax
rdtsc
mov [edi+2ah], ax
add edi, 30h
; $StandardInformation
mov byte [edi+attributeType], 10h
mov byte [edi+sizeWithHeader], 48h
2421,7 → 2342,7
rep movsd
mov byte [edi+sizeWithHeader], 50h
mov byte [edi+attributeID], 2
cmp [ebp+NTFS.bFolder], 1
cmp [ebp+NTFS.ntfsFolder], 1
jz .indexRoot
; $Data
mov byte [edi+attributeType], 80h
2450,7 → 2371,7
mov [edi+sizeWithoutHeader], ecx
mov byte [edi+attributeOffset], 18h
push edi
mov esi, [ebp+NTFS.fileDataBuffer]
mov esi, [ebp+NTFS.fileDataStart]
add edi, 18h
rep movsb
@@:
2462,7 → 2383,7
mov [edi+sizeWithHeader], eax
add edi, eax
mov al, 1
jmp .end
jmp @f
 
.indexRoot:
mov byte [edi+attributeType], 90h
2472,19 → 2393,12
mov byte [edi+attributeOffset], 20h
mov dword[edi+18h], 490024h ; unicode $I30
mov dword[edi+18h+4], 300033h
mov byte [edi+20h+indexedAttributesType], 30h
mov byte [edi+20h+attributeType], 30h
mov byte [edi+20h+collationRule], 1
mov eax, [ebp+NTFS.sectors_per_cluster]
mov dl, 1
shl eax, 8
@@:
shl eax, 1
shl edx, 1
cmp eax, [ebp+NTFS.frs_size]
jc @b
shr edx, 1
shl eax, 9
mov [edi+20h+indexRecordSize], eax
mov [edi+20h+indexRecordSizeClus], dl
mov byte [edi+20h+indexRecordSizeClus], 1
mov byte [edi+30h+indexOffset], 16
mov byte [edi+30h+nodeRealSize], 32
mov byte [edi+30h+nodeAllocatedSize], 32
2492,16 → 2406,18
mov byte [edi+40h+indexFlags], 2
add edi, 50h
mov al, 3
.end:
@@:
mov esi, [ebp+NTFS.frs_buffer]
mov dword [edi], -1
mov dword [edi+4], 0
add edi, 8
sub edi, esi
mov [ebp+NTFS.cur_buf], esi
mov [ebp+NTFS.ntfs_cur_buf], esi
mov [esi+recordFlags], al
mov [esi+recordRealSize], edi
call writeRecord
test eax, eax
jnz ntfsDevice
; write MFT bitmap
mov eax, [ebp+NTFS.newMftRecord]
shr eax, 3+9
2512,14 → 2428,37
mov ecx, 1
xor edx, edx
call fs_write64_sys
test eax, eax
jnz ntfsDevice
; 5. Write partition bitmap
cmp [ebp+NTFS.ntfsFolder], 1
jz @f
mov eax, [ebp+NTFS.fileDataStart]
mov ecx, [ebp+NTFS.fileDataSize]
test ecx, ecx
jz @f
add ecx, eax
add ecx, 4095
shr ecx, 3+9
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
test eax, eax
jnz ntfsDevice
@@:
mov edi, [ebp+NTFS.indexOffset]
mov eax, [ebp+NTFS.newMftRecord]
mov [edi+fileRecordReference], eax
; 5. Write directory node
; 6. Write directory node
mov eax, [ebp+NTFS.nodeLastRead]
mov [ebp+NTFS.LastRead], eax
mov [ebp+NTFS.ntfsLastRead], eax
mov eax, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.cur_buf], eax
mov [ebp+NTFS.ntfs_cur_buf], eax
call writeRecord
mov ebx, [ebp+NTFS.fileRealSize]
ntfsDone:
2532,9 → 2471,9
writeRecord:
; make updateSequence and write to disk
; in:
; [ebp+NTFS.cur_buf] -> record
; [ebp+NTFS.LastRead] = partition sector
mov esi, [ebp+NTFS.cur_buf]
; [ebp+NTFS.ntfs_cur_buf] -> record
; [ebp+NTFS.ntfsLastRead] = partition sector
mov esi, [ebp+NTFS.ntfs_cur_buf]
mov edi, esi
movzx ecx, word [esi+updateSequenceOffset]
add edi, ecx
2550,8 → 2489,8
mov [esi-2], ax
dec ecx
jnz @b
mov eax, [ebp+NTFS.LastRead]
mov ebx, [ebp+NTFS.cur_buf]
mov eax, [ebp+NTFS.ntfsLastRead]
mov ebx, [ebp+NTFS.ntfs_cur_buf]
pop ecx
xor edx, edx
jmp fs_write64_sys
2620,15 → 2559,15
resizeAttribute:
; in:
; [ebp+NTFS.frs_buffer] -> file record
; [ebp+NTFS.attr_offs] -> attribute
; [ebp+NTFS.ntfs_attr_offs] -> attribute
; edx:eax = new size
; out:
; [ebp+NTFS.fileDataSize] = clusters added (positive)
; [ebp+NTFS.fileDataStart] = added block
; CF=1 -> eax = error code
mov esi, [ebp+NTFS.attr_offs]
mov dword [ebp+NTFS.attr_size], eax
mov dword [ebp+NTFS.attr_size+4], edx
mov esi, [ebp+NTFS.ntfs_attr_offs]
mov dword [ebp+NTFS.ntfs_attr_size], eax
mov dword [ebp+NTFS.ntfs_attr_size+4], edx
cmp byte [esi+nonResidentFlag], 0
jz .resident
mov ecx, [ebp+NTFS.sectors_per_cluster]
2670,7 → 2609,7
shr edi, 5
shl edi, 2
push eax
cmp [ebp+NTFS.cur_iRecord], 0
cmp [ebp+NTFS.ntfs_cur_iRecord], 0
jz @f
cmp edi, [ebp+NTFS.BitmapStart]
jc .err1
2677,7 → 2616,6
@@:
call ntfsSpaceAlloc
jc .err1
mov eax, [ebp+NTFS.fileDataStart]
pop edi
pop edx
cmp edx, eax
2698,25 → 2636,46
sub eax, edx
mov [ebp+NTFS.fileDataStart], eax
@@:
mov esi, [ebp+NTFS.attr_offs]
mov esi, [ebp+NTFS.ntfs_attr_offs]
call createMcbEntry
pop [ebp+NTFS.fileDataSize]
pop [ebp+NTFS.fileDataStart]
movi eax, ERROR_UNSUPPORTED_FS
pop ecx
pop eax
jc .err2
mov [ebp+NTFS.fileDataSize], ecx
mov [ebp+NTFS.fileDataStart], eax
.writeBitmap:
add ecx, eax
add ecx, 4095
shr ecx, 3+9
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
test eax, eax
jnz @f
.done:
ret
 
.err4:
pop eax
@@:
movi eax, ERROR_DEVICE
stc
ret
 
.err1:
add esp, 24
stc
.err2:
.err10:
movi eax, ERROR_DISK_FULL
ret
 
.err3:
movi eax, ERROR_FS_FAIL
add esp, 20
stc
.err2:
movi eax, ERROR_UNSUPPORTED_FS
ret
 
.shrinkAttribute:
2757,12 → 2716,18
pop edi
cmp [ebp+NTFS.fileDataSize], 0
jz @f
mov esi, [ebp+NTFS.attr_offs]
mov esi, [ebp+NTFS.ntfs_attr_offs]
call createMcbEntry
mov [ebp+NTFS.fileDataSize], 0
@@:
ret
 
.err3:
movi eax, ERROR_FS_FAIL
add esp, 20
stc
ret
 
.resident:
test edx, edx
jnz .nonResident
2795,9 → 2760,9
xor eax, eax
rep stosd
cld
mov esi, [ebp+NTFS.attr_offs]
mov esi, [ebp+NTFS.ntfs_attr_offs]
@@:
mov eax, dword [ebp+NTFS.attr_size]
mov eax, dword [ebp+NTFS.ntfs_attr_size]
mov [esi+sizeWithoutHeader], eax
mov [ebp+NTFS.fileDataSize], 0
clc
2804,7 → 2769,7
ret
 
.nonResident: ; convert resident to non-resident
mov eax, dword [ebp+NTFS.attr_size]
mov eax, dword [ebp+NTFS.ntfs_attr_size]
sub eax, 1
sbb edx, 0
mov ecx, [ebp+NTFS.sectors_per_cluster]
2816,8 → 2781,9
push ecx
call ntfsSpaceAlloc
pop ecx
jc .err2
mov esi, [ebp+NTFS.attr_offs]
jc .err10
mov [ebp+NTFS.fileDataStart], eax
mov esi, [ebp+NTFS.ntfs_attr_offs]
xor eax, eax
xor edx, edx
@@:
2844,22 → 2810,26
pop ecx
shr ecx, 9
call fs_write64_app
stdcall kernel_free, ebx
mov esi, [ebp+NTFS.attr_offs]
push ebx
mov ebx, eax
call kernel_free
test ebx, ebx
jnz .err4
mov esi, [ebp+NTFS.ntfs_attr_offs]
add esi, [esi+sizeWithHeader]
mov ecx, [ebp+NTFS.frs_buffer]
add ecx, [ecx+recordRealSize]
sub ecx, esi
shr ecx, 2
lea edi, [ebp+NTFS.bitmap_buf]
lea edi, [ebp+NTFS.ntfs_bitmap_buf]
push ecx
rep movsd
mov edi, [ebp+NTFS.attr_offs]
mov edi, [ebp+NTFS.ntfs_attr_offs]
add edi, 16
mov cl, 6
xor eax, eax
rep stosd
mov edi, [ebp+NTFS.attr_offs]
mov edi, [ebp+NTFS.ntfs_attr_offs]
mov eax, [ebp+NTFS.fileDataSize]
dec eax
mov [edi+lastVCN], eax
2872,8 → 2842,8
mov byte [edi+dataRunsOffset], 40h
mov [edi+attributeAllocatedSize], eax
mov [edi+attributeAllocatedSize+4], edx
mov eax, dword [ebp+NTFS.attr_size]
mov edx, dword [ebp+NTFS.attr_size+4]
mov eax, dword [ebp+NTFS.ntfs_attr_size]
mov edx, dword [ebp+NTFS.ntfs_attr_size+4]
mov [edi+attributeRealSize], eax
mov [edi+attributeRealSize+4], edx
mov [edi+initialDataSize], eax
2882,13 → 2852,13
add edi, 40h
call createMcbEntry
mov eax, edi
mov edi, [ebp+NTFS.attr_offs]
mov edi, [ebp+NTFS.ntfs_attr_offs]
sub eax, edi
add eax, 8
and eax, not 7
mov [edi+sizeWithHeader], eax
pop ecx
lea esi, [ebp+NTFS.bitmap_buf]
lea esi, [ebp+NTFS.ntfs_bitmap_buf]
add edi, eax
rep movsd
mov esi, [ebp+NTFS.frs_buffer]
2895,9 → 2865,11
sub edi, esi
mov [esi+recordRealSize], edi
pop edx
mov ecx, [ebp+NTFS.fileDataSize]
sub [ebp+NTFS.fileDataSize], edx
mov eax, [ebp+NTFS.fileDataStart]
add [ebp+NTFS.fileDataStart], edx
ret
jmp .writeBitmap
 
.makeResident: ; convert non-resident to empty resident
movzx eax, byte [esi+dataRunsOffset]
2946,7 → 2918,7
rep stosd
mov eax, [ebp+NTFS.fileDataStart]
mul [ebp+NTFS.sectors_per_cluster]
mov [ebp+NTFS.LastRead], eax
mov [ebp+NTFS.ntfsLastRead], eax
pop ecx
call fs_write64_app
stdcall kernel_free, ebx
2954,14 → 2926,13
ret
 
ntfsSpaceAlloc:
; allocate disk space
; find and mark block of free space in bitmap buffer
; in:
; edi = offset in bitmap to start search from
; [ebp+NTFS.fileDataSize] = block size in clusters
; out:
; [ebp+NTFS.fileDataStart] = allocated block starting cluster
; eax = allocated block starting cluster
; CF=1 -> disk full
push eax
mov ecx, [ebp+NTFS.BitmapBuffer]
add edi, ecx
add ecx, [ebp+NTFS.BitmapSize]
2974,7 → 2945,7
mov eax, [ebp+NTFS.fileDataSize]
shr eax, 5
jz .small
mov ebx, eax ; bitmap dwords
push eax ; bitmap dwords
.start:
mov ecx, [ebp+NTFS.BitmapBuffer]
add ecx, [ebp+NTFS.BitmapSize]
2987,13 → 2958,13
call bitmapBuffering
jmp @b
@@:
cmp ecx, ebx
cmp ecx, [esp]
jnc @f
call bitmapBuffering
jmp @b
@@:
sub edi, 4
mov ecx, ebx
mov ecx, [esp]
mov esi, edi
xor eax, eax
repz scasd ; check following dwords
3026,9 → 2997,11
.small: ; less than 32 clusters
mov eax, -1
repz scasd ; search for zero bits
push ecx
test ecx, ecx
jnz @f
call bitmapBuffering
pop eax
jmp .small
@@:
sub edi, 4
3035,7 → 3008,7
mov eax, [edi]
not eax
@@:
bsf ebx, eax ; first 0
bsf ecx, eax ; first 0
jz .again
not eax
shr eax, cl
3042,10 → 3015,10
shl eax, cl
bsf edx, eax ; next 1
jz @f
sub edx, ebx
sub edx, ecx
cmp edx, [ebp+NTFS.fileDataSize]
jnc .got ; fits inside
bsf ebx, eax
bsf ecx, eax
not eax
shr eax, cl
shl eax, cl
3055,15 → 3028,16
bsf edx, eax
jz .got ; empty
add edx, 32
sub edx, ebx
sub edx, ecx
cmp edx, [ebp+NTFS.fileDataSize]
jnc .got ; share between dwords
.again:
add edi, 4
pop ecx
jmp .small
 
.got:
push ebx ; starting bit
push ecx ; starting bit
push edi ; starting dword
.done: ; mark space
mov ecx, [esp+4]
3104,24 → 3078,12
or [edi], eax
.end:
pop eax
pop ecx
sub eax, [ebp+NTFS.BitmapBuffer]
shl eax, 3
add eax, ecx
pop ecx
mov ecx, [ebp+NTFS.fileDataSize]
mov [ebp+NTFS.fileDataStart], eax
add ecx, eax
add ecx, 4095
shr ecx, 3+9
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
jmp fs_write64_app
pop edx
add eax, edx
pop edx
ret
 
ntfsSpaceFree:
; free disk space
3236,7 → 3198,9
mov ecx, 8
call release_pages
.end:
add esp, 12 ; ret
pop ebx
pop eax ; ret
pop eax
stc
ret
 
3251,11 → 3215,11
call ntfs_lock
stdcall ntfs_find_lfn, [esp+4]
jc ntfsNotFound
cmp [ebp+NTFS.cur_iRecord], 16
cmp [ebp+NTFS.ntfs_cur_iRecord], 16
jc ntfsDenied
bt dword [eax+fileFlags], 28
jc ntfsDenied
cmp [ebp+NTFS.fragmentCount], 1
cmp [ebp+NTFS.ntfsFragmentCount], 1
jnz ntfsUnsupported ; record fragmented
; edit directory node
mov edi, [ebp+NTFS.cur_index_buf]
3265,7 → 3229,7
mov ecx, [esi+recordRealSize]
shr ecx, 2
rep movsd
mov esi, [ebp+NTFS.attr_offs]
mov esi, [ebp+NTFS.ntfs_attr_offs]
mov cl, [esi+attributeOffset]
sub esi, [ebp+NTFS.frs_buffer]
add eax, ecx
3277,11 → 3241,11
adc edx, 0
mov [eax+fileRealSize], ecx
mov [eax+fileRealSize+4], edx
mov eax, [ebp+NTFS.LastRead]
mov eax, [ebp+NTFS.ntfsLastRead]
mov [ebp+NTFS.nodeLastRead], eax
mov [ebp+NTFS.cur_attr], 0x80
mov [ebp+NTFS.cur_offs], 0
mov [ebp+NTFS.cur_size], 0
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 ntfsFail
mov eax, ecx
3288,7 → 3252,7
mov ecx, [ebp+NTFS.frs_buffer]
cmp word [ecx+baseRecordReuse], 0
jnz ntfsUnsupported ; auxiliary record
mov ecx, [ebp+NTFS.attr_offs]
mov ecx, [ebp+NTFS.ntfs_attr_offs]
cmp word [ecx+attributeFlags], 0
jnz ntfsUnsupported
push ebx
3302,7 → 3266,7
.resizeAttribute:
call resizeAttribute
jc ntfsErrorPop
mov ecx, [ebp+NTFS.attr_offs]
mov ecx, [ebp+NTFS.ntfs_attr_offs]
cmp byte [ecx+nonResidentFlag], 1
jz @f
mov ebx, [esp]
3314,18 → 3278,18
rep movsb
@@:
mov eax, [ebp+NTFS.frs_buffer]
mov [ebp+NTFS.cur_buf], eax
mov [ebp+NTFS.ntfs_cur_buf], eax
call writeRecord ; file
mov ebx, [ebp+NTFS.frs_buffer]
call ntfs_restore_usa_frs
.writeNode:
mov eax, [ebp+NTFS.nodeLastRead]
mov [ebp+NTFS.LastRead], eax
mov [ebp+NTFS.ntfsLastRead], eax
mov eax, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.cur_buf], eax
mov [ebp+NTFS.ntfs_cur_buf], eax
call writeRecord ; directory
pop ebx
mov ecx, [ebp+NTFS.attr_offs]
mov ecx, [ebp+NTFS.ntfs_attr_offs]
cmp byte [ecx+nonResidentFlag], 0
jz .done
mov ecx, [ebx+12]
3337,16 → 3301,16
shrd eax, edx, 9
test dword[ebx+4], 1FFh
jz .aligned
mov [ebp+NTFS.cur_offs], eax
mov [ebp+NTFS.cur_size], 1
lea edi, [ebp+NTFS.bitmap_buf]
mov [ebp+NTFS.cur_buf], edi
mov [ebp+NTFS.ntfs_cur_offs], eax
mov [ebp+NTFS.ntfs_cur_size], 1
lea edi, [ebp+NTFS.ntfs_bitmap_buf]
mov [ebp+NTFS.ntfs_cur_buf], edi
call ntfs_read_attr.continue
jc ntfsDevice
mov eax, [ebx+4]
and eax, 1FFh
add edi, eax
sub eax, [ebp+NTFS.cur_read]
sub eax, [ebp+NTFS.ntfs_cur_read]
neg eax
push ecx
cmp ecx, eax
3356,8 → 3320,8
sub [esp], ecx
rep movsb
push ebx
mov eax, [ebp+NTFS.LastRead]
lea ebx, [ebp+NTFS.bitmap_buf]
mov eax, [ebp+NTFS.ntfsLastRead]
lea ebx, [ebp+NTFS.ntfs_bitmap_buf]
mov ecx, 1
xor edx, edx
call fs_write64_app
3372,29 → 3336,29
.aligned:
push ecx
shr ecx, 9
mov [ebp+NTFS.cur_offs], eax
mov [ebp+NTFS.cur_size], ecx
mov [ebp+NTFS.cur_buf], esi
mov [ebp+NTFS.ntfs_cur_offs], eax
mov [ebp+NTFS.ntfs_cur_size], ecx
mov [ebp+NTFS.ntfs_cur_buf], esi
add eax, ecx
push eax
mov [ebp+NTFS.bWriteAttr], 1
mov [ebp+NTFS.ntfsWriteAttr], 1
call ntfs_read_attr.continue
mov [ebp+NTFS.bWriteAttr], 0
pop [ebp+NTFS.cur_offs]
mov [ebp+NTFS.ntfsWriteAttr], 0
pop [ebp+NTFS.ntfs_cur_offs]
pop ecx
jc ntfsDevice
and ecx, 1FFh
jz .done
add esi, [ebp+NTFS.cur_read]
mov [ebp+NTFS.cur_size], 1
lea edi, [ebp+NTFS.bitmap_buf]
mov [ebp+NTFS.cur_buf], edi
add esi, [ebp+NTFS.ntfs_cur_read]
mov [ebp+NTFS.ntfs_cur_size], 1
lea edi, [ebp+NTFS.ntfs_bitmap_buf]
mov [ebp+NTFS.ntfs_cur_buf], edi
call ntfs_read_attr.continue
jc ntfsDevice
rep movsb
push ebx
mov eax, [ebp+NTFS.LastRead]
lea ebx, [ebp+NTFS.bitmap_buf]
mov eax, [ebp+NTFS.ntfsLastRead]
lea ebx, [ebp+NTFS.ntfs_bitmap_buf]
mov ecx, 1
xor edx, edx
call fs_write64_app
3414,13 → 3378,13
call ntfs_lock
stdcall ntfs_find_lfn, [esp+4]
jc ntfsNotFound
cmp [ebp+NTFS.cur_iRecord], 16
cmp [ebp+NTFS.ntfs_cur_iRecord], 16
jc ntfsDenied
cmp [ebp+NTFS.fragmentCount], 1
cmp [ebp+NTFS.ntfsFragmentCount], 1
jnz ntfsUnsupported ; record fragmented
test byte [eax+indexFlags], 1
jnz ntfsUnsupported ; index has a subnode
mov edx, [ebp+NTFS.cur_iRecord]
mov edx, [ebp+NTFS.ntfs_cur_iRecord]
shr edx, 3
cmp edx, [ebp+NTFS.mftBitmapSize]
jnc ntfsUnsupported
3439,7 → 3403,7
shr ecx, 2
rep movsd
mov esi, [ebp+NTFS.cur_index_buf]
mov edi, [ebp+NTFS.attr_offs]
mov edi, [ebp+NTFS.ntfs_attr_offs]
sub edi, [ebp+NTFS.frs_buffer]
add edi, esi
sub [edi+sizeWithHeader], edx
3446,8 → 3410,8
sub [edi+sizeWithoutHeader], edx
mov cl, [edi+attributeOffset]
add edi, ecx
sub [edi+rootNode+nodeRealSize], edx
sub [edi+rootNode+nodeAllocatedSize], edx
sub [edi+16+nodeRealSize], edx
sub [edi+16+nodeAllocatedSize], edx
sub eax, esi
add eax, edi
sub [esi+recordRealSize], edx
3455,10 → 3419,9
jmp @f
 
.indexRecord:
add edi, recordNode+nodeRealSize
sub [edi], edx
mov ecx, [edi]
add ecx, recordNode
sub [edi+28], edx
mov ecx, [edi+28]
add ecx, 24
@@:
add ecx, [ebp+NTFS.cur_index_buf]
sub ecx, eax
3467,18 → 3430,18
add esi, edx
mov edi, eax
rep movsd
mov eax, [ebp+NTFS.LastRead]
mov eax, [ebp+NTFS.ntfsLastRead]
mov [ebp+NTFS.nodeLastRead], eax
; examine file record
mov [ebp+NTFS.cur_attr], 0x80
mov [ebp+NTFS.cur_offs], 0
mov [ebp+NTFS.cur_size], 0
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
mov esi, [ebp+NTFS.attr_offs]
mov esi, [ebp+NTFS.ntfs_attr_offs]
cmp byte [esi+nonResidentFlag], 0
jz .writeBitmapMFT
movzx eax, byte [esi+dataRunsOffset]
3499,18 → 3462,18
jmp .writeBitmapMFT
 
.folder: ; empty?
lea esi, [ebp+NTFS.bitmap_buf]
mov [ebp+NTFS.cur_buf], esi
mov [ebp+NTFS.cur_attr], 0x90
mov [ebp+NTFS.cur_offs], 0
mov [ebp+NTFS.cur_size], 1
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.cur_read], 48
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.cur_iRecord]
mov eax, [ebp+NTFS.ntfs_cur_iRecord]
mov ecx, eax
shr eax, 3
and ecx, 7
3525,14 → 3488,14
xor edx, edx
call fs_write64_sys
mov esi, [ebp+NTFS.frs_buffer]
mov [ebp+NTFS.cur_buf], esi
mov [ebp+NTFS.ntfs_cur_buf], esi
mov byte [esi+recordFlags], 0
call writeRecord
; write directory node
mov eax, [ebp+NTFS.nodeLastRead]
mov [ebp+NTFS.LastRead], eax
mov [ebp+NTFS.ntfsLastRead], eax
mov eax, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.cur_buf], eax
mov [ebp+NTFS.ntfs_cur_buf], eax
call writeRecord
jmp ntfsDone
 
3547,11 → 3510,11
call ntfs_lock
stdcall ntfs_find_lfn, [esp+4]
jc ntfsNotFound
cmp [ebp+NTFS.cur_iRecord], 16
cmp [ebp+NTFS.ntfs_cur_iRecord], 16
jc ntfsDenied
bt dword [eax+fileFlags], 28
jc ntfsDenied
cmp [ebp+NTFS.fragmentCount], 1
cmp [ebp+NTFS.ntfsFragmentCount], 1
jnz ntfsUnsupported ; record fragmented
; edit directory node
mov edi, [ebp+NTFS.cur_index_buf]
3561,7 → 3524,7
mov ecx, [esi+recordRealSize]
shr ecx, 2
rep movsd
mov esi, [ebp+NTFS.attr_offs]
mov esi, [ebp+NTFS.ntfs_attr_offs]
mov cl, [esi+attributeOffset]
sub esi, [ebp+NTFS.frs_buffer]
add eax, ecx
3571,11 → 3534,11
mov edx, [ebx+8]
mov [eax+fileRealSize], ecx
mov [eax+fileRealSize+4], edx
mov eax, [ebp+NTFS.LastRead]
mov eax, [ebp+NTFS.ntfsLastRead]
mov [ebp+NTFS.nodeLastRead], eax
mov [ebp+NTFS.cur_attr], 0x80
mov [ebp+NTFS.cur_offs], 0
mov [ebp+NTFS.cur_size], 0
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 ntfsFail
mov eax, ecx
3582,7 → 3545,7
mov ecx, [ebp+NTFS.frs_buffer]
cmp word [ecx+baseRecordReuse], 0
jnz ntfsUnsupported ; auxiliary record
mov ecx, [ebp+NTFS.attr_offs]
mov ecx, [ebp+NTFS.ntfs_attr_offs]
cmp word [ecx+attributeFlags], 0
jnz ntfsUnsupported
cmp byte [ecx+nonResidentFlag], 0
3593,7 → 3556,7
jnc .resizeAttribute
mov eax, [ecx+attributeRealSize]
mov ecx, [ebp+NTFS.sectors_per_cluster]
mov [ebp+NTFS.cur_size], ecx
mov [ebp+NTFS.ntfs_cur_size], ecx
shl ecx, 9
div ecx
test edx, edx
3601,28 → 3564,28
push edx
push ecx
mul [ebp+NTFS.sectors_per_cluster]
mov [ebp+NTFS.cur_offs], eax
mov [ebp+NTFS.ntfs_cur_offs], eax
stdcall kernel_alloc, ecx
pop ecx
pop edi
sub ecx, edi
add edi, eax
mov [ebp+NTFS.cur_buf], eax
push [ebp+NTFS.LastRead]
mov [ebp+NTFS.ntfs_cur_buf], eax
push [ebp+NTFS.ntfsLastRead]
call ntfs_read_attr.continue
jc @f
xor eax, eax
rep stosb
push ebx
mov eax, [ebp+NTFS.LastRead]
mov ebx, [ebp+NTFS.cur_buf]
mov eax, [ebp+NTFS.ntfsLastRead]
mov ebx, [ebp+NTFS.ntfs_cur_buf]
mov ecx, [ebp+NTFS.sectors_per_cluster]
xor edx, edx
call fs_write64_app
pop ebx
@@:
pop [ebp+NTFS.LastRead]
stdcall kernel_free, [ebp+NTFS.cur_buf]
pop [ebp+NTFS.ntfsLastRead]
stdcall kernel_free, [ebp+NTFS.ntfs_cur_buf]
.aligned:
mov eax, [ebx+4]
mov edx, [ebx+8]
3630,12 → 3593,12
call resizeAttribute
jc ntfsError
mov eax, [ebp+NTFS.frs_buffer]
mov [ebp+NTFS.cur_buf], eax
mov [ebp+NTFS.ntfs_cur_buf], eax
call writeRecord ; file
mov eax, [ebp+NTFS.nodeLastRead]
mov [ebp+NTFS.LastRead], eax
mov [ebp+NTFS.ntfsLastRead], eax
mov eax, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.cur_buf], eax
mov [ebp+NTFS.ntfs_cur_buf], eax
call writeRecord ; directory
call ntfsSpaceClean
jmp ntfsDone
/kernel/branches/Kolibri-acpi/fs/fat.inc
1228,7 → 1228,117
lea ecx, [ebp+FAT.Lock]
jmp mutex_unlock
 
; \begin{diamond}
uni2ansi_str:
; convert UNICODE zero-terminated string to ASCII-string (codepage 866)
; in: esi->source, edi->buffer (may be esi=edi)
; destroys: eax,esi,edi
lodsw
test ax, ax
jz .done
cmp ax, 0x80
jb .ascii
cmp ax, 0x401
jz .yo1
cmp ax, 0x451
jz .yo2
cmp ax, 0x410
jb .unk
cmp ax, 0x440
jb .rus1
cmp ax, 0x450
jb .rus2
.unk:
mov al, '_'
jmp .doit
.yo1:
mov al, 0xF0 ; 'Ё'
jmp .doit
.yo2:
mov al, 0xF1 ; 'ё'
jmp .doit
.rus1:
; 0x410-0x43F -> 0x80-0xAF
add al, 0x70
jmp .doit
.rus2:
; 0x440-0x44F -> 0xE0-0xEF
add al, 0xA0
.ascii:
.doit:
stosb
jmp uni2ansi_str
.done:
mov byte [edi], 0
ret
 
ansi2uni_char:
; convert ANSI character in al to UNICODE character in ax, using cp866 encoding
mov ah, 0
; 0x00-0x7F - trivial map
cmp al, 0x80
jb .ret
; 0x80-0xAF -> 0x410-0x43F
cmp al, 0xB0
jae @f
add ax, 0x410-0x80
.ret:
ret
@@:
; 0xE0-0xEF -> 0x440-0x44F
cmp al, 0xE0
jb .unk
cmp al, 0xF0
jae @f
add ax, 0x440-0xE0
ret
; 0xF0 -> 0x401
; 0xF1 -> 0x451
@@:
cmp al, 0xF0 ; 'Ё'
jz .yo1
cmp al, 0xF1 ; 'ё'
jz .yo2
.unk:
mov al, '_' ; ah=0
ret
.yo1:
mov ax, 0x401
ret
.yo2:
mov ax, 0x451
ret
 
char_toupper:
; convert character to uppercase, using cp866 encoding
; in: al=symbol
; out: al=converted symbol
cmp al, 'a'
jb .ret
cmp al, 'z'
jbe .az
cmp al, 0xF1 ; 'ё'
jz .yo1
cmp al, 0xA0 ; 'а'
jb .ret
cmp al, 0xE0 ; 'р'
jb .rus1
cmp al, 0xEF ; 'я'
ja .ret
; 0xE0-0xEF -> 0x90-0x9F
sub al, 0xE0-0x90
.ret:
ret
.rus1:
; 0xA0-0xAF -> 0x80-0x8F
.az:
and al, not 0x20
ret
.yo1:
; 0xF1 -> 0xF0
dec ax
ret
 
fat_get_name:
; in: edi->FAT entry
; out: CF=1 - no valid entry
3641,3 → 3751,5
pop edi
xor eax, eax
ret
 
; \end{diamond}
/kernel/branches/Kolibri-acpi/fs/iso9660.inc
831,3 → 831,81
inc esi
clc
ret
;-----------------------------------------------------------------------------
char_todown:
; convert character to uppercase, using cp866 encoding
; in: al=symbol
; out: al=converted symbol
cmp al, 'A'
jb .ret
 
cmp al, 'Z'
jbe .az
 
cmp al, 0x80 ; 'А'
jb .ret
 
cmp al, 0x90 ; 'Р'
jb .rus1
 
cmp al, 0x9F ; 'Я'
ja .ret
; 0x90-0x9F -> 0xE0-0xEF
add al, 0xE0-0x90
;--------------------------------------
.ret:
ret
;--------------------------------------
.rus1:
; 0x80-0x8F -> 0xA0-0xAF
.az:
add al, 0x20
ret
;-----------------------------------------------------------------------------
uni2ansi_char:
; convert UNICODE character in al to ANSI character in ax, using cp866 encoding
; in: ax=UNICODE character
; out: al=converted ANSI character
cmp ax, 0x80
jb .ascii
 
cmp ax, 0x401
jz .yo1
 
cmp ax, 0x451
jz .yo2
 
cmp ax, 0x410
jb .unk
 
cmp ax, 0x440
jb .rus1
 
cmp ax, 0x450
jb .rus2
;--------------------------------------
.unk:
mov al, '_'
jmp .doit
;--------------------------------------
.yo1:
mov al, 0xF0 ; 'Ё' in cp866
jmp .doit
;--------------------------------------
.yo2:
mov al, 0xF1 ; 'ё' in cp866
jmp .doit
;--------------------------------------
.rus1:
; 0x410-0x43F -> 0x80-0xAF
add al, 0x70
jmp .doit
;--------------------------------------
.rus2:
; 0x440-0x44F -> 0xE0-0xEF
add al, 0xA0
;--------------------------------------
.ascii:
.doit:
ret
;-----------------------------------------------------------------------------
/kernel/branches/Kolibri-acpi/fs/parse_fn.inc
5,6 → 5,15
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;-------------------------------------------------------------------------
;
; File path partial substitution (according to configuration)
;
;
; SPraid
;
;-------------------------------------------------------------------------
 
$Revision$
 
 
236,158 → 245,3
stc
ret
endp
 
 
char_todown:
; convert character in al to downcase, using cp866 encoding
cmp al, 'A'
jb .ret
cmp al, 'Z'
jbe .az
cmp al, 0x80 ; 'А'
jb .ret
cmp al, 0x90 ; 'Р'
jb .rus
cmp al, 0xF0 ; 'Ё'
jz .yo
cmp al, 0x9F ; 'Я'
ja .ret
; 0x90-0x9F -> 0xE0-0xEF
add al, 0xE0-0x90
.ret:
ret
 
.az:
.rus: ; 0x80-0x8F -> 0xA0-0xAF
add al, 0x20
ret
 
.yo:
inc al
ret
 
 
char_toupper:
; convert character in al to uppercase, using cp866 encoding
cmp al, 'a'
jb .ret
cmp al, 'z'
jbe .az
cmp al, 0xA0 ; 'а'
jb .ret
cmp al, 0xE0 ; 'р'
jb .rus
cmp al, 0xF1 ; 'ё'
jz .yo
cmp al, 0xEF ; 'я'
ja .ret
; 0xE0-0xEF -> 0x90-0x9F
sub al, 0xE0-0x90
.ret:
ret
 
.az:
.rus: ; 0xA0-0xAF -> 0x80-0x8F
and al, not 0x20
ret
 
.yo:
dec al
ret
 
 
uni2ansi_str:
; convert UNICODE zero-terminated string to ASCII-string (codepage 866)
; in: esi->source, edi->buffer (may be esi=edi)
; destroys: eax,esi,edi
lodsw
call uni2ansi_char
stosb
test al, al
jnz uni2ansi_str
ret
 
 
uni2ansi_char:
; convert UNICODE character in ax to ANSI character in al using cp866 encoding
cmp ax, 0x80
jb .ret
cmp ax, 0xB6
jz .B6
cmp ax, 0x400
jb .unk
cmp ax, 0x410
jb @f
cmp ax, 0x440
jb .rus1
cmp ax, 0x450
jb .rus2
cmp ax, 0x460
jb @f
.unk:
mov al, '_'
.ret:
ret
 
.B6:
mov al, 20
ret
 
.rus1: ; 0x410-0x43F -> 0x80-0xAF
add al, 0x70
ret
 
.rus2: ; 0x440-0x44F -> 0xE0-0xEF
add al, 0xA0
ret
 
@@:
push ecx edi
mov ecx, 8
mov edi, .table
repnz scasb
mov ah, cl
pop edi ecx
jnz .unk
mov al, 0xF7
sub al, ah
ret
 
.table db 1, 51h, 4, 54h, 7, 57h, 0Eh, 5Eh
 
 
ansi2uni_char:
; convert ANSI character in al to UNICODE character in ax, using cp866 encoding
movzx eax, al
cmp al, 0x80
jb @f ; 0x00-0x7F - trivial map
cmp al, 0xB0
jb .rus ; 0x80-0xAF -> 0x410-0x43F
cmp al, 0xE0
jb .unk
cmp al, 0xF0
jb .rus2 ; 0xE0-0xEF -> 0x440-0x44F
cmp al, 0xF8
jnc .unk
mov al, [eax+uni2ansi_char.table-0xF0]
add ax, 400h
ret
 
@@:
cmp al, 20
jnz .ret
mov al, 0xB6
.ret:
ret
 
.rus:
add ax, 0x410-0x80
ret
 
.rus2:
add ax, 0x440-0xE0
ret
 
.unk:
mov al, '_'
ret
/kernel/branches/Kolibri-acpi/boot/shutdown.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2016. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; Shutdown for Menuet ;;