Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 1397 → Rev 1396

/kernel/trunk/fs/ext2.inc
40,14 → 40,6
FS_FT_ASCII = 0 ;имя в ascii
FS_FT_UNICODE = 1 ;имя в unicode
 
uglobal
EXT2_files_in_folder dd ? ;всего файлов в папке
EXT2_read_in_folder dd ? ;сколько файлов "считали"
EXT2_end_block dd ? ;конец очередного блока папки
EXT2_counter_blocks dd ?
EXT2_filename db 256 dup ?
endg
 
struct EXT2_INODE_STRUC
.i_mode dw ?
.i_uid dw ?
289,6 → 281,15
ret
 
;----------------------------------------------------------------
ext2_upcase:
cmp al, 'a'
jb .ret
cmp al, 'z'
ja .ret
and al, 0xDF ; upcase = clear 0010 0000
.ret:
ret
;----------------------------------------------------------------
; in: esi -> children
; ebx -> pointer to dir block
; out: esi -> name without parent or not_changed
302,29 → 303,24
.start_rec:
cmp [ebx + EXT2_DIR_STRUC.inode], 0
jz .next_rec
; test [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR
; jz .next_rec
 
push esi
movzx ecx, [ebx + EXT2_DIR_STRUC.name_len]
mov edi, EXT2_filename
lea esi, [ebx + EXT2_DIR_STRUC.name]
lea edi, [ebx + EXT2_DIR_STRUC.name]
inc ecx
 
call utf8toansi_str
mov ecx, edi
sub ecx, EXT2_filename ;кол-во байт в получившейся строке
 
mov edi, EXT2_filename
mov esi, [esp]
@@:
dec ecx
jecxz .test_find
dec ecx
 
lodsb
call char_toupper
 
mov ah, [edi]
inc edi
 
call ext2_upcase
xchg al, ah
call char_toupper
call ext2_upcase
cmp al, ah
je @B
@@: ;не подошло
344,6 → 340,7
inc esi
.find:
pop eax ;удаляем из стека сохраненое значение
; mov ebx, [ebx + EXT2_DIR_STRUC.inode]
.ret:
pop edi edx ecx eax
ret
363,6 → 360,13
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
uglobal
EXT2_files_in_folder dd ? ;всего файлов в папке
EXT2_read_in_folder dd ? ;сколько файлов "считали"
EXT2_end_block dd ? ;конец очередного блока папки
EXT2_counter_blocks dd ?
endg
 
ext2_HdReadFolder:
cmp byte [esi], 0
jz .doit
400,7 → 404,7
mov eax, [ebp + EXT2_INODE_STRUC.i_blocks]
mov [EXT2_counter_blocks], eax
 
add edx, 32 ; (header pointer in stack) edx = current mem for return
add edx, 32 ; заголовок будем заполнять в конце (адрес - в стеке) edx = current mem for return
xor esi, esi ; esi = номер блока по порядку
 
.new_block_folder: ;reserved label
422,7 → 426,7
jecxz .find_wanted_end
.find_wanted_cycle:
cmp [eax + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used
jz @F
je @F
inc [EXT2_files_in_folder]
@@:
movzx ebx, [eax+EXT2_DIR_STRUC.rec_len]
434,7 → 438,8
 
mov ecx, edi
.wanted_start: ; ищем first_wanted+count
jecxz .find_wanted_cycle ; ecx=0 => огромный цикл до конца папки
jecxz .wanted_end
.wanted_cycle:
cmp [eax + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used
jz .empty_rec
inc [EXT2_files_in_folder]
464,30 → 469,33
xor dword [edx], FS_FT_DIR
or dword [edx+4], FS_FT_ASCII ; symbol type in name
 
;теперь скопируем название, сконвертировав из UTF-8 в CP866
push eax ecx esi
push ecx esi ;copy name
movzx ecx, [eax + EXT2_DIR_STRUC.name_len]
lea edi, [edx + 40]
mov edi, edx
add edi, 40
lea esi, [eax + EXT2_DIR_STRUC.name]
call utf8toansi_str
;rep movsb
pop esi ecx eax
rep movsb
pop esi ecx
and byte [edi], 0
 
add edx, 40 + 264 ; go to next record
 
dec ecx ; если запись пустая ecx не надо уменьшать
.empty_rec:
movzx ebx, [eax + EXT2_DIR_STRUC.rec_len]
add eax, ebx
cmp eax, [EXT2_end_block]
jb .wanted_start
jae .end_block_wanted ;по хорошему должно быть =, но ччнш
loop .wanted_cycle
 
.end_block_wanted: ;вылетели из цикла wanted
.wanted_end: ;теперь дойдем до конца чтобы узнать сколько файлов в папке
or ecx, -1 ;цикл уже есть, просто поставим ему огромный счетчик
jmp .find_wanted_cycle
 
.end_block_find_wanted: ;вылетили из цикла find_wanted
mov ebx, [ext2_data.count_block_in_block]
sub [EXT2_counter_blocks], ebx
jz .end_dir
 
;получаем новый блок
inc esi
push ecx
mov ecx, esi
500,14 → 508,13
mov eax, ebx
add ebx, [ext2_data.block_size]
mov [EXT2_end_block], ebx
jmp .wanted_start
jmp .find_wanted_start
 
.end_block_find_wanted: ;вылетили из цикла find_wanted
.end_block_wanted: ;вылетели из цикла wanted
mov ebx, [ext2_data.count_block_in_block]
sub [EXT2_counter_blocks], ebx
jz .end_dir
 
;получаем новый блок
inc esi
push ecx
mov ecx, esi
520,7 → 527,7
mov eax, ebx
add ebx, [ext2_data.block_size]
mov [EXT2_end_block], ebx
jmp .find_wanted_start
jmp .wanted_start
 
.end_dir:
pop edx
535,55 → 542,7
rep stosd
ret
;====================== end ext2_HdReadFolder
utf8toansi_str:
; convert UTF-8 string to ASCII-string (codepage 866)
; in: ecx=length source, esi->source, edi->buffer
; destroys: eax,esi,edi
jecxz .ret
.start:
lodsw
cmp al, 0x80
jb .ascii
 
xchg al, ah
cmp ax, 0xd080
jz .yo1
cmp ax, 0xd191
jz .yo2
cmp ax, 0xd090
jb .unk
cmp ax, 0xd180
jb .rus1
cmp ax, 0xd190
jb .rus2
.unk:
mov al, '_'
jmp .doit
.yo1:
mov al, 0xf0 ; Ё capital
jmp .doit
.yo2:
mov al, 0xf1 ; ё small
jmp .doit
.rus1:
sub ax, 0xd090 - 0x80
jmp .doit
.rus2:
sub ax, 0xd18f - 0xEF
.doit:
stosb
sub ecx, 2
ja .start
ret
 
.ascii:
stosb
dec esi
dec ecx
jnz .start
.ret:
ret
 
;----------------------------------------------------------------
;
; ext2_HdRead - read hard disk
599,79 → 558,146
;
;--------------------------------------------------------------
ext2_HdRead:
xchg bx, bx
mov ebp, [ext2_data.root_inode]
 
push ecx edx ebx
.next_folder:
push esi
@@:
lodsb
test al, al
jz .find_end
cmp al, '/'
jz .find_folder
jmp @B
 
.find_end:
;установим флаг что ищем файл или очередную папку
mov edi, 1
jmp .find_any
.find_folder:
xor edi, edi
.find_any:
pop esi
 
cmp byte [esi], 0
jnz @F
jz .not_found
 
or [EXT2_counter_blocks], -1 ;счетчик блоков папки cur block of inode
mov eax, [ebp + EXT2_INODE_STRUC.i_blocks] ;убывающий счетчик блоков
add eax, [ext2_data.count_block_in_block]
mov [EXT2_end_block], eax
.next_block_folder:
mov eax, [ext2_data.count_block_in_block]
sub [EXT2_end_block], eax
jz .not_found
inc [EXT2_counter_blocks]
mov ecx, [EXT2_counter_blocks]
call ext2_get_inode_block
 
mov eax, ecx
mov ebx, [ext2_data.ext2_save_block] ;ebx = cur dir record
call ext2_get_block
 
mov eax, esi
call ext2_test_block_by_name
cmp eax, esi ;нашли имя?
je .next_block_folder
 
cmp [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_REG_FILE
je .test_file
cmp [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR
jne .this_is_nofile
 
;.test_dir:
cmp edi, 0
jne .this_is_nofile
 
mov eax, [ebx + EXT2_DIR_STRUC.inode]
mov ebx, [ext2_data.ext2_save_inode] ;все же папка.
call ext2_get_inode
mov ebp, ebx
jmp .next_folder
 
.test_file:
cmp edi, 0
je .not_found
 
mov eax, [ebx + EXT2_DIR_STRUC.inode]
mov ebx, [ext2_data.ext2_save_inode]
call ext2_get_inode
jmp .get_file
 
.not_found:
pop edx ecx ebx
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
.this_is_nofile:
pop edx ecx ebx
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
 
@@:
push ecx ebx
call ext2_find_lfn
pop ebx ecx
jnc .doit
;.not_found:
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
 
.doit:
test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFREG
jz .this_is_nofile
 
;-----------------------------------------------------------------------------final step
.get_file:
mov ebp ,ebx
 
mov edi, edx ; edi = pointer to return mem
mov esi, ebx ; esi = pointer to first_wanted
;pop eax edi ecx ; первый_блок память кол-во_байт
mov esi, [esp]
mov edi, [esp + 8] ;edi = нужно считать байт
 
;///// сравним хватит ли нам файла или нет
mov ebx, [esi+4]
mov eax, [esi] ; ebx : eax - стартовый номер байта
 
; mov edx, [ebp + EXT2_INODE_STRUC.i_dir_acl]
; mov ecx, [ebp + EXT2_INODE_STRUC.i_size] ;edx : ecx - размер файла
mov edx, [ebp + EXT2_INODE_STRUC.i_dir_acl]
mov ecx, [ebp + EXT2_INODE_STRUC.i_size] ;edx : ecx - размер файла
 
cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
cmp edx, ebx
ja .size_great
jb .size_less
 
cmp [ebp + EXT2_INODE_STRUC.i_size], eax
cmp ecx, eax
ja .size_great
 
.size_less:
pop ecx
xor ebx, ebx
add esp, 12
mov ebx, 0
mov eax, 6 ;EOF
ret
.size_great:
add eax, ecx ;add to first_wanted кол-во байт для чтения
adc ebx, 0
 
cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
;прибавим к старту кол-во байт для чтения
add eax, edi
jnc @F
inc ebx
@@:
cmp edx, ebx
ja .size_great_great
jb .size_great_less
cmp [ebp + EXT2_INODE_STRUC.i_size], eax
jae .size_great_great ; а если равно, то не важно куда
 
cmp ecx, eax
jae .size_great_great
;jmp .size_great_less
; а если равно, то не важно куда
.size_great_less:
or [EXT2_files_in_folder], 1 ;читаем по границе размера
mov ecx, [ebp + EXT2_INODE_STRUC.i_size]
sub ecx, [esi] ;(размер - старт)
sub ecx, [esi]
pop eax edi edx ;ecx - не меняем
jmp @F
 
.size_great_great:
and [EXT2_files_in_folder], 0 ;читаем столько сколько запросили
and [EXT2_files_in_folder], 0 ;читаем нормально
pop eax edi ecx
 
@@:
push ecx ;save for return
test esi, esi
jz .zero_start
push ecx ;сохраним размер считанных байт в стеке
test eax, eax
je .zero_start
 
;пока делаем п..ц криво =)
mov edx, [esi+4]
mov eax, [esi]
mov edx, [eax+4]
mov eax, [eax]
div [ext2_data.block_size]
 
mov [EXT2_counter_blocks], eax ;номер блока запоминаем
686,7 → 712,7
add ebx, edx
 
neg edx
add edx,[ext2_data.block_size] ;block_size - стартовый байт = сколько байт 1-го блока
add edx,[ext2_data.block_size] ;block_size - стартоый блок = сколько байт 1-го блока
cmp ecx, edx
jbe .only_one_block
 
700,14 → 726,14
 
.zero_start:
mov eax, ecx
mov ebx, edi ;чтение блока прям в ebx
;теперь в eax кол-во оставшихся байт для чтения
@@:
mov ebx, edi ;чтение блока прям в ->ebx
xor edx, edx
div [ext2_data.block_size] ;кол-во байт в последнем блоке (остаток) в edx
mov edi, eax ;кол-во целых блоков в edi
mov [EXT2_end_block], eax ;кол-во целых блоков в EXT2_end_block
@@:
test edi, edi
cmp [EXT2_end_block], 0
jz .finish_block
inc [EXT2_counter_blocks]
mov ecx, [EXT2_counter_blocks]
717,12 → 743,12
call ext2_get_block
add ebx, [ext2_data.block_size]
 
dec edi
dec [EXT2_end_block]
jmp @B
 
.finish_block: ;в edx - кол-во байт в последнем блоке
test edx, edx
jz .end_read
cmp edx, 0
je .end_read
 
mov ecx, [EXT2_counter_blocks]
inc ecx
795,6 → 821,7
mov ebx, [ext2_data.ext2_save_inode]
call ext2_get_inode
mov ebp, ebx
.ret:
clc
ret