support russian filenames in ext2

git-svn-id: svn://kolibrios.org@1397 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
turbanoff 2010-02-08 19:51:43 +00:00
parent 96dcf55fe0
commit 0aa07aa06e

View File

@ -40,6 +40,14 @@ FS_FT_DIR = 0x10 ;это папка
FS_FT_ASCII = 0 ;имя в ascii FS_FT_ASCII = 0 ;имя в ascii
FS_FT_UNICODE = 1 ;имя в unicode 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 struct EXT2_INODE_STRUC
.i_mode dw ? .i_mode dw ?
.i_uid dw ? .i_uid dw ?
@ -281,15 +289,6 @@ ext2_get_inode:
ret 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 ; in: esi -> children
; ebx -> pointer to dir block ; ebx -> pointer to dir block
; out: esi -> name without parent or not_changed ; out: esi -> name without parent or not_changed
@ -303,24 +302,29 @@ ext2_test_block_by_name:
.start_rec: .start_rec:
cmp [ebx + EXT2_DIR_STRUC.inode], 0 cmp [ebx + EXT2_DIR_STRUC.inode], 0
jz .next_rec jz .next_rec
; test [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR
; jz .next_rec
push esi push esi
movzx ecx, [ebx + EXT2_DIR_STRUC.name_len] movzx ecx, [ebx + EXT2_DIR_STRUC.name_len]
lea edi, [ebx + EXT2_DIR_STRUC.name] mov edi, EXT2_filename
inc ecx lea esi, [ebx + EXT2_DIR_STRUC.name]
call utf8toansi_str
mov ecx, edi
sub ecx, EXT2_filename ;кол-во байт в получившейся строке
mov edi, EXT2_filename
mov esi, [esp]
@@: @@:
dec ecx
jecxz .test_find jecxz .test_find
dec ecx
lodsb lodsb
call char_toupper
mov ah, [edi] mov ah, [edi]
inc edi inc edi
call ext2_upcase
xchg al, ah xchg al, ah
call ext2_upcase call char_toupper
cmp al, ah cmp al, ah
je @B je @B
@@: ;не подошло @@: ;не подошло
@ -340,7 +344,6 @@ ext2_test_block_by_name:
inc esi inc esi
.find: .find:
pop eax ;удаляем из стека сохраненое значение pop eax ;удаляем из стека сохраненое значение
; mov ebx, [ebx + EXT2_DIR_STRUC.inode]
.ret: .ret:
pop edi edx ecx eax pop edi edx ecx eax
ret ret
@ -360,13 +363,6 @@ ext2_test_block_by_name:
; eax = 0 ok read or other = errormsg ; 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: ext2_HdReadFolder:
cmp byte [esi], 0 cmp byte [esi], 0
jz .doit jz .doit
@ -404,7 +400,7 @@ ext2_HdReadFolder:
mov eax, [ebp + EXT2_INODE_STRUC.i_blocks] mov eax, [ebp + EXT2_INODE_STRUC.i_blocks]
mov [EXT2_counter_blocks], eax mov [EXT2_counter_blocks], eax
add edx, 32 ; заголовок будем заполнять в конце (адрес - в стеке) edx = current mem for return add edx, 32 ; (header pointer in stack) edx = current mem for return
xor esi, esi ; esi = номер блока по порядку xor esi, esi ; esi = номер блока по порядку
.new_block_folder: ;reserved label .new_block_folder: ;reserved label
@ -426,7 +422,7 @@ ext2_HdReadFolder:
jecxz .find_wanted_end jecxz .find_wanted_end
.find_wanted_cycle: .find_wanted_cycle:
cmp [eax + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used cmp [eax + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used
je @F jz @F
inc [EXT2_files_in_folder] inc [EXT2_files_in_folder]
@@: @@:
movzx ebx, [eax+EXT2_DIR_STRUC.rec_len] movzx ebx, [eax+EXT2_DIR_STRUC.rec_len]
@ -438,8 +434,7 @@ ext2_HdReadFolder:
mov ecx, edi mov ecx, edi
.wanted_start: ; ищем first_wanted+count .wanted_start: ; ищем first_wanted+count
jecxz .wanted_end jecxz .find_wanted_cycle ; ecx=0 => огромный цикл до конца папки
.wanted_cycle:
cmp [eax + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used cmp [eax + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used
jz .empty_rec jz .empty_rec
inc [EXT2_files_in_folder] inc [EXT2_files_in_folder]
@ -469,26 +464,43 @@ ext2_HdReadFolder:
xor dword [edx], FS_FT_DIR xor dword [edx], FS_FT_DIR
or dword [edx+4], FS_FT_ASCII ; symbol type in name or dword [edx+4], FS_FT_ASCII ; symbol type in name
push ecx esi ;copy name ;теперь скопируем название, сконвертировав из UTF-8 в CP866
push eax ecx esi
movzx ecx, [eax + EXT2_DIR_STRUC.name_len] movzx ecx, [eax + EXT2_DIR_STRUC.name_len]
mov edi, edx lea edi, [edx + 40]
add edi, 40
lea esi, [eax + EXT2_DIR_STRUC.name] lea esi, [eax + EXT2_DIR_STRUC.name]
rep movsb call utf8toansi_str
pop esi ecx ;rep movsb
pop esi ecx eax
and byte [edi], 0 and byte [edi], 0
add edx, 40 + 264 ; go to next record add edx, 40 + 264 ; go to next record
dec ecx ; если запись пустая ecx не надо уменьшать
.empty_rec: .empty_rec:
movzx ebx, [eax + EXT2_DIR_STRUC.rec_len] movzx ebx, [eax + EXT2_DIR_STRUC.rec_len]
add eax, ebx add eax, ebx
cmp eax, [EXT2_end_block] cmp eax, [EXT2_end_block]
jae .end_block_wanted ;по хорошему должно быть =, но ччнш jb .wanted_start
loop .wanted_cycle
.wanted_end: ;теперь дойдем до конца чтобы узнать сколько файлов в папке .end_block_wanted: ;вылетели из цикла wanted
or ecx, -1 ;цикл уже есть, просто поставим ему огромный счетчик mov ebx, [ext2_data.count_block_in_block]
jmp .find_wanted_cycle sub [EXT2_counter_blocks], ebx
jz .end_dir
inc esi
push ecx
mov ecx, esi
call ext2_get_inode_block
mov eax, ecx
mov ebx, [ext2_data.ext2_save_block]
call ext2_get_block
pop ecx
dec ecx
mov eax, ebx
add ebx, [ext2_data.block_size]
mov [EXT2_end_block], ebx
jmp .wanted_start
.end_block_find_wanted: ;вылетили из цикла find_wanted .end_block_find_wanted: ;вылетили из цикла find_wanted
mov ebx, [ext2_data.count_block_in_block] mov ebx, [ext2_data.count_block_in_block]
@ -510,25 +522,6 @@ ext2_HdReadFolder:
mov [EXT2_end_block], ebx mov [EXT2_end_block], ebx
jmp .find_wanted_start jmp .find_wanted_start
.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
call ext2_get_inode_block
mov eax, ecx
mov ebx, [ext2_data.ext2_save_block]
call ext2_get_block
pop ecx
dec ecx
mov eax, ebx
add ebx, [ext2_data.block_size]
mov [EXT2_end_block], ebx
jmp .wanted_start
.end_dir: .end_dir:
pop edx pop edx
mov ebx, [EXT2_read_in_folder] mov ebx, [EXT2_read_in_folder]
@ -542,6 +535,54 @@ ext2_HdReadFolder:
rep stosd rep stosd
ret ret
;====================== end ext2_HdReadFolder ;====================== 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
;---------------------------------------------------------------- ;----------------------------------------------------------------
; ;
@ -558,146 +599,79 @@ ext2_HdReadFolder:
; ;
;-------------------------------------------------------------- ;--------------------------------------------------------------
ext2_HdRead: 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 cmp byte [esi], 0
jz .not_found jnz @F
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: .this_is_nofile:
pop edx ecx ebx
or ebx, -1 or ebx, -1
mov eax, ERROR_ACCESS_DENIED mov eax, ERROR_ACCESS_DENIED
ret ret
;-----------------------------------------------------------------------------final step @@:
.get_file: push ecx ebx
mov ebp ,ebx call ext2_find_lfn
pop ebx ecx
jnc .doit
;.not_found:
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
;pop eax edi ecx ; первый_блок память кол-во_байт .doit:
mov esi, [esp] test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFREG
mov edi, [esp + 8] ;edi = нужно считать байт jz .this_is_nofile
;-----------------------------------------------------------------------------final step
mov edi, edx ; edi = pointer to return mem
mov esi, ebx ; esi = pointer to first_wanted
;///// сравним хватит ли нам файла или нет ;///// сравним хватит ли нам файла или нет
mov ebx, [esi+4] mov ebx, [esi+4]
mov eax, [esi] ; ebx : eax - стартовый номер байта mov eax, [esi] ; ebx : eax - стартовый номер байта
mov edx, [ebp + EXT2_INODE_STRUC.i_dir_acl] ; mov edx, [ebp + EXT2_INODE_STRUC.i_dir_acl]
mov ecx, [ebp + EXT2_INODE_STRUC.i_size] ;edx : ecx - размер файла ; mov ecx, [ebp + EXT2_INODE_STRUC.i_size] ;edx : ecx - размер файла
cmp edx, ebx cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
ja .size_great ja .size_great
jb .size_less jb .size_less
cmp ecx, eax cmp [ebp + EXT2_INODE_STRUC.i_size], eax
ja .size_great ja .size_great
.size_less: .size_less:
add esp, 12 pop ecx
mov ebx, 0 xor ebx, ebx
mov eax, 6 ;EOF mov eax, 6 ;EOF
ret ret
.size_great: .size_great:
;прибавим к старту кол-во байт для чтения add eax, ecx ;add to first_wanted кол-во байт для чтения
add eax, edi adc ebx, 0
jnc @F
inc ebx cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
@@:
cmp edx, ebx
ja .size_great_great ja .size_great_great
jb .size_great_less jb .size_great_less
cmp ecx, eax cmp [ebp + EXT2_INODE_STRUC.i_size], eax
jae .size_great_great jae .size_great_great ; а если равно, то не важно куда
;jmp .size_great_less
; а если равно, то не важно куда
.size_great_less: .size_great_less:
or [EXT2_files_in_folder], 1 ;читаем по границе размера or [EXT2_files_in_folder], 1 ;читаем по границе размера
sub ecx, [esi] mov ecx, [ebp + EXT2_INODE_STRUC.i_size]
pop eax edi edx ;ecx - не меняем sub ecx, [esi] ;(размер - старт)
jmp @F jmp @F
.size_great_great: .size_great_great:
and [EXT2_files_in_folder], 0 ;читаем нормально and [EXT2_files_in_folder], 0 ;читаем столько сколько запросили
pop eax edi ecx
@@: @@:
push ecx ;сохраним размер считанных байт в стеке push ecx ;save for return
test eax, eax test esi, esi
je .zero_start jz .zero_start
;пока делаем п..ц криво =) ;пока делаем п..ц криво =)
mov edx, [eax+4] mov edx, [esi+4]
mov eax, [eax] mov eax, [esi]
div [ext2_data.block_size] div [ext2_data.block_size]
mov [EXT2_counter_blocks], eax ;номер блока запоминаем mov [EXT2_counter_blocks], eax ;номер блока запоминаем
@ -705,14 +679,14 @@ ext2_HdRead:
push ecx push ecx
mov ecx, eax mov ecx, eax
call ext2_get_inode_block call ext2_get_inode_block
mov ebx , [ext2_data.ext2_save_block] mov ebx, [ext2_data.ext2_save_block]
mov eax, ecx mov eax, ecx
call ext2_get_block call ext2_get_block
pop ecx pop ecx
add ebx, edx add ebx, edx
neg edx neg edx
add edx,[ext2_data.block_size] ;block_size - стартоый блок = сколько байт 1-го блока add edx,[ext2_data.block_size] ;block_size - стартовый байт = сколько байт 1-го блока
cmp ecx, edx cmp ecx, edx
jbe .only_one_block jbe .only_one_block
@ -726,29 +700,29 @@ ext2_HdRead:
.zero_start: .zero_start:
mov eax, ecx mov eax, ecx
mov ebx, edi ;чтение блока прям в ebx
;теперь в eax кол-во оставшихся байт для чтения ;теперь в eax кол-во оставшихся байт для чтения
@@: @@:
mov ebx, edi ;чтение блока прям в ->ebx
xor edx, edx xor edx, edx
div [ext2_data.block_size] ;кол-во байт в последнем блоке (остаток) в edx div [ext2_data.block_size] ;кол-во байт в последнем блоке (остаток) в edx
mov [EXT2_end_block], eax ;кол-во целых блоков в EXT2_end_block mov edi, eax ;кол-во целых блоков в edi
@@: @@:
cmp [EXT2_end_block], 0 test edi, edi
jz .finish_block jz .finish_block
inc [EXT2_counter_blocks] inc [EXT2_counter_blocks]
mov ecx, [EXT2_counter_blocks] mov ecx, [EXT2_counter_blocks]
call ext2_get_inode_block call ext2_get_inode_block
mov eax, ecx ;а ebx уже забит нужным значением mov eax, ecx ;а ebx уже забит нужным значением
call ext2_get_block call ext2_get_block
add ebx, [ext2_data.block_size] add ebx, [ext2_data.block_size]
dec [EXT2_end_block] dec edi
jmp @B jmp @B
.finish_block: ;в edx - кол-во байт в последнем блоке .finish_block: ;в edx - кол-во байт в последнем блоке
cmp edx, 0 test edx, edx
je .end_read jz .end_read
mov ecx, [EXT2_counter_blocks] mov ecx, [EXT2_counter_blocks]
inc ecx inc ecx
@ -821,7 +795,6 @@ ext2_find_lfn:
mov ebx, [ext2_data.ext2_save_inode] mov ebx, [ext2_data.ext2_save_inode]
call ext2_get_inode call ext2_get_inode
mov ebp, ebx mov ebp, ebx
.ret:
clc clc
ret ret