Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 6310 → Rev 6311

/kernel/branches/Kolibri-acpi/boot/shutdown.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2016. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; Shutdown for Menuet ;;
/kernel/branches/Kolibri-acpi/data32.inc
173,7 → 173,6
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-2012. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2016. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2104,12 → 2104,16
* бит 31 установлен = не выводить ведущие нули числа
* ecx = число (при bl=0) или указатель (при bl=1)
* edx = [координата по оси x]*65536 + [координата по оси y]
* esi = 0xX0RRGGBB:
* RR, GG, BB задают цвет
* X = ABnn (биты)
* nn = шрифт (0/1)
* A игнорируется
* B=1 - закрашивать фон цветом edi
* 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
Возвращаемое значение:
* функция не возвращает значения
Замечания:
2118,7 → 2122,6
может быть записано меньшим количеством цифр, оно дополняется
ведущими нулями; если число велико и не может быть записано
таким количеством цифр, "лишние" ведущие цифры обрезаются.
* Параметры шрифтов указаны в описании функции 4 (вывода текста).
 
---------------------- Константы для регистров: ----------------------
eax - SF_DRAW_NUMBER (47)
/kernel/branches/Kolibri-acpi/docs/sysfuncs.txt
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2016. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2081,12 → 2081,16
* 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 = 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
* 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
Returned value:
* function does not return value
Remarks:
2095,8 → 2099,6
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/fat.inc
1228,117 → 1228,7
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
3751,5 → 3641,3
pop edi
xor eax, eax
ret
 
; \end{diamond}
/kernel/branches/Kolibri-acpi/fs/iso9660.inc
831,81 → 831,3
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/ntfs.inc
29,8 → 29,10
 
; Offsets:
; record header
magic = 0
updateSequenceOffset = 4
updateSequenceSize = 6
; FileRecord header
reuseCounter = 16
hardLinkCounter = 12h
attributeOffset = 14h
50,7 → 52,7
attributeID = 14
; resident attribute header
sizeWithoutHeader = 10h
; attributeOffset = 14h
attributeOffset = 14h
indexedFlag = 16h
; non resident attribute header
firstVCN = 10h
60,13 → 62,19
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
75,10 → 83,16
indexFlags = 12
directoryRecordReference = 16
directoryReferenceReuse = 16h
fileCreated = 18h
fileModified = 20h
recordModified = 28h
fileAccessed = 30h
fileAllocatedSize = 38h
fileRealSize = 40h
fileFlags = 48h
fileNameLength = 50h
namespace = 51h
fileName = 52h
 
struct NTFS PARTITION
Lock MUTEX ? ; Currently operations with one partition
103,35 → 117,36
mftBitmapSize dd ? ; bytes readen
mftBitmapLocation dd ? ; starting sector
 
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
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
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 ?
ntfs_bCanContinue db ?
ntfsFolder db ?
ntfsWriteAttr db ? ; Warning: Don't forget to turn off!!!
ntfsFragmentCount db ?
fragmentCount db ?
bCanContinue db ?
bFolder db ?
bWriteAttr db ? ; Warning: Don't forget to turn off!!!
 
cur_subnode_size 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 ?
attr_iRecord dd ?
attr_iBaseRecord dd ?
attr_offs dd ?
attr_list dd ?
attr_size dq ?
cur_tail dd ?
 
ntfs_attrlist_buf rb 0x400
ntfs_attrlist_mft_buf rb 0x400
ntfs_bitmap_buf rb 0x400
attrlist_buf rb 0x400
attrlist_mft_buf rb 0x400
bitmap_buf rb 0x400
ends
 
; NTFS external functions
266,6 → 281,7
.nope:
xor eax, eax
jmp .exit
 
; By given bootsector, initialize some NTFS variables
.ntfs_setup:
movi eax, sizeof.NTFS
279,7 → 295,7
mov ecx, [ebp+PARTITION.Disk]
mov [eax+NTFS.Disk], ecx
mov [eax+NTFS.FSUserFunctions], ntfs_user_functions
mov [eax+NTFS.ntfsWriteAttr], 0
mov [eax+NTFS.bWriteAttr], 0
 
push ebx ebp esi
mov ebp, eax
300,6 → 316,7
mul [ebp+NTFS.sectors_per_cluster]
shl eax, 9
jmp .1
 
@@:
neg eax
mov ecx, eax
355,6 → 372,7
@@:
add eax, [eax+4]
jmp .scandata
 
.founddata:
cmp byte [eax+8], 0
jz .fail_free_mft
375,6 → 393,7
mov [eax+4], edx
inc [ebp+NTFS.mft_retrieval_size]
jmp .scanmcb
 
.scanmcbend:
add esp, 10h
; there may be other portions of $DATA attribute in auxiliary records;
397,7 → 416,7
test eax, eax
jz .failFreeIndex
mov [ebp+NTFS.BitmapBuffer], eax
mov [ebp+NTFS.ntfs_cur_buf], eax
mov [ebp+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
409,7 → 428,7
push eax
push eax
shl eax, 3
mov [ebp+NTFS.ntfs_cur_size], eax
mov [ebp+NTFS.cur_size], eax
call alloc_pages
test eax, eax
pop ecx
417,36 → 436,36
add eax, 3
mov ebx, [ebp+NTFS.BitmapBuffer]
call commit_pages
mov [ebp+NTFS.ntfs_cur_iRecord], 6
mov [ebp+NTFS.ntfs_cur_attr], 0x80
mov [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.cur_iRecord], 6
mov [ebp+NTFS.cur_attr], 0x80
mov [ebp+NTFS.cur_offs], 0
call ntfs_read_attr
jc .failFreeBitmap
mov eax, [ebp+NTFS.ntfs_cur_read]
mov eax, [ebp+NTFS.cur_read]
mov [ebp+NTFS.BitmapSize], eax
mov eax, [ebp+NTFS.ntfsLastRead]
mov eax, [ebp+NTFS.LastRead]
mov [ebp+NTFS.BitmapLocation], eax
; read MFT $BITMAP attribute
mov eax, [ebp+NTFS.sectors_per_cluster]
mov [ebp+NTFS.ntfs_cur_size], eax
mov [ebp+NTFS.cur_size], eax
shl eax, 9
stdcall kernel_alloc, eax
test eax, eax
jz .failFreeBitmap
mov [ebp+NTFS.mftBitmapBuffer], eax
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
mov [ebp+NTFS.cur_buf], eax
mov [ebp+NTFS.cur_iRecord], 0
mov [ebp+NTFS.cur_attr], 0xB0
mov [ebp+NTFS.cur_offs], 0
call ntfs_read_attr
mov eax, [ebp+NTFS.ntfs_cur_read]
mov eax, [ebp+NTFS.cur_read]
cmp eax, 4
jc .failFreeBitmapMFT
mov ecx, [ebp+NTFS.ntfs_attr_offs]
mov ecx, [ebp+NTFS.attr_offs]
cmp byte [ecx+nonResidentFlag], 1
jnz .failFreeBitmapMFT
mov [ebp+NTFS.mftBitmapSize], eax
mov eax, [ebp+NTFS.ntfsLastRead]
mov eax, [ebp+NTFS.LastRead]
mov [ebp+NTFS.mftBitmapLocation], eax
 
mov eax, ebp
489,6 → 508,7
popad
add esp, 14h
jmp .fail_free_mft
 
@@:
mov esi, [ebp+NTFS.mft_retrieval]
mov edi, eax
550,31 → 570,31
ret
 
ntfs_read_attr:
; [ebp+NTFS.ntfsWriteAttr]=1 -> write attribute
; [ebp+NTFS.bWriteAttr]=1 -> write attribute
; in:
; [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
; [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
; out:
; [ebp+NTFS.ntfs_cur_read] = bytes readen
; [ebp+NTFS.cur_read] = bytes readen
; CF=1 -> failed, eax = disk error code, eax=0 -> something with FS
xor eax, eax
pushad
and [ebp+NTFS.ntfs_cur_read], 0
cmp [ebp+NTFS.ntfs_cur_iRecord], 0
and [ebp+NTFS.cur_read], 0
cmp [ebp+NTFS.cur_iRecord], 0
jnz .nomft
cmp [ebp+NTFS.ntfs_cur_attr], 0x80
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.ntfs_cur_offs]
cmp eax, [ebp+NTFS.cur_offs]
jbe .nomft
; precalculated part of $Mft $DATA
mov esi, [ebp+NTFS.mft_retrieval]
mov eax, [ebp+NTFS.ntfs_cur_offs]
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
592,6 → 612,7
pop eax
jnz .mftscan
jmp .nomft
 
@@:
push ecx
add ecx, eax
603,15 → 624,15
; eax = sector on partition
pop edx
add eax, edx
mov ebx, [ebp+NTFS.ntfs_cur_buf]
mov ebx, [ebp+NTFS.cur_buf]
pop ecx
neg ecx
imul ecx, [ebp+NTFS.sectors_per_cluster]
sub ecx, edx
mov [ebp+NTFS.ntfsLastRead], eax
cmp ecx, [ebp+NTFS.ntfs_cur_size]
mov [ebp+NTFS.LastRead], eax
cmp ecx, [ebp+NTFS.cur_size]
jb @f
mov ecx, [ebp+NTFS.ntfs_cur_size]
mov ecx, [ebp+NTFS.cur_size]
@@:
; ecx = number of sequential sectors to read
push eax
619,17 → 640,17
pop edx
test eax, eax
jnz .errread
add [ebp+NTFS.ntfs_cur_read], 0x200
dec [ebp+NTFS.ntfs_cur_size]
inc [ebp+NTFS.ntfs_cur_offs]
add [ebp+NTFS.cur_read], 0x200
dec [ebp+NTFS.cur_size]
inc [ebp+NTFS.cur_offs]
add ebx, 0x200
mov [ebp+NTFS.ntfs_cur_buf], ebx
mov [ebp+NTFS.cur_buf], ebx
lea eax, [edx+1]
loop @b
pop ecx
xor eax, eax
xor edx, edx
cmp [ebp+NTFS.ntfs_cur_size], eax
cmp [ebp+NTFS.cur_size], eax
jz @f
add esi, 8
push eax
640,25 → 661,29
pop eax
jz .nomft
jmp .mftscan
@@:
popad
ret
 
.errret2_pop:
xor eax, eax
.errret_pop:
pop ecx
.errread:
pop ecx
.errret:
mov [esp+28], eax
stc
@@:
popad
ret
 
.nomft:
; 1. Read file record.
; N.B. This will do recursive call of read_attr for $MFT::$Data.
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
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
call ntfs_read_file_record
jc .errret
; 2. Find required attribute.
666,126 → 691,128
; a) For auxiliary records, read base record.
; If base record is present, base iRecord may be 0 (for $Mft),
; but SequenceNumber is nonzero.
cmp dword [eax+24h], 0
cmp word [eax+baseRecordReuse], 0
jz @f
mov eax, [eax+20h]
mov eax, [eax+baseRecordReference]
.beginfindattr:
mov [ebp+NTFS.ntfs_attr_iRecord], eax
mov [ebp+NTFS.attr_iRecord], eax
call ntfs_read_file_record
jc .errret
jmp @f
 
.newAttribute:
pushad
and [ebp+NTFS.cur_read], 0
@@:
; b) Scan for required attribute and for $ATTR_LIST
mov eax, [ebp+NTFS.frs_buffer]
movzx ecx, word [eax+14h]
movzx ecx, word [eax+attributeOffset]
add eax, ecx
mov ecx, [ebp+NTFS.ntfs_cur_attr]
and [ebp+NTFS.ntfs_attr_offs], 0
mov ecx, [ebp+NTFS.cur_attr]
and [ebp+NTFS.attr_offs], 0
.scanattr:
cmp dword [eax], -1
jz .scandone
cmp dword [eax], ecx
jz .okattr
cmp [ebp+NTFS.ntfs_attr_iBaseRecord], -1
cmp [ebp+NTFS.attr_iBaseRecord], -1
jnz .scancont
cmp dword [eax], 0x20 ; $ATTR_LIST
jnz .scancont
mov [ebp+NTFS.ntfs_attr_list], eax
mov [ebp+NTFS.attr_list], eax
jmp .scancont
 
.okattr:
; ignore named $DATA attributes (aka NTFS streams)
cmp ecx, 0x80
jnz @f
cmp byte [eax+9], 0
cmp byte [eax+nameLength], 0
jnz .scancont
@@:
mov [ebp+NTFS.ntfs_attr_offs], eax
mov [ebp+NTFS.attr_offs], eax
.scancont:
add eax, [eax+4]
add eax, [eax+sizeWithHeader]
jmp .scanattr
 
.continue:
pushad
and [ebp+NTFS.ntfs_cur_read], 0
and [ebp+NTFS.cur_read], 0
.scandone:
; c) Check for required offset and length
mov ecx, [ebp+NTFS.ntfs_attr_offs]
mov ecx, [ebp+NTFS.attr_offs]
jecxz .noattr
push [ebp+NTFS.ntfs_cur_size]
push [ebp+NTFS.ntfs_cur_read]
push [ebp+NTFS.cur_size]
push [ebp+NTFS.cur_read]
call .doreadattr
pop edx
pop ecx
jc @f
cmp [ebp+NTFS.ntfs_bCanContinue], 0
jz @f
sub edx, [ebp+NTFS.ntfs_cur_read]
jc .ret
cmp [ebp+NTFS.bCanContinue], 0
jz .ret
sub edx, [ebp+NTFS.cur_read]
neg edx
shr edx, 9
sub ecx, edx
mov [ebp+NTFS.ntfs_cur_size], ecx
jnz .not_in_cur
@@:
popad
ret
mov [ebp+NTFS.cur_size], ecx
jz .ret
.noattr:
.not_in_cur:
cmp [ebp+NTFS.ntfs_cur_attr], 0x20
cmp [ebp+NTFS.cur_attr], 0x20
jz @f
mov ecx, [ebp+NTFS.ntfs_attr_list]
mov ecx, [ebp+NTFS.attr_list]
test ecx, ecx
jnz .lookattr
.ret_is_attr:
and dword [esp+28], 0
cmp [ebp+NTFS.ntfs_attr_offs], 1 ; CF set <=> ntfs_attr_offs == 0
cmp [ebp+NTFS.attr_offs], 1 ; define CF
.ret:
popad
ret
 
.lookattr:
; required attribute or required offset was not found in base record;
; it may be present in auxiliary records;
; scan $ATTR_LIST
mov eax, [ebp+NTFS.ntfs_attr_iBaseRecord]
mov eax, [ebp+NTFS.attr_iBaseRecord]
cmp eax, -1
jz @f
call ntfs_read_file_record
jc .errret
or [ebp+NTFS.ntfs_attr_iBaseRecord], -1
or [ebp+NTFS.attr_iBaseRecord], -1
@@:
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
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
jnz @f
lea eax, [ebp+NTFS.ntfs_attrlist_mft_buf]
lea eax, [ebp+NTFS.attrlist_mft_buf]
@@:
mov [ebp+NTFS.ntfs_cur_buf], eax
mov [ebp+NTFS.cur_buf], eax
push eax
call .doreadattr
pop esi
mov edx, 1
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]
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]
jc .errret
or edi, -1
lea ecx, [ecx+esi-1Ah]
.scanliststart:
push ecx
mov eax, [ebp+NTFS.ntfs_cur_attr]
mov eax, [ebp+NTFS.cur_attr]
.scanlist:
cmp esi, [esp]
jae .scanlistdone
795,6 → 822,7
movzx ecx, word [esi+4]
add esi, ecx
jmp .scanlist
 
@@:
; ignore named $DATA attributes (aka NTFS streams)
cmp eax, 0x80
806,25 → 834,18
mov eax, [esi+8]
test eax, eax
jnz .testf
mov eax, dword [ebp+NTFS.ntfs_attr_size]
and eax, dword [ebp+NTFS.ntfs_attr_size+4]
mov eax, dword [ebp+NTFS.attr_size]
and eax, dword [ebp+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
jnc @f
.errret_pop:
pop ecx ecx
jmp .errret
.errret2_pop:
xor eax, eax
jmp .errret_pop
@@:
jc .errret_pop
mov eax, [ebp+NTFS.frs_buffer]
movzx ecx, word [eax+14h]
add eax, ecx
mov ecx, [ebp+NTFS.ntfs_cur_attr]
mov ecx, [ebp+NTFS.cur_attr]
@@:
cmp dword [eax], -1
jz .errret2_pop
833,6 → 854,7
.l1:
add eax, [eax+4]
jmp @b
 
@@:
cmp eax, 0x80
jnz @f
842,53 → 864,53
cmp byte [eax+8], 0
jnz .sdnores
mov eax, [eax+10h]
mov dword [ebp+NTFS.ntfs_attr_size], eax
and dword [ebp+NTFS.ntfs_attr_size+4], 0
mov dword [ebp+NTFS.attr_size], eax
and dword [ebp+NTFS.attr_size+4], 0
jmp .testfz
 
.sdnores:
mov ecx, [eax+30h]
mov dword [ebp+NTFS.ntfs_attr_size], ecx
mov dword [ebp+NTFS.attr_size], ecx
mov ecx, [eax+34h]
mov dword [ebp+NTFS.ntfs_attr_size+4], ecx
mov dword [ebp+NTFS.attr_size+4], ecx
.testfz:
xor eax, eax
.testf:
imul eax, [ebp+NTFS.sectors_per_cluster]
cmp eax, [ebp+NTFS.ntfs_cur_offs]
cmp eax, [ebp+NTFS.cur_offs]
pop eax
ja @f
mov edi, [esi+10h] ; keep previous iRecord
jmp .scanlistcont
 
@@:
pop ecx
.scanlistfound:
cmp edi, -1
jnz @f
popad
ret
@@:
mov eax, [ebp+NTFS.ntfs_cur_iRecord]
mov [ebp+NTFS.ntfs_attr_iBaseRecord], eax
jz .ret
mov eax, [ebp+NTFS.cur_iRecord]
mov [ebp+NTFS.attr_iBaseRecord], eax
mov eax, edi
jmp .beginfindattr
 
.scanlistdone:
pop ecx
sub ecx, ebp
sub ecx, NTFS.ntfs_attrlist_buf-1Ah
cmp [ebp+NTFS.ntfs_cur_iRecord], 0
sub ecx, NTFS.attrlist_buf-1Ah
cmp [ebp+NTFS.cur_iRecord], 0
jnz @f
sub ecx, NTFS.ntfs_attrlist_mft_buf-NTFS.ntfs_attrlist_buf
sub ecx, NTFS.attrlist_mft_buf-NTFS.attrlist_buf
@@:
cmp ecx, 0x400
jnz .scanlistfound
inc edx
push esi edi
lea esi, [ebp+NTFS.ntfs_attrlist_buf+0x200]
lea edi, [ebp+NTFS.ntfs_attrlist_buf]
cmp [ebp+NTFS.ntfs_cur_iRecord], 0
lea esi, [ebp+NTFS.attrlist_buf+0x200]
lea edi, [ebp+NTFS.attrlist_buf]
cmp [ebp+NTFS.cur_iRecord], 0
jnz @f
lea esi, [ebp+NTFS.ntfs_attrlist_mft_buf+0x200]
lea edi, [ebp+NTFS.ntfs_attrlist_mft_buf]
lea esi, [ebp+NTFS.attrlist_mft_buf+0x200]
lea edi, [ebp+NTFS.attrlist_mft_buf]
@@:
mov ecx, 0x200/4
rep movsd
895,52 → 917,52
mov eax, edi
pop edi esi
sub esi, 0x200
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 [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 esi edx edi
call .doreadattr
pop edi edx esi
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]
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]
jc .errret
lea ecx, [ecx+ebp+NTFS.ntfs_attrlist_buf+0x200-0x1A]
cmp [ebp+NTFS.ntfs_cur_iRecord], 0
lea ecx, [ecx+ebp+NTFS.attrlist_buf+0x200-0x1A]
cmp [ebp+NTFS.cur_iRecord], 0
jnz .scanliststart
add ecx, NTFS.ntfs_attrlist_mft_buf-NTFS.ntfs_attrlist_buf
add ecx, NTFS.attrlist_mft_buf-NTFS.attrlist_buf
jmp .scanliststart
 
.doreadattr:
mov [ebp+NTFS.ntfs_bCanContinue], 0
cmp byte [ecx+8], 0
mov [ebp+NTFS.bCanContinue], 0
cmp byte [ecx+nonResidentFlag], 0
jnz .nonresident
mov eax, [ecx+10h] ; length
mov eax, [ecx+sizeWithoutHeader]
mov esi, eax
mov edx, [ebp+NTFS.ntfs_cur_offs]
mov edx, [ebp+NTFS.cur_offs]
shr eax, 9
cmp eax, edx
jb .okret
shl edx, 9
sub esi, edx
movzx eax, word [ecx+14h]
movzx eax, word [ecx+attributeOffset]
add edx, eax
add edx, ecx ; edx -> data
mov eax, [ebp+NTFS.ntfs_cur_size]
mov eax, [ebp+NTFS.cur_size]
cmp eax, (0xFFFFFFFF shr 9)+1
jbe @f
mov eax, (0xFFFFFFFF shr 9)+1
951,72 → 973,75
mov eax, esi
@@:
; eax = length, edx -> data
mov [ebp+NTFS.ntfs_cur_read], eax
mov [ebp+NTFS.cur_read], eax
mov ecx, eax
mov eax, edx
mov ebx, [ebp+NTFS.ntfs_cur_buf]
mov ebx, [ebp+NTFS.cur_buf]
call memmove
and [ebp+NTFS.ntfs_cur_size], 0 ; CF=0
and [ebp+NTFS.cur_size], 0 ; CF=0
ret
 
.nonresident:
; Not all auxiliary records contain correct FileSize info
mov eax, dword [ebp+NTFS.ntfs_attr_size]
mov edx, dword [ebp+NTFS.ntfs_attr_size+4]
mov eax, dword [ebp+NTFS.attr_size]
mov edx, dword [ebp+NTFS.attr_size+4]
push eax
and eax, edx
cmp eax, -1
pop eax
jnz @f
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
mov eax, [ecx+attributeRealSize]
mov edx, [ecx+attributeRealSize+4]
mov dword [ebp+NTFS.attr_size], eax
mov dword [ebp+NTFS.attr_size+4], edx
@@:
add eax, 0x1FF
adc edx, 0
shrd eax, edx, 9
sub eax, [ebp+NTFS.ntfs_cur_offs]
sub eax, [ebp+NTFS.cur_offs]
ja @f
; return with nothing read
and [ebp+NTFS.ntfs_cur_size], 0
and [ebp+NTFS.cur_size], 0
.okret:
clc
ret
 
@@:
; reduce read length
and [ebp+NTFS.ntfs_cur_tail], 0
cmp [ebp+NTFS.ntfs_cur_size], eax
and [ebp+NTFS.cur_tail], 0
cmp [ebp+NTFS.cur_size], eax
jb @f
mov [ebp+NTFS.ntfs_cur_size], eax
mov eax, dword [ebp+NTFS.ntfs_attr_size]
mov [ebp+NTFS.cur_size], eax
mov eax, dword [ebp+NTFS.attr_size]
and eax, 0x1FF
mov [ebp+NTFS.ntfs_cur_tail], eax
mov [ebp+NTFS.cur_tail], eax
@@:
cmp [ebp+NTFS.ntfs_cur_size], 0
cmp [ebp+NTFS.cur_size], 0
jz .okret
mov eax, [ebp+NTFS.ntfs_cur_offs]
mov eax, [ebp+NTFS.cur_offs]
xor edx, edx
div [ebp+NTFS.sectors_per_cluster]
sub eax, [ecx+10h] ; first_vbo
sub eax, [ecx+firstVCN]
jb .okret
; eax = cluster, edx = starting sector
cmp [ebp+NTFS.ntfs_cur_attr], 0x80
cmp [ebp+NTFS.cur_attr], 0x80
jnz .sys
cmp [ebp+NTFS.ntfs_cur_iRecord], 0
cmp [ebp+NTFS.cur_iRecord], 0
jz .sys
push fs_read64_app
cmp [ebp+NTFS.ntfsWriteAttr], 1
cmp [ebp+NTFS.bWriteAttr], 1
jnz @f
mov dword[esp], fs_write64_app
jmp @f
 
.sys:
push fs_read64_sys
@@:
sub esp, 10h
movzx esi, word [ecx+20h] ; mcb_info_ofs
movzx esi, word [ecx+dataRunsOffset]
add esi, ecx
xor edi, edi
mov [ebp+NTFS.ntfsFragmentCount], 0
mov [ebp+NTFS.fragmentCount], 0
.readloop:
call ntfs_decode_mcb_entry
jnc .break
1033,12 → 1058,12
neg ecx
imul ecx, [ebp+NTFS.sectors_per_cluster]
sub ecx, edx
cmp ecx, [ebp+NTFS.ntfs_cur_size]
cmp ecx, [ebp+NTFS.cur_size]
jb @f
mov ecx, [ebp+NTFS.ntfs_cur_size]
mov ecx, [ebp+NTFS.cur_size]
@@:
mov ebx, [ebp+NTFS.ntfs_cur_buf]
mov [ebp+NTFS.ntfsLastRead], eax
mov ebx, [ebp+NTFS.cur_buf]
mov [ebp+NTFS.LastRead], eax
push ecx
xor edx, edx
call dword[esp+18h]
1045,34 → 1070,36
pop ecx
test eax, eax
jnz .errread2
sub [ebp+NTFS.ntfs_cur_size], ecx
add [ebp+NTFS.ntfs_cur_offs], ecx
sub [ebp+NTFS.cur_size], ecx
add [ebp+NTFS.cur_offs], ecx
shl ecx, 9
add [ebp+NTFS.ntfs_cur_read], ecx
add [ebp+NTFS.ntfs_cur_buf], ecx
inc [ebp+NTFS.ntfsFragmentCount]
add [ebp+NTFS.cur_read], ecx
add [ebp+NTFS.cur_buf], ecx
inc [ebp+NTFS.fragmentCount]
pop ecx
xor eax, eax
xor edx, edx
cmp [ebp+NTFS.ntfs_cur_size], 0
cmp [ebp+NTFS.cur_size], 0
jnz .readloop
add esp, 14h
mov eax, [ebp+NTFS.ntfs_cur_tail]
mov eax, [ebp+NTFS.cur_tail]
test eax, eax
jz @f
sub eax, 0x200
add [ebp+NTFS.ntfs_cur_read], eax
add [ebp+NTFS.cur_read], eax
@@:
clc
ret
 
.errread2:
pop ecx
add esp, 14h
stc
ret
 
.break:
add esp, 14h ; CF=0
mov [ebp+NTFS.ntfs_bCanContinue], 1
mov [ebp+NTFS.bCanContinue], 1
ret
 
ntfs_read_file_record:
1086,39 → 1113,39
shrd eax, edx, 9
shr edx, 9
jnz .errret
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
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
shr ecx, 9
mov [ebp+NTFS.ntfs_cur_size], ecx
mov [ebp+NTFS.cur_size], ecx
mov eax, [ebp+NTFS.frs_buffer]
mov [ebp+NTFS.ntfs_cur_buf], eax
mov [ebp+NTFS.cur_buf], eax
call ntfs_read_attr
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]
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]
jc .ret
cmp edx, [ebp+NTFS.frs_size]
jnz .errret
1133,6 → 1160,7
.ret:
pop edx ecx
ret
 
.errret:
pop edx ecx
xor eax, eax
1149,9 → 1177,9
shr eax, 9
mov ecx, eax
inc eax
cmp [ebx+6], ax
cmp [ebx+updateSequenceSize], ax
jnz .err
movzx eax, word [ebx+4]
movzx eax, word [ebx+updateSequenceOffset]
lea esi, [eax+ebx]
lodsw
mov edx, eax
1166,6 → 1194,7
popad
clc
ret
 
.err:
popad
stc
1233,87 → 1262,43
ntfs_find_lfn:
; in: [esi]+[esp+4] = name
; out:
; [ebp+NTFS.ntfs_cur_iRecord] = number of MFT fileRecord
; [ebp+NTFS.cur_iRecord] = number of MFT fileRecord
; eax -> index in the parent index node
; CF=1 -> file not found, eax=0 -> error
mov [ebp+NTFS.ntfs_cur_iRecord], 5 ; start parse from root cluster
mov [ebp+NTFS.cur_iRecord], 5 ; start from root directory
.doit2:
mov [ebp+NTFS.ntfs_cur_attr], 0x90 ; $INDEX_ROOT
and [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.cur_attr], 0x90 ; $INDEX_ROOT
and [ebp+NTFS.cur_offs], 0
mov eax, [ebp+NTFS.cur_index_size]
mov [ebp+NTFS.ntfs_cur_size], eax
mov [ebp+NTFS.cur_size], eax
mov eax, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.ntfs_cur_buf], eax
mov [ebp+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 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
mov edx, [esi+indexRecordSize]
shr edx, 9
cmp edx, [ebp+NTFS.cur_index_size]
jbe .ok2
push esi edx
stdcall kernel_alloc, edx
pop edx esi
test eax, eax
jz .stc_ret
mov edi, eax
mov ecx, [ebp+NTFS.cur_index_size]
shl ecx, 9-2
rep movsd
mov esi, eax
mov [ebp+NTFS.cur_index_size], edx
push esi edx
stdcall kernel_free, [ebp+NTFS.cur_index_buf]
pop edx esi
mov [ebp+NTFS.cur_index_buf], esi
.ok2:
add esi, 10h
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
mov edi, [esp+4]
; edi -> name, esi -> current index data, edx = subnode size
; edi -> name, esi -> current index node, edx = subnode size
.scanloop:
add esi, [esi]
add esi, [esi+indexOffset]
.scanloopint:
test byte [esi+0Ch], 2
test byte [esi+indexFlags], 2
jnz .subnode
push esi
add esi, 0x52
movzx ecx, byte [esi-2]
movzx ecx, byte [esi+fileNameLength]
add esi, fileName
push edi
@@:
lodsw
1333,46 → 1318,60
pop esi
jb .subnode
.scanloopcont:
movzx eax, word [esi+8]
movzx eax, word [esi+indexAllocatedSize]
add esi, eax
jmp .scanloopint
 
.realloc:
mov edi, edx
stdcall kernel_alloc, [esi+indexRecordSize]
test eax, eax
jz .err
push [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.cur_index_buf], eax
call kernel_free
mov [ebp+NTFS.cur_index_size], edi
popad
jmp .doit2
 
.notfound:
mov [esp+1Ch], esi
.err:
popad
stc
.ret:
ret 4
 
.slash:
pop eax
pop edi
pop esi
.subnode:
test byte [esi+0Ch], 1
test byte [esi+indexFlags], 1
jz .notfound
movzx eax, word [esi+8]
movzx eax, word [esi+indexAllocatedSize]
mov eax, [esi+eax-8]
imul eax, [ebp+NTFS.sectors_per_cluster]
mov [ebp+NTFS.ntfs_cur_offs], eax
mov [ebp+NTFS.ntfs_cur_attr], 0xA0 ; $INDEX_ALLOCATION
mov [ebp+NTFS.ntfs_cur_size], edx
mov [ebp+NTFS.cur_offs], eax
mov [ebp+NTFS.cur_attr], 0xA0 ; $INDEX_ALLOCATION
mov [ebp+NTFS.cur_size], edx
mov eax, [ebp+NTFS.cur_index_buf]
mov esi, eax
mov [ebp+NTFS.ntfs_cur_buf], eax
push edx
call ntfs_read_attr
pop edx
mov [ebp+NTFS.cur_buf], eax
call ntfs_read_attr.newAttribute
mov eax, edx
shl eax, 9
cmp [ebp+NTFS.ntfs_cur_read], eax
cmp [ebp+NTFS.cur_read], eax
jnz .err
cmp dword [esi], 'INDX'
jnz .err
mov [ebp+NTFS.ntfs_cur_buf], esi
mov [ebp+NTFS.cur_buf], esi
mov ebx, esi
call ntfs_restore_usa
jc .err
add esi, 0x18
add esi, recordNode
jmp .scanloop
.notfound:
mov [esp+1Ch], esi
.err:
popad
stc
ret 4
 
.found:
cmp byte [edi], 0
jz .done
1381,12 → 1380,13
pop edi
pop esi
jmp .scanloopcont
 
.done:
.next:
pop esi
pop esi
mov eax, [esi]
mov [ebp+NTFS.ntfs_cur_iRecord], eax
mov [ebp+NTFS.cur_iRecord], eax
mov [esp+1Ch], esi
mov [esp+4], edi
popad
1394,12 → 1394,10
cmp byte [esi-1], 0
jnz .doit2
cmp dword [esp+4], 0
jz @f
jz .ret
mov esi, [esp+4]
mov dword [esp+4], 0
jmp .doit2
@@:
ret 4
 
;----------------------------------------------------------------
ntfs_ReadFile:
1408,6 → 1406,7
or ebx, -1
movi eax, ERROR_ACCESS_DENIED
ret
 
@@:
call ntfs_lock
stdcall ntfs_find_lfn, [esp+4]
1416,10 → 1415,11
or ebx, -1
movi eax, ERROR_FILE_NOT_FOUND
ret
 
.found:
mov [ebp+NTFS.ntfs_cur_attr], 0x80 ; $DATA
and [ebp+NTFS.ntfs_cur_offs], 0
and [ebp+NTFS.ntfs_cur_size], 0
mov [ebp+NTFS.cur_attr], 0x80 ; $DATA
and [ebp+NTFS.cur_offs], 0
and [ebp+NTFS.cur_size], 0
call ntfs_read_attr
jnc @f
call ntfs_unlock
1426,6 → 1426,7
or ebx, -1
movi eax, ERROR_ACCESS_DENIED
ret
 
@@:
pushad
and dword [esp+10h], 0
1436,10 → 1437,10
popad
xor ebx, ebx
.eof:
push ERROR_END_OF_FILE
call ntfs_unlock
pop eax
movi eax, ERROR_END_OF_FILE
ret
 
@@:
mov ecx, [ebx+12]
mov edx, [ebx+16]
1450,15 → 1451,15
mov edx, [ebx+8]
shrd eax, edx, 9
pop edx
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
mov [ebp+NTFS.cur_offs], eax
mov [ebp+NTFS.cur_size], 1
lea eax, [ebp+NTFS.bitmap_buf]
mov [ebp+NTFS.cur_buf], eax
call ntfs_read_attr.continue
mov eax, [ebx+4]
and eax, 0x1FF
lea esi, [ebp+NTFS.ntfs_bitmap_buf+eax]
sub eax, [ebp+NTFS.ntfs_cur_read]
lea esi, [ebp+NTFS.bitmap_buf+eax]
sub eax, [ebp+NTFS.cur_read]
jae .eof0
neg eax
push ecx
1478,12 → 1479,14
call ntfs_unlock
xor eax, eax
ret
 
@@:
cmp [ebp+NTFS.ntfs_cur_read], 0x200
cmp [ebp+NTFS.cur_read], 0x200
jz .alignedstart
.eof_ebx:
popad
jmp .eof
 
.alignedstart:
mov eax, [ebx+4]
push edx
1492,41 → 1495,41
adc edx, 0
shrd eax, edx, 9
pop edx
mov [ebp+NTFS.ntfs_cur_offs], eax
mov [ebp+NTFS.ntfs_cur_buf], edx
mov [ebp+NTFS.cur_offs], eax
mov [ebp+NTFS.cur_buf], edx
mov eax, ecx
shr eax, 9
mov [ebp+NTFS.ntfs_cur_size], eax
add eax, [ebp+NTFS.ntfs_cur_offs]
mov [ebp+NTFS.cur_size], eax
add eax, [ebp+NTFS.cur_offs]
push eax
call ntfs_read_attr.continue
pop [ebp+NTFS.ntfs_cur_offs]
mov eax, [ebp+NTFS.ntfs_cur_read]
pop [ebp+NTFS.cur_offs]
mov eax, [ebp+NTFS.cur_read]
add [esp+10h], eax
mov eax, ecx
and eax, not 0x1FF
cmp [ebp+NTFS.ntfs_cur_read], eax
cmp [ebp+NTFS.cur_read], eax
jnz .eof_ebx
and ecx, 0x1FF
jz .retok
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
add edx, [ebp+NTFS.cur_read]
mov [ebp+NTFS.cur_size], 1
lea eax, [ebp+NTFS.bitmap_buf]
mov [ebp+NTFS.cur_buf], eax
call ntfs_read_attr.continue
cmp [ebp+NTFS.ntfs_cur_read], ecx
cmp [ebp+NTFS.cur_read], ecx
jb @f
mov [ebp+NTFS.ntfs_cur_read], ecx
mov [ebp+NTFS.cur_read], ecx
@@:
xchg ecx, [ebp+NTFS.ntfs_cur_read]
xchg ecx, [ebp+NTFS.cur_read]
push ecx
mov edi, edx
lea esi, [ebp+NTFS.ntfs_bitmap_buf]
lea esi, [ebp+NTFS.bitmap_buf]
add [esp+10h+4], ecx
rep movsb
pop ecx
xor eax, eax
cmp ecx, [ebp+NTFS.ntfs_cur_read]
cmp ecx, [ebp+NTFS.cur_read]
jz @f
mov al, ERROR_END_OF_FILE
@@:
1538,103 → 1541,41
;----------------------------------------------------------------
ntfs_ReadFolder:
call ntfs_lock
mov eax, 5 ; root cluster
mov [ebp+NTFS.cur_iRecord], 5 ; root directory
cmp byte [esi], 0
jz .doit
jz @f
stdcall ntfs_find_lfn, [esp+4]
jnc .doit2
.notfound:
or ebx, -1
push ERROR_FILE_NOT_FOUND
.pop_ret:
call ntfs_unlock
pop eax
ret
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
call ntfs_read_attr
jc ntfsFail
mov [ebp+NTFS.cur_attr], 0x90 ; $INDEX_ROOT
.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 .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.ntfs_cur_size], eax
mov [ebp+NTFS.cur_size], eax
mov eax, [ebp+NTFS.cur_index_buf]
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
@@:
mov [ebp+NTFS.cur_buf], eax
call ntfs_read_attr.newAttribute
jc ntfsFail
cmp [ebp+NTFS.cur_read], 0x20
jc ntfsFail
pushad
mov esi, [ebp+NTFS.cur_index_buf]
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
mov edx, [esi+indexRecordSize]
shr edx, 9
cmp [ebp+NTFS.cur_index_size], edx
jc .realloc
mov [ebp+NTFS.cur_subnode_size], edx
cmp edx, [ebp+NTFS.cur_index_size]
jbe .ok2
push esi edx
stdcall kernel_alloc, edx
pop edx esi
test eax, eax
jz .nomem
mov edi, eax
mov ecx, [ebp+NTFS.cur_index_size]
shl ecx, 9-2
rep movsd
mov esi, eax
mov [ebp+NTFS.cur_index_size], edx
stdcall kernel_free, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.cur_index_buf], esi
.ok2:
add esi, 10h
add esi, rootNode
mov eax, [esi+nodeRealSize]
add eax, rootNode
cmp [ebp+NTFS.cur_read], eax
jc .err
mov edx, [ebx+16]
push dword [ebx+8] ; read ANSI/UNICODE name
; init header
1650,7 → 1591,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.ntfs_cur_iRecord], 5
cmp [ebp+NTFS.cur_iRecord], 5
jz .skip_specials
; dot and dotdot entries
push esi
1661,50 → 1602,66
pop esi
.skip_specials:
; at first, dump index root
add esi, [esi]
add esi, [esi+indexOffset]
.dump_root:
test byte [esi+0Ch], 2
test byte [esi+indexFlags], 2
jnz .dump_root_done
call .add_entry
movzx eax, word [esi+8]
movzx eax, word [esi+indexAllocatedSize]
add esi, eax
jmp .dump_root
 
.realloc:
mov edi, edx
stdcall kernel_alloc, [esi+indexRecordSize]
test eax, eax
jz .err
push [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.cur_index_buf], eax
call kernel_free
mov [ebp+NTFS.cur_index_size], edi
popad
jmp .doit
 
.err:
popad
jmp ntfsFail
 
.dump_root_done:
; now dump all subnodes
push ecx edi
lea edi, [ebp+NTFS.ntfs_bitmap_buf]
mov [ebp+NTFS.ntfs_cur_buf], edi
lea edi, [ebp+NTFS.bitmap_buf]
mov [ebp+NTFS.cur_buf], edi
mov ecx, 0x400/4
xor eax, eax
rep stosd
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
mov [ebp+NTFS.cur_attr], 0xB0 ; $BITMAP
and [ebp+NTFS.cur_offs], 0
mov [ebp+NTFS.cur_size], 2
call ntfs_read_attr.newAttribute
pop edi ecx
push 0 ; save offset in $BITMAP attribute
and [ebp+NTFS.ntfs_cur_offs], 0
and [ebp+NTFS.cur_offs], 0
.dumploop:
mov [ebp+NTFS.ntfs_cur_attr], 0xA0
mov [ebp+NTFS.cur_attr], 0xA0
mov eax, [ebp+NTFS.cur_subnode_size]
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]
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
imul eax, [ebp+NTFS.cur_subnode_size]
mov [ebp+NTFS.ntfs_cur_offs], eax
call ntfs_read_attr
pop [ebp+NTFS.ntfs_cur_offs]
mov [ebp+NTFS.cur_offs], eax
call ntfs_read_attr.newAttribute
pop [ebp+NTFS.cur_offs]
mov eax, [ebp+NTFS.cur_subnode_size]
shl eax, 9
cmp [ebp+NTFS.ntfs_cur_read], eax
cmp [ebp+NTFS.cur_read], eax
jnz .done
push eax
mov eax, [ebp+NTFS.ntfs_cur_offs]
mov eax, [ebp+NTFS.cur_offs]
and eax, 0x400*8-1
bt dword [ebp+NTFS.ntfs_bitmap_buf], eax
bt dword [ebp+NTFS.bitmap_buf], eax
pop eax
jnc .dump_subnode_done
cmp dword [esi], 'INDX'
1714,38 → 1671,40
call ntfs_restore_usa
pop ebx
jc .dump_subnode_done
add esi, 0x18
add esi, [esi]
add esi, recordNode
add esi, [esi+indexOffset]
.dump_subnode:
test byte [esi+0Ch], 2
test byte [esi+indexFlags], 2
jnz .dump_subnode_done
call .add_entry
movzx eax, word [esi+8]
movzx eax, word [esi+indexAllocatedSize]
add esi, eax
jmp .dump_subnode
 
.dump_subnode_done:
inc [ebp+NTFS.ntfs_cur_offs]
test [ebp+NTFS.ntfs_cur_offs], 0x400*8-1
inc [ebp+NTFS.cur_offs]
test [ebp+NTFS.cur_offs], 0x400*8-1
jnz .dumploop
mov [ebp+NTFS.ntfs_cur_attr], 0xB0
mov [ebp+NTFS.cur_attr], 0xB0
push ecx edi
lea edi, [ebp+NTFS.ntfs_bitmap_buf]
mov [ebp+NTFS.ntfs_cur_buf], edi
lea edi, [ebp+NTFS.bitmap_buf]
mov [ebp+NTFS.cur_buf], edi
mov ecx, 0x400/4
xor eax, eax
rep stosd
pop edi ecx
pop eax
push [ebp+NTFS.ntfs_cur_offs]
push [ebp+NTFS.cur_offs]
inc eax
mov [ebp+NTFS.ntfs_cur_offs], eax
mov [ebp+NTFS.ntfs_cur_size], 2
mov [ebp+NTFS.cur_offs], eax
mov [ebp+NTFS.cur_size], 2
push eax
call ntfs_read_attr
call ntfs_read_attr.newAttribute
pop eax
pop [ebp+NTFS.ntfs_cur_offs]
pop [ebp+NTFS.cur_offs]
push eax
jmp .dumploop
 
.done:
pop eax
pop edx
1772,20 → 1731,18
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.ntfs_bitmap_buf]
mov edx, dword [ebp+NTFS.ntfs_bitmap_buf+4]
mov eax, dword [ebp+NTFS.bitmap_buf]
mov edx, dword [ebp+NTFS.bitmap_buf+4]
call ntfs_datetime_to_bdfe
mov eax, dword [ebp+NTFS.ntfs_bitmap_buf+0x18]
mov edx, dword [ebp+NTFS.ntfs_bitmap_buf+0x1C]
mov eax, dword [ebp+NTFS.bitmap_buf+0x18]
mov edx, dword [ebp+NTFS.bitmap_buf+0x1C]
call ntfs_datetime_to_bdfe
mov eax, dword [ebp+NTFS.ntfs_bitmap_buf+8]
mov edx, dword [ebp+NTFS.ntfs_bitmap_buf+0xC]
mov eax, dword [ebp+NTFS.bitmap_buf+8]
mov edx, dword [ebp+NTFS.bitmap_buf+0xC]
call ntfs_datetime_to_bdfe
pop edx
xor eax, eax
1803,6 → 1760,7
pop edi
add edi, 520
ret
 
@@:
rep stosb
pop ecx
1815,11 → 1773,11
 
.add_entry:
; do not return DOS 8.3 names
cmp byte [esi+0x51], 2
cmp byte [esi+namespace], 2
jz .ret
; do not return system files
; ... note that there will be no bad effects if system files also were reported ...
cmp dword [esi], 0x10
cmp dword [esi+fileRecordReference], 0x10
jb .ret
mov eax, [edx]
inc dword [eax+8] ; new file found
1831,8 → 1789,8
mov eax, [edx+4] ; flags
call ntfs_direntry_to_bdfe
push ecx esi edi
movzx ecx, byte [esi+0x50]
add esi, 0x52
movzx ecx, byte [esi+fileNameLength]
add esi, fileName
test byte [edi-0x24], 1
jz .ansi
shr ecx, 1
1844,6 → 1802,7
add edi, 520
pop esi ecx
ret
 
.ansi:
jecxz .skip
@@:
1861,7 → 1820,7
 
ntfs_direntry_to_bdfe:
mov [edi+4], eax ; ANSI/UNICODE name
mov eax, [esi+48h]
mov eax, [esi+fileFlags]
test eax, 0x10000000
jz @f
and eax, not 0x10000000
1870,136 → 1829,108
stosd
scasd
push edx
mov eax, [esi+0x18]
mov edx, [esi+0x1C]
mov eax, [esi+fileCreated]
mov edx, [esi+fileCreated+4]
call ntfs_datetime_to_bdfe
mov eax, [esi+0x30]
mov edx, [esi+0x34]
mov eax, [esi+fileAccessed]
mov edx, [esi+fileAccessed+4]
call ntfs_datetime_to_bdfe
mov eax, [esi+0x20]
mov edx, [esi+0x24]
mov eax, [esi+fileModified]
mov edx, [esi+fileModified+4]
call ntfs_datetime_to_bdfe
pop edx
mov eax, [esi+0x40]
mov eax, [esi+fileRealSize]
stosd
mov eax, [esi+0x44]
mov eax, [esi+fileRealSize+4]
stosd
ret
 
iglobal
_24 dd 24
_60 dd 60
_10000000 dd 10000000
days400year dd 365*400+100-4+1
days100year dd 365*100+25-1
days4year dd 365*4+1
days1year dd 365
months dd 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
months2 dd 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
_400 dd 400
_100 dd 100
months db 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
months2 db 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
endg
 
ntfs_datetime_to_bdfe:
; edx:eax = number of 100-nanosecond intervals since January 1, 1601, in UTC
push eax
push ebx ecx
mov ebx, eax
mov eax, edx
xor edx, edx
div [_10000000]
xchg eax, [esp]
div [_10000000]
pop edx
.sec:
; edx:eax = number of seconds since January 1, 1601
push eax
mov eax, edx
mov ecx, 10000000
div ecx
xchg eax, ebx
div ecx
.forEXT:
xchg eax, ebx
xor edx, edx
div [_60]
xchg eax, [esp]
div [_60]
mov ecx, 60
div ecx
xchg eax, ebx
div ecx
mov [edi], dl
pop edx
mov edx, ebx
; edx:eax = number of minutes
div [_60]
div ecx
mov [edi+1], dl
; eax = number of hours (note that 2^64/(10^7*60*60) < 2^32)
; eax = number of hours
xor edx, edx
div [_24]
mov [edi+2], dl
mov [edi+3], byte 0
mov cl, 24
div ecx
mov [edi+2], dx
; eax = number of days since January 1, 1601
xor edx, edx
div [days400year]
imul eax, 400
add eax, 1601
mov [edi+6], ax
mov eax, edx
xor edx, edx
div [days100year]
cmp al, 4
mov cx, 365
div ecx
mov ebx, eax
add ebx, 1601
shr eax, 2
sub edx, eax
mov cl, 25
div cl
xor ah, ah
add edx, eax
shr eax, 2
sub edx, eax
jns @f
dec ebx
add edx, 365
test bl, 3
jnz @f
dec eax
add edx, [days100year]
inc edx
@@:
imul eax, 100
add [edi+6], ax
mov eax, edx
xor edx, edx
div [days4year]
shl eax, 2
add [edi+6], ax
mov eax, edx
xor edx, edx
div [days1year]
cmp al, 4
xor eax, eax
mov ecx, months-1
test bl, 3
jnz @f
dec eax
add edx, [days1year]
add ecx, 12
@@:
add [edi+6], ax
push esi edx
mov esi, months
movzx eax, word [edi+6]
test al, 3
jnz .noleap
xor edx, edx
push eax
div [_400]
pop eax
test edx, edx
jz .leap
xor edx, edx
div [_100]
test edx, edx
jz .noleap
.leap:
mov esi, months2
.noleap:
pop edx
xor eax, eax
inc ecx
inc eax
@@:
sub edx, [esi]
jb @f
add esi, 4
inc eax
jmp @b
@@:
add edx, [esi]
pop esi
sub dl, [ecx]
jnc @b
dec dh
jns @b
add dl, [ecx]
inc edx
mov [edi+4], dl
mov [edi+5], al
mov [edi+6], bx
add edi, 8
pop ecx ebx
ret
 
.sec:
push ebx ecx
mov ebx, edx
jmp .forEXT
 
;----------------------------------------------------------------
ntfs_CreateFolder:
mov [ebp+NTFS.ntfsFolder], 1
mov [ebp+NTFS.bFolder], 1
jmp @f
 
ntfs_CreateFile:
mov [ebp+NTFS.ntfsFolder], 0
mov [ebp+NTFS.bFolder], 0
@@:
cmp byte [esi], 0
jnz @f
2006,16 → 1937,17
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.ntfs_cur_iRecord], 16
cmp [ebp+NTFS.cur_iRecord], 16
jc ntfsDenied
cmp [ebp+NTFS.ntfsFolder], 1
cmp [ebp+NTFS.bFolder], 1
jz .folder
cmp [ebp+NTFS.ntfsFragmentCount], 1
cmp [ebp+NTFS.fragmentCount], 1
jnz ntfsUnsupported ; record fragmented
; edit directory node
mov edi, [ebp+NTFS.cur_index_buf]
2025,7 → 1957,7
mov ecx, [esi+recordRealSize]
shr ecx, 2
rep movsd
mov esi, [ebp+NTFS.ntfs_attr_offs]
mov esi, [ebp+NTFS.attr_offs]
mov cl, [esi+attributeOffset]
sub esi, [ebp+NTFS.frs_buffer]
add eax, ecx
2034,11 → 1966,11
mov edx, [ebx+12]
mov [eax+fileRealSize], edx
mov dword [eax+fileRealSize+4], 0
mov eax, [ebp+NTFS.ntfsLastRead]
mov eax, [ebp+NTFS.LastRead]
mov [ebp+NTFS.nodeLastRead], eax
mov [ebp+NTFS.ntfs_cur_attr], 0x80
mov [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.ntfs_cur_size], 0
mov [ebp+NTFS.cur_attr], 0x80
mov [ebp+NTFS.cur_offs], 0
mov [ebp+NTFS.cur_size], 0
call ntfs_read_attr
jc ntfsFail
mov ecx, [ebp+NTFS.frs_buffer]
2046,7 → 1978,7
xor edx, edx
cmp word [ecx+baseRecordReuse], 0
jnz ntfsUnsupported ; auxiliary record
mov ecx, [ebp+NTFS.ntfs_attr_offs]
mov ecx, [ebp+NTFS.attr_offs]
cmp word [ecx+attributeFlags], 0
jnz ntfsUnsupported
push ebx
2068,7 → 2000,7
.notFound: ; create
test eax, eax
jz ntfsFail
cmp [ebp+NTFS.ntfsFragmentCount], 1
cmp [ebp+NTFS.fragmentCount], 1
jnz ntfsUnsupported ; record fragmented
; 2. Prepare directory record
mov ecx, esi
2079,27 → 2011,29
cmp byte [ecx], 0
jnz @b
sub ecx, esi
push ecx
lea ecx, [ecx*2+52h+7] ; precalculate index length
and ecx, not 7 ; align 8
push ecx ; name length
shl ecx, 1
add ecx, fileName+7
and ecx, not 7
mov edi, [ebp+NTFS.cur_index_buf]
mov edx, [ebx+12]
mov [ebp+NTFS.fileRealSize], edx
mov edx, [ebx+16]
mov [ebp+NTFS.fileDataBuffer], edx
push esi
push ecx
push ecx ; index length
mov edx, ecx
cmp dword [edi], 'INDX'
jz .indexRecord
mov esi, [ebp+NTFS.frs_buffer] ; indexRoot
mov edx, [esi+recordRealSize]
mov ecx, [esi+recordRealSize]
add edx, ecx
cmp [esi+recordAllocatedSize], edx
jnc @f
add esp, 12
jmp ntfsUnsupported ; indexAllocation required
@@: ; index fits in the indexRoot
jc .growTree
mov [esi+recordRealSize], edx
mov ecx, edx
shr ecx, 2
rep movsd
mov edi, [ebp+NTFS.ntfs_attr_offs]
mov edi, [ebp+NTFS.attr_offs]
sub edi, [ebp+NTFS.frs_buffer]
add edi, [ebp+NTFS.cur_index_buf]
mov esi, [esp]
2107,30 → 2041,172
add [edi+sizeWithoutHeader], esi
mov cl, [edi+attributeOffset]
add edi, ecx
add [edi+16+nodeRealSize], esi
add [edi+16+nodeAllocatedSize], esi
add [edi+rootNode+nodeRealSize], esi
add [edi+rootNode+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:
mov edx, [edi+28]
add edx, ecx
cmp [edi+32], edx
add edi, recordNode
add edx, [edi+nodeRealSize]
cmp [edi+nodeAllocatedSize], edx
jnc @f
add esp, 12
jmp ntfsUnsupported ; new node required
 
@@: ; index fits in the node
mov [edi+28], edx
lea edi, [edi+edx+24-4]
mov [edi+nodeRealSize], edx
.common:
add edi, edx
sub edi, 4
mov esi, edi
sub esi, [esp]
mov ecx, esi
sub ecx, eax ; eax = pointer in the node
sub ecx, eax ; eax = pointer in the record
shr ecx, 2
inc ecx
std
2148,20 → 2224,20
shl eax, 1
add eax, 42h
mov [edi+indexRawSize], ax
mov eax, [ebp+NTFS.ntfs_attr_iRecord]
mov eax, [ebp+NTFS.attr_iRecord]
mov [edi+directoryRecordReference], eax
mov eax, [ebp+NTFS.frs_buffer]
mov eax, [eax+reuseCounter]
mov [edi+directoryReferenceReuse], ax
mov eax, [ebx+12]
mov eax, [ebp+NTFS.frs_size]
shr eax, 8
add ecx, 30h+48h+8+18h+8
add ecx, eax
mov [ebp+NTFS.fileRealSize], eax
mov eax, [ebp+NTFS.fileRealSize]
add ecx, 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]
2176,7 → 2252,7
pop ecx
mov [ebp+NTFS.indexOffset], edi
mov [edi+fileNameLength], cl
add edi, 52h
add edi, fileName
@@: ; record filename
lodsb
call ansi2uni_char
2183,9 → 2259,9
stosw
dec ecx
jnz @b
mov eax, [ebp+NTFS.ntfsLastRead]
mov eax, [ebp+NTFS.LastRead]
mov [ebp+NTFS.nodeLastRead], eax
cmp [ebp+NTFS.ntfsFolder], 0
cmp [ebp+NTFS.bFolder], 0
jz @f
mov edi, [ebp+NTFS.indexOffset]
bts dword [edi+fileFlags], 28
2197,12 → 2273,12
mov edi, [ebp+NTFS.BitmapStart]
call ntfsSpaceAlloc
jc ntfsDiskFull
mov [ebp+NTFS.fileDataStart], eax
mov eax, [ebp+NTFS.fileDataStart]
mul [ebp+NTFS.sectors_per_cluster]
mov ecx, [ebp+NTFS.fileRealSize]
add ecx, 511
shr ecx, 9
mov ebx, [ebx+16]
mov ebx, [ebp+NTFS.fileDataBuffer]
call fs_write64_app
test eax, eax
jnz ntfsDevice
2228,14 → 2304,14
mov eax, [ebp+NTFS.frs_size]
shr eax, 9
mul edi
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 [ebp+NTFS.cur_iRecord], 0
mov [ebp+NTFS.cur_attr], 0x80
mov [ebp+NTFS.cur_offs], eax
mov [ebp+NTFS.cur_size], 1
mov eax, [ebp+NTFS.frs_buffer]
mov [ebp+NTFS.ntfs_cur_buf], eax
mov [ebp+NTFS.cur_buf], eax
call ntfs_read_attr
cmp [ebp+NTFS.ntfs_cur_read], 0
cmp [ebp+NTFS.cur_read], 0
jz .extendMFT
jmp .mftRecord
 
2244,21 → 2320,21
shl eax, 9
cmp [ebp+NTFS.mftBitmapSize], eax
jnc ntfsUnsupported
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
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
mov eax, [ebp+NTFS.mft_cluster]
mul [ebp+NTFS.sectors_per_cluster]
cmp eax, [ebp+NTFS.ntfsLastRead]
cmp eax, [ebp+NTFS.LastRead]
jnz ntfsUnsupported ; auxiliary record
mov edi, [ebp+NTFS.mftBitmapBuffer]
mov ecx, [ebp+NTFS.mftBitmapSize]
add edi, ecx
mov eax, ecx
mov edx, [ebp+NTFS.ntfs_attr_offs]
mov edx, [ebp+NTFS.attr_offs]
add ecx, 8
mov [edx+attributeRealSize], ecx
mov [edx+initialDataSize], ecx
2266,7 → 2342,7
mov [ebp+NTFS.newMftRecord], eax
mov dword [edi], 1
mov dword [edi+4], 0
mov [ebp+NTFS.ntfs_cur_attr], 0x80
mov [ebp+NTFS.cur_attr], 0x80
call ntfs_read_attr.newAttribute
jc ntfsFail
mov [ebp+NTFS.mftBitmapSize], ecx
2273,9 → 2349,9
.extendMFT:
mov eax, [ebp+NTFS.mft_cluster]
mul [ebp+NTFS.sectors_per_cluster]
cmp eax, [ebp+NTFS.ntfsLastRead]
cmp eax, [ebp+NTFS.LastRead]
jnz ntfsUnsupported ; auxiliary record
mov ecx, [ebp+NTFS.ntfs_attr_offs]
mov ecx, [ebp+NTFS.attr_offs]
mov eax, [ecx+attributeRealSize]
mov edx, [ecx+attributeRealSize+4]
xor ax, ax
2286,7 → 2362,7
call resizeAttribute
jc ntfsErrorPop2
mov eax, [ebp+NTFS.frs_buffer]
mov [ebp+NTFS.ntfs_cur_buf], eax
mov [ebp+NTFS.cur_buf], eax
call writeRecord ; $MFT
mov eax, [ebp+NTFS.mftmirr_cluster]
mul [ebp+NTFS.sectors_per_cluster]
2305,19 → 2381,22
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
rdtsc
mov [edi+2ah], ax
add edi, 30h
mov [edi+attributeOffset], al
add edi, eax
; $StandardInformation
mov byte [edi+attributeType], 10h
mov byte [edi+sizeWithHeader], 48h
2342,7 → 2421,7
rep movsd
mov byte [edi+sizeWithHeader], 50h
mov byte [edi+attributeID], 2
cmp [ebp+NTFS.ntfsFolder], 1
cmp [ebp+NTFS.bFolder], 1
jz .indexRoot
; $Data
mov byte [edi+attributeType], 80h
2371,7 → 2450,7
mov [edi+sizeWithoutHeader], ecx
mov byte [edi+attributeOffset], 18h
push edi
mov esi, [ebp+NTFS.fileDataStart]
mov esi, [ebp+NTFS.fileDataBuffer]
add edi, 18h
rep movsb
@@:
2383,7 → 2462,7
mov [edi+sizeWithHeader], eax
add edi, eax
mov al, 1
jmp @f
jmp .end
 
.indexRoot:
mov byte [edi+attributeType], 90h
2393,12 → 2472,19
mov byte [edi+attributeOffset], 20h
mov dword[edi+18h], 490024h ; unicode $I30
mov dword[edi+18h+4], 300033h
mov byte [edi+20h+attributeType], 30h
mov byte [edi+20h+indexedAttributesType], 30h
mov byte [edi+20h+collationRule], 1
mov eax, [ebp+NTFS.sectors_per_cluster]
shl eax, 9
mov dl, 1
shl eax, 8
@@:
shl eax, 1
shl edx, 1
cmp eax, [ebp+NTFS.frs_size]
jc @b
shr edx, 1
mov [edi+20h+indexRecordSize], eax
mov byte [edi+20h+indexRecordSizeClus], 1
mov [edi+20h+indexRecordSizeClus], dl
mov byte [edi+30h+indexOffset], 16
mov byte [edi+30h+nodeRealSize], 32
mov byte [edi+30h+nodeAllocatedSize], 32
2406,18 → 2492,16
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.ntfs_cur_buf], esi
mov [ebp+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
2428,37 → 2512,14
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
; 6. Write directory node
; 5. Write directory node
mov eax, [ebp+NTFS.nodeLastRead]
mov [ebp+NTFS.ntfsLastRead], eax
mov [ebp+NTFS.LastRead], eax
mov eax, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.ntfs_cur_buf], eax
mov [ebp+NTFS.cur_buf], eax
call writeRecord
mov ebx, [ebp+NTFS.fileRealSize]
ntfsDone:
2471,9 → 2532,9
writeRecord:
; make updateSequence and write to disk
; in:
; [ebp+NTFS.ntfs_cur_buf] -> record
; [ebp+NTFS.ntfsLastRead] = partition sector
mov esi, [ebp+NTFS.ntfs_cur_buf]
; [ebp+NTFS.cur_buf] -> record
; [ebp+NTFS.LastRead] = partition sector
mov esi, [ebp+NTFS.cur_buf]
mov edi, esi
movzx ecx, word [esi+updateSequenceOffset]
add edi, ecx
2489,8 → 2550,8
mov [esi-2], ax
dec ecx
jnz @b
mov eax, [ebp+NTFS.ntfsLastRead]
mov ebx, [ebp+NTFS.ntfs_cur_buf]
mov eax, [ebp+NTFS.LastRead]
mov ebx, [ebp+NTFS.cur_buf]
pop ecx
xor edx, edx
jmp fs_write64_sys
2559,15 → 2620,15
resizeAttribute:
; in:
; [ebp+NTFS.frs_buffer] -> file record
; [ebp+NTFS.ntfs_attr_offs] -> attribute
; [ebp+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.ntfs_attr_offs]
mov dword [ebp+NTFS.ntfs_attr_size], eax
mov dword [ebp+NTFS.ntfs_attr_size+4], edx
mov esi, [ebp+NTFS.attr_offs]
mov dword [ebp+NTFS.attr_size], eax
mov dword [ebp+NTFS.attr_size+4], edx
cmp byte [esi+nonResidentFlag], 0
jz .resident
mov ecx, [ebp+NTFS.sectors_per_cluster]
2609,7 → 2670,7
shr edi, 5
shl edi, 2
push eax
cmp [ebp+NTFS.ntfs_cur_iRecord], 0
cmp [ebp+NTFS.cur_iRecord], 0
jz @f
cmp edi, [ebp+NTFS.BitmapStart]
jc .err1
2616,6 → 2677,7
@@:
call ntfsSpaceAlloc
jc .err1
mov eax, [ebp+NTFS.fileDataStart]
pop edi
pop edx
cmp edx, eax
2636,46 → 2698,25
sub eax, edx
mov [ebp+NTFS.fileDataStart], eax
@@:
mov esi, [ebp+NTFS.ntfs_attr_offs]
mov esi, [ebp+NTFS.attr_offs]
call createMcbEntry
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
pop [ebp+NTFS.fileDataSize]
pop [ebp+NTFS.fileDataStart]
movi eax, ERROR_UNSUPPORTED_FS
.done:
ret
 
.err4:
pop eax
@@:
movi eax, ERROR_DEVICE
stc
ret
 
.err1:
add esp, 24
stc
.err10:
.err2:
movi eax, ERROR_DISK_FULL
ret
 
.err2:
movi eax, ERROR_UNSUPPORTED_FS
.err3:
movi eax, ERROR_FS_FAIL
add esp, 20
stc
ret
 
.shrinkAttribute:
2716,18 → 2757,12
pop edi
cmp [ebp+NTFS.fileDataSize], 0
jz @f
mov esi, [ebp+NTFS.ntfs_attr_offs]
mov esi, [ebp+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
2760,9 → 2795,9
xor eax, eax
rep stosd
cld
mov esi, [ebp+NTFS.ntfs_attr_offs]
mov esi, [ebp+NTFS.attr_offs]
@@:
mov eax, dword [ebp+NTFS.ntfs_attr_size]
mov eax, dword [ebp+NTFS.attr_size]
mov [esi+sizeWithoutHeader], eax
mov [ebp+NTFS.fileDataSize], 0
clc
2769,7 → 2804,7
ret
 
.nonResident: ; convert resident to non-resident
mov eax, dword [ebp+NTFS.ntfs_attr_size]
mov eax, dword [ebp+NTFS.attr_size]
sub eax, 1
sbb edx, 0
mov ecx, [ebp+NTFS.sectors_per_cluster]
2781,9 → 2816,8
push ecx
call ntfsSpaceAlloc
pop ecx
jc .err10
mov [ebp+NTFS.fileDataStart], eax
mov esi, [ebp+NTFS.ntfs_attr_offs]
jc .err2
mov esi, [ebp+NTFS.attr_offs]
xor eax, eax
xor edx, edx
@@:
2810,26 → 2844,22
pop ecx
shr ecx, 9
call fs_write64_app
push ebx
mov ebx, eax
call kernel_free
test ebx, ebx
jnz .err4
mov esi, [ebp+NTFS.ntfs_attr_offs]
stdcall kernel_free, ebx
mov esi, [ebp+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.ntfs_bitmap_buf]
lea edi, [ebp+NTFS.bitmap_buf]
push ecx
rep movsd
mov edi, [ebp+NTFS.ntfs_attr_offs]
mov edi, [ebp+NTFS.attr_offs]
add edi, 16
mov cl, 6
xor eax, eax
rep stosd
mov edi, [ebp+NTFS.ntfs_attr_offs]
mov edi, [ebp+NTFS.attr_offs]
mov eax, [ebp+NTFS.fileDataSize]
dec eax
mov [edi+lastVCN], eax
2842,8 → 2872,8
mov byte [edi+dataRunsOffset], 40h
mov [edi+attributeAllocatedSize], eax
mov [edi+attributeAllocatedSize+4], edx
mov eax, dword [ebp+NTFS.ntfs_attr_size]
mov edx, dword [ebp+NTFS.ntfs_attr_size+4]
mov eax, dword [ebp+NTFS.attr_size]
mov edx, dword [ebp+NTFS.attr_size+4]
mov [edi+attributeRealSize], eax
mov [edi+attributeRealSize+4], edx
mov [edi+initialDataSize], eax
2852,13 → 2882,13
add edi, 40h
call createMcbEntry
mov eax, edi
mov edi, [ebp+NTFS.ntfs_attr_offs]
mov edi, [ebp+NTFS.attr_offs]
sub eax, edi
add eax, 8
and eax, not 7
mov [edi+sizeWithHeader], eax
pop ecx
lea esi, [ebp+NTFS.ntfs_bitmap_buf]
lea esi, [ebp+NTFS.bitmap_buf]
add edi, eax
rep movsd
mov esi, [ebp+NTFS.frs_buffer]
2865,11 → 2895,9
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
jmp .writeBitmap
ret
 
.makeResident: ; convert non-resident to empty resident
movzx eax, byte [esi+dataRunsOffset]
2918,7 → 2946,7
rep stosd
mov eax, [ebp+NTFS.fileDataStart]
mul [ebp+NTFS.sectors_per_cluster]
mov [ebp+NTFS.ntfsLastRead], eax
mov [ebp+NTFS.LastRead], eax
pop ecx
call fs_write64_app
stdcall kernel_free, ebx
2926,13 → 2954,14
ret
 
ntfsSpaceAlloc:
; find and mark block of free space in bitmap buffer
; allocate disk space
; in:
; edi = offset in bitmap to start search from
; [ebp+NTFS.fileDataSize] = block size in clusters
; out:
; eax = allocated block starting cluster
; [ebp+NTFS.fileDataStart] = allocated block starting cluster
; CF=1 -> disk full
push eax
mov ecx, [ebp+NTFS.BitmapBuffer]
add edi, ecx
add ecx, [ebp+NTFS.BitmapSize]
2945,7 → 2974,7
mov eax, [ebp+NTFS.fileDataSize]
shr eax, 5
jz .small
push eax ; bitmap dwords
mov ebx, eax ; bitmap dwords
.start:
mov ecx, [ebp+NTFS.BitmapBuffer]
add ecx, [ebp+NTFS.BitmapSize]
2958,13 → 2987,13
call bitmapBuffering
jmp @b
@@:
cmp ecx, [esp]
cmp ecx, ebx
jnc @f
call bitmapBuffering
jmp @b
@@:
sub edi, 4
mov ecx, [esp]
mov ecx, ebx
mov esi, edi
xor eax, eax
repz scasd ; check following dwords
2997,11 → 3026,9
.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
3008,7 → 3035,7
mov eax, [edi]
not eax
@@:
bsf ecx, eax ; first 0
bsf ebx, eax ; first 0
jz .again
not eax
shr eax, cl
3015,10 → 3042,10
shl eax, cl
bsf edx, eax ; next 1
jz @f
sub edx, ecx
sub edx, ebx
cmp edx, [ebp+NTFS.fileDataSize]
jnc .got ; fits inside
bsf ecx, eax
bsf ebx, eax
not eax
shr eax, cl
shl eax, cl
3028,16 → 3055,15
bsf edx, eax
jz .got ; empty
add edx, 32
sub edx, ecx
sub edx, ebx
cmp edx, [ebp+NTFS.fileDataSize]
jnc .got ; share between dwords
.again:
add edi, 4
pop ecx
jmp .small
 
.got:
push ecx ; starting bit
push ebx ; starting bit
push edi ; starting dword
.done: ; mark space
mov ecx, [esp+4]
3078,12 → 3104,24
or [edi], eax
.end:
pop eax
pop ecx
sub eax, [ebp+NTFS.BitmapBuffer]
shl eax, 3
pop edx
add eax, edx
pop edx
ret
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
 
ntfsSpaceFree:
; free disk space
3198,9 → 3236,7
mov ecx, 8
call release_pages
.end:
pop ebx
pop eax ; ret
pop eax
add esp, 12 ; ret
stc
ret
 
3215,11 → 3251,11
call ntfs_lock
stdcall ntfs_find_lfn, [esp+4]
jc ntfsNotFound
cmp [ebp+NTFS.ntfs_cur_iRecord], 16
cmp [ebp+NTFS.cur_iRecord], 16
jc ntfsDenied
bt dword [eax+fileFlags], 28
jc ntfsDenied
cmp [ebp+NTFS.ntfsFragmentCount], 1
cmp [ebp+NTFS.fragmentCount], 1
jnz ntfsUnsupported ; record fragmented
; edit directory node
mov edi, [ebp+NTFS.cur_index_buf]
3229,7 → 3265,7
mov ecx, [esi+recordRealSize]
shr ecx, 2
rep movsd
mov esi, [ebp+NTFS.ntfs_attr_offs]
mov esi, [ebp+NTFS.attr_offs]
mov cl, [esi+attributeOffset]
sub esi, [ebp+NTFS.frs_buffer]
add eax, ecx
3241,11 → 3277,11
adc edx, 0
mov [eax+fileRealSize], ecx
mov [eax+fileRealSize+4], edx
mov eax, [ebp+NTFS.ntfsLastRead]
mov eax, [ebp+NTFS.LastRead]
mov [ebp+NTFS.nodeLastRead], eax
mov [ebp+NTFS.ntfs_cur_attr], 0x80
mov [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.ntfs_cur_size], 0
mov [ebp+NTFS.cur_attr], 0x80
mov [ebp+NTFS.cur_offs], 0
mov [ebp+NTFS.cur_size], 0
call ntfs_read_attr
jc ntfsFail
mov eax, ecx
3252,7 → 3288,7
mov ecx, [ebp+NTFS.frs_buffer]
cmp word [ecx+baseRecordReuse], 0
jnz ntfsUnsupported ; auxiliary record
mov ecx, [ebp+NTFS.ntfs_attr_offs]
mov ecx, [ebp+NTFS.attr_offs]
cmp word [ecx+attributeFlags], 0
jnz ntfsUnsupported
push ebx
3266,7 → 3302,7
.resizeAttribute:
call resizeAttribute
jc ntfsErrorPop
mov ecx, [ebp+NTFS.ntfs_attr_offs]
mov ecx, [ebp+NTFS.attr_offs]
cmp byte [ecx+nonResidentFlag], 1
jz @f
mov ebx, [esp]
3278,18 → 3314,18
rep movsb
@@:
mov eax, [ebp+NTFS.frs_buffer]
mov [ebp+NTFS.ntfs_cur_buf], eax
mov [ebp+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.ntfsLastRead], eax
mov [ebp+NTFS.LastRead], eax
mov eax, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.ntfs_cur_buf], eax
mov [ebp+NTFS.cur_buf], eax
call writeRecord ; directory
pop ebx
mov ecx, [ebp+NTFS.ntfs_attr_offs]
mov ecx, [ebp+NTFS.attr_offs]
cmp byte [ecx+nonResidentFlag], 0
jz .done
mov ecx, [ebx+12]
3301,16 → 3337,16
shrd eax, edx, 9
test dword[ebx+4], 1FFh
jz .aligned
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
mov [ebp+NTFS.cur_offs], eax
mov [ebp+NTFS.cur_size], 1
lea edi, [ebp+NTFS.bitmap_buf]
mov [ebp+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.ntfs_cur_read]
sub eax, [ebp+NTFS.cur_read]
neg eax
push ecx
cmp ecx, eax
3320,8 → 3356,8
sub [esp], ecx
rep movsb
push ebx
mov eax, [ebp+NTFS.ntfsLastRead]
lea ebx, [ebp+NTFS.ntfs_bitmap_buf]
mov eax, [ebp+NTFS.LastRead]
lea ebx, [ebp+NTFS.bitmap_buf]
mov ecx, 1
xor edx, edx
call fs_write64_app
3336,29 → 3372,29
.aligned:
push ecx
shr ecx, 9
mov [ebp+NTFS.ntfs_cur_offs], eax
mov [ebp+NTFS.ntfs_cur_size], ecx
mov [ebp+NTFS.ntfs_cur_buf], esi
mov [ebp+NTFS.cur_offs], eax
mov [ebp+NTFS.cur_size], ecx
mov [ebp+NTFS.cur_buf], esi
add eax, ecx
push eax
mov [ebp+NTFS.ntfsWriteAttr], 1
mov [ebp+NTFS.bWriteAttr], 1
call ntfs_read_attr.continue
mov [ebp+NTFS.ntfsWriteAttr], 0
pop [ebp+NTFS.ntfs_cur_offs]
mov [ebp+NTFS.bWriteAttr], 0
pop [ebp+NTFS.cur_offs]
pop ecx
jc ntfsDevice
and ecx, 1FFh
jz .done
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
add esi, [ebp+NTFS.cur_read]
mov [ebp+NTFS.cur_size], 1
lea edi, [ebp+NTFS.bitmap_buf]
mov [ebp+NTFS.cur_buf], edi
call ntfs_read_attr.continue
jc ntfsDevice
rep movsb
push ebx
mov eax, [ebp+NTFS.ntfsLastRead]
lea ebx, [ebp+NTFS.ntfs_bitmap_buf]
mov eax, [ebp+NTFS.LastRead]
lea ebx, [ebp+NTFS.bitmap_buf]
mov ecx, 1
xor edx, edx
call fs_write64_app
3378,13 → 3414,13
call ntfs_lock
stdcall ntfs_find_lfn, [esp+4]
jc ntfsNotFound
cmp [ebp+NTFS.ntfs_cur_iRecord], 16
cmp [ebp+NTFS.cur_iRecord], 16
jc ntfsDenied
cmp [ebp+NTFS.ntfsFragmentCount], 1
cmp [ebp+NTFS.fragmentCount], 1
jnz ntfsUnsupported ; record fragmented
test byte [eax+indexFlags], 1
jnz ntfsUnsupported ; index has a subnode
mov edx, [ebp+NTFS.ntfs_cur_iRecord]
mov edx, [ebp+NTFS.cur_iRecord]
shr edx, 3
cmp edx, [ebp+NTFS.mftBitmapSize]
jnc ntfsUnsupported
3403,7 → 3439,7
shr ecx, 2
rep movsd
mov esi, [ebp+NTFS.cur_index_buf]
mov edi, [ebp+NTFS.ntfs_attr_offs]
mov edi, [ebp+NTFS.attr_offs]
sub edi, [ebp+NTFS.frs_buffer]
add edi, esi
sub [edi+sizeWithHeader], edx
3410,8 → 3446,8
sub [edi+sizeWithoutHeader], edx
mov cl, [edi+attributeOffset]
add edi, ecx
sub [edi+16+nodeRealSize], edx
sub [edi+16+nodeAllocatedSize], edx
sub [edi+rootNode+nodeRealSize], edx
sub [edi+rootNode+nodeAllocatedSize], edx
sub eax, esi
add eax, edi
sub [esi+recordRealSize], edx
3419,9 → 3455,10
jmp @f
 
.indexRecord:
sub [edi+28], edx
mov ecx, [edi+28]
add ecx, 24
add edi, recordNode+nodeRealSize
sub [edi], edx
mov ecx, [edi]
add ecx, recordNode
@@:
add ecx, [ebp+NTFS.cur_index_buf]
sub ecx, eax
3430,18 → 3467,18
add esi, edx
mov edi, eax
rep movsd
mov eax, [ebp+NTFS.ntfsLastRead]
mov eax, [ebp+NTFS.LastRead]
mov [ebp+NTFS.nodeLastRead], eax
; examine file record
mov [ebp+NTFS.ntfs_cur_attr], 0x80
mov [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.ntfs_cur_size], 0
mov [ebp+NTFS.cur_attr], 0x80
mov [ebp+NTFS.cur_offs], 0
mov [ebp+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.ntfs_attr_offs]
mov esi, [ebp+NTFS.attr_offs]
cmp byte [esi+nonResidentFlag], 0
jz .writeBitmapMFT
movzx eax, byte [esi+dataRunsOffset]
3462,18 → 3499,18
jmp .writeBitmapMFT
 
.folder: ; empty?
lea esi, [ebp+NTFS.ntfs_bitmap_buf]
mov [ebp+NTFS.ntfs_cur_buf], esi
mov [ebp+NTFS.ntfs_cur_attr], 0x90
mov [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.ntfs_cur_size], 1
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
call ntfs_read_attr
cmp [ebp+NTFS.ntfs_cur_read], 48
cmp [ebp+NTFS.cur_read], 48
jnz ntfsDenied
test byte [esi+32+indexFlags], 1
jnz ntfsDenied
.writeBitmapMFT: ; "delete" file record
mov eax, [ebp+NTFS.ntfs_cur_iRecord]
mov eax, [ebp+NTFS.cur_iRecord]
mov ecx, eax
shr eax, 3
and ecx, 7
3488,14 → 3525,14
xor edx, edx
call fs_write64_sys
mov esi, [ebp+NTFS.frs_buffer]
mov [ebp+NTFS.ntfs_cur_buf], esi
mov [ebp+NTFS.cur_buf], esi
mov byte [esi+recordFlags], 0
call writeRecord
; write directory node
mov eax, [ebp+NTFS.nodeLastRead]
mov [ebp+NTFS.ntfsLastRead], eax
mov [ebp+NTFS.LastRead], eax
mov eax, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.ntfs_cur_buf], eax
mov [ebp+NTFS.cur_buf], eax
call writeRecord
jmp ntfsDone
 
3510,11 → 3547,11
call ntfs_lock
stdcall ntfs_find_lfn, [esp+4]
jc ntfsNotFound
cmp [ebp+NTFS.ntfs_cur_iRecord], 16
cmp [ebp+NTFS.cur_iRecord], 16
jc ntfsDenied
bt dword [eax+fileFlags], 28
jc ntfsDenied
cmp [ebp+NTFS.ntfsFragmentCount], 1
cmp [ebp+NTFS.fragmentCount], 1
jnz ntfsUnsupported ; record fragmented
; edit directory node
mov edi, [ebp+NTFS.cur_index_buf]
3524,7 → 3561,7
mov ecx, [esi+recordRealSize]
shr ecx, 2
rep movsd
mov esi, [ebp+NTFS.ntfs_attr_offs]
mov esi, [ebp+NTFS.attr_offs]
mov cl, [esi+attributeOffset]
sub esi, [ebp+NTFS.frs_buffer]
add eax, ecx
3534,11 → 3571,11
mov edx, [ebx+8]
mov [eax+fileRealSize], ecx
mov [eax+fileRealSize+4], edx
mov eax, [ebp+NTFS.ntfsLastRead]
mov eax, [ebp+NTFS.LastRead]
mov [ebp+NTFS.nodeLastRead], eax
mov [ebp+NTFS.ntfs_cur_attr], 0x80
mov [ebp+NTFS.ntfs_cur_offs], 0
mov [ebp+NTFS.ntfs_cur_size], 0
mov [ebp+NTFS.cur_attr], 0x80
mov [ebp+NTFS.cur_offs], 0
mov [ebp+NTFS.cur_size], 0
call ntfs_read_attr
jc ntfsFail
mov eax, ecx
3545,7 → 3582,7
mov ecx, [ebp+NTFS.frs_buffer]
cmp word [ecx+baseRecordReuse], 0
jnz ntfsUnsupported ; auxiliary record
mov ecx, [ebp+NTFS.ntfs_attr_offs]
mov ecx, [ebp+NTFS.attr_offs]
cmp word [ecx+attributeFlags], 0
jnz ntfsUnsupported
cmp byte [ecx+nonResidentFlag], 0
3556,7 → 3593,7
jnc .resizeAttribute
mov eax, [ecx+attributeRealSize]
mov ecx, [ebp+NTFS.sectors_per_cluster]
mov [ebp+NTFS.ntfs_cur_size], ecx
mov [ebp+NTFS.cur_size], ecx
shl ecx, 9
div ecx
test edx, edx
3564,28 → 3601,28
push edx
push ecx
mul [ebp+NTFS.sectors_per_cluster]
mov [ebp+NTFS.ntfs_cur_offs], eax
mov [ebp+NTFS.cur_offs], eax
stdcall kernel_alloc, ecx
pop ecx
pop edi
sub ecx, edi
add edi, eax
mov [ebp+NTFS.ntfs_cur_buf], eax
push [ebp+NTFS.ntfsLastRead]
mov [ebp+NTFS.cur_buf], eax
push [ebp+NTFS.LastRead]
call ntfs_read_attr.continue
jc @f
xor eax, eax
rep stosb
push ebx
mov eax, [ebp+NTFS.ntfsLastRead]
mov ebx, [ebp+NTFS.ntfs_cur_buf]
mov eax, [ebp+NTFS.LastRead]
mov ebx, [ebp+NTFS.cur_buf]
mov ecx, [ebp+NTFS.sectors_per_cluster]
xor edx, edx
call fs_write64_app
pop ebx
@@:
pop [ebp+NTFS.ntfsLastRead]
stdcall kernel_free, [ebp+NTFS.ntfs_cur_buf]
pop [ebp+NTFS.LastRead]
stdcall kernel_free, [ebp+NTFS.cur_buf]
.aligned:
mov eax, [ebx+4]
mov edx, [ebx+8]
3593,12 → 3630,12
call resizeAttribute
jc ntfsError
mov eax, [ebp+NTFS.frs_buffer]
mov [ebp+NTFS.ntfs_cur_buf], eax
mov [ebp+NTFS.cur_buf], eax
call writeRecord ; file
mov eax, [ebp+NTFS.nodeLastRead]
mov [ebp+NTFS.ntfsLastRead], eax
mov [ebp+NTFS.LastRead], eax
mov eax, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.ntfs_cur_buf], eax
mov [ebp+NTFS.cur_buf], eax
call writeRecord ; directory
call ntfsSpaceClean
jmp ntfsDone
/kernel/branches/Kolibri-acpi/fs/parse_fn.inc
5,15 → 5,6
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;-------------------------------------------------------------------------
;
; File path partial substitution (according to configuration)
;
;
; SPraid
;
;-------------------------------------------------------------------------
 
$Revision$
 
 
245,3 → 236,158
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/kernel.asm
1100,9 → 1100,6
 
first_app_found:
 
mov ecx, bios_fb
call set_framebuffer
 
; START MULTITASKING
 
; A 'All set - press ESC to start' messages if need
1632,9 → 1629,13
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,8 → 127,9
jnc .create_page_tables
 
mov edx, 0x00400000
or esi, PG_GLOBAL+PDE_LARGE+PAT_WC+PG_UWR
or esi, PG_GLOBAL+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
188,6 → 189,8
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)