40,6 → 40,14 |
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 ? |
281,15 → 289,6 |
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 |
303,24 → 302,29 |
.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] |
lea edi, [ebx + EXT2_DIR_STRUC.name] |
inc ecx |
mov edi, EXT2_filename |
lea esi, [ebx + EXT2_DIR_STRUC.name] |
|
call utf8toansi_str |
mov ecx, edi |
sub ecx, EXT2_filename ;кол-во байт в получившейся строке |
|
mov edi, EXT2_filename |
mov esi, [esp] |
@@: |
jecxz .test_find |
dec ecx |
jecxz .test_find |
|
lodsb |
call char_toupper |
|
mov ah, [edi] |
inc edi |
|
call ext2_upcase |
xchg al, ah |
call ext2_upcase |
call char_toupper |
cmp al, ah |
je @B |
@@: ;не подошло |
340,7 → 344,6 |
inc esi |
.find: |
pop eax ;удаляем из стека сохраненое значение |
; mov ebx, [ebx + EXT2_DIR_STRUC.inode] |
.ret: |
pop edi edx ecx eax |
ret |
360,13 → 363,6 |
; 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 |
404,7 → 400,7 |
mov eax, [ebp + EXT2_INODE_STRUC.i_blocks] |
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 = номер блока по порядку |
|
.new_block_folder: ;reserved label |
426,7 → 422,7 |
jecxz .find_wanted_end |
.find_wanted_cycle: |
cmp [eax + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used |
je @F |
jz @F |
inc [EXT2_files_in_folder] |
@@: |
movzx ebx, [eax+EXT2_DIR_STRUC.rec_len] |
438,8 → 434,7 |
|
mov ecx, edi |
.wanted_start: ; ищем first_wanted+count |
jecxz .wanted_end |
.wanted_cycle: |
jecxz .find_wanted_cycle ; ecx=0 => огромный цикл до конца папки |
cmp [eax + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used |
jz .empty_rec |
inc [EXT2_files_in_folder] |
469,33 → 464,30 |
xor dword [edx], FS_FT_DIR |
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] |
mov edi, edx |
add edi, 40 |
lea edi, [edx + 40] |
lea esi, [eax + EXT2_DIR_STRUC.name] |
rep movsb |
pop esi ecx |
call utf8toansi_str |
;rep movsb |
pop esi ecx eax |
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] |
jae .end_block_wanted ;по хорошему должно быть =, но ччнш |
loop .wanted_cycle |
jb .wanted_start |
|
.wanted_end: ;теперь дойдем до конца чтобы узнать сколько файлов в папке |
or ecx, -1 ;цикл уже есть, просто поставим ему огромный счетчик |
jmp .find_wanted_cycle |
|
.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 |
508,13 → 500,14 |
mov eax, ebx |
add ebx, [ext2_data.block_size] |
mov [EXT2_end_block], ebx |
jmp .find_wanted_start |
jmp .wanted_start |
|
.end_block_wanted: ;вылетели из цикла wanted |
.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 |
527,7 → 520,7 |
mov eax, ebx |
add ebx, [ext2_data.block_size] |
mov [EXT2_end_block], ebx |
jmp .wanted_start |
jmp .find_wanted_start |
|
.end_dir: |
pop edx |
542,7 → 535,55 |
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 |
558,146 → 599,79 |
; |
;-------------------------------------------------------------- |
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 |
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: |
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 |
|
;pop eax edi ecx ; первый_блок память кол-во_байт |
mov esi, [esp] |
mov edi, [esp + 8] ;edi = нужно считать байт |
mov edi, edx ; edi = pointer to return mem |
mov esi, ebx ; esi = pointer to first_wanted |
|
;///// сравним хватит ли нам файла или нет |
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 edx, ebx |
cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx |
ja .size_great |
jb .size_less |
|
cmp ecx, eax |
cmp [ebp + EXT2_INODE_STRUC.i_size], eax |
ja .size_great |
|
.size_less: |
add esp, 12 |
mov ebx, 0 |
pop ecx |
xor ebx, ebx |
mov eax, 6 ;EOF |
ret |
.size_great: |
;прибавим к старту кол-во байт для чтения |
add eax, edi |
jnc @F |
inc ebx |
@@: |
cmp edx, ebx |
add eax, ecx ;add to first_wanted кол-во байт для чтения |
adc ebx, 0 |
|
cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx |
ja .size_great_great |
jb .size_great_less |
cmp ecx, eax |
jae .size_great_great |
;jmp .size_great_less |
; а если равно, то не важно куда |
cmp [ebp + EXT2_INODE_STRUC.i_size], eax |
jae .size_great_great ; а если равно, то не важно куда |
|
.size_great_less: |
or [EXT2_files_in_folder], 1 ;читаем по границе размера |
sub ecx, [esi] |
pop eax edi edx ;ecx - не меняем |
mov ecx, [ebp + EXT2_INODE_STRUC.i_size] |
sub ecx, [esi] ;(размер - старт) |
jmp @F |
|
.size_great_great: |
and [EXT2_files_in_folder], 0 ;читаем нормально |
pop eax edi ecx |
and [EXT2_files_in_folder], 0 ;читаем столько сколько запросили |
|
@@: |
push ecx ;сохраним размер считанных байт в стеке |
test eax, eax |
je .zero_start |
push ecx ;save for return |
test esi, esi |
jz .zero_start |
|
;пока делаем п..ц криво =) |
mov edx, [eax+4] |
mov eax, [eax] |
mov edx, [esi+4] |
mov eax, [esi] |
div [ext2_data.block_size] |
|
mov [EXT2_counter_blocks], eax ;номер блока запоминаем |
712,7 → 686,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 |
|
726,14 → 700,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 [EXT2_end_block], eax ;кол-во целых блоков в EXT2_end_block |
mov edi, eax ;кол-во целых блоков в edi |
@@: |
cmp [EXT2_end_block], 0 |
test edi, edi |
jz .finish_block |
inc [EXT2_counter_blocks] |
mov ecx, [EXT2_counter_blocks] |
743,12 → 717,12 |
call ext2_get_block |
add ebx, [ext2_data.block_size] |
|
dec [EXT2_end_block] |
dec edi |
jmp @B |
|
.finish_block: ;в edx - кол-во байт в последнем блоке |
cmp edx, 0 |
je .end_read |
test edx, edx |
jz .end_read |
|
mov ecx, [EXT2_counter_blocks] |
inc ecx |
821,7 → 795,6 |
mov ebx, [ext2_data.ext2_save_inode] |
call ext2_get_inode |
mov ebp, ebx |
.ret: |
clc |
ret |
|