Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 4922 → Rev 4923

/kernel/branches/kolibri-process/fs/iso9660.inc
5,20 → 5,17
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 3742 $
$Revision: 4700 $
 
 
;-----------------------------------------------------------------------------
uglobal
cd_current_pointer_of_input dd 0
cd_current_pointer_of_input_2 dd 0
cd_mem_location dd 0
cd_counter_block dd 0
IDE_Channel_1 db 0
IDE_Channel_2 db 0
endg
 
;-----------------------------------------------------------------------------
reserve_cd:
 
cli
cmp [cd_status], 0
je reserve_ok2
26,9 → 23,8
sti
call change_task
jmp reserve_cd
 
;-----------------------------------------------------------------------------
reserve_ok2:
 
push eax
mov eax, [CURRENT_TASK]
shl eax, 5
37,48 → 33,105
pop eax
sti
ret
;-----------------------------------------------------------------------------
reserve_cd_channel:
pushad
mov eax, [cdpos]
dec eax
shr eax, 2
 
reserve_cd_channel:
test eax, eax
jnz .1
 
cmp [ChannelNumber], 1
jne .IDE_Channel_2
.IDE_Channel_1:
pushad
jne @f
 
mov ecx, ide_channel1_mutex
jmp .mutex_lock
;--------------------------------------
@@:
mov ecx, ide_channel2_mutex
jmp .mutex_lock
;--------------------------------------
.1:
dec eax
jnz .2
 
cmp [ChannelNumber], 1
jne @f
 
mov ecx, ide_channel3_mutex
jmp .mutex_lock
;--------------------------------------
@@:
mov ecx, ide_channel4_mutex
jmp .mutex_lock
;--------------------------------------
.2:
cmp [ChannelNumber], 1
jne @f
 
mov ecx, ide_channel5_mutex
jmp .mutex_lock
;--------------------------------------
@@:
mov ecx, ide_channel6_mutex
.mutex_lock:
call mutex_lock
mov [IDE_Channel_1], 1
popad
ret
.IDE_Channel_2:
;-----------------------------------------------------------------------------
free_cd_channel:
pushad
mov ecx, ide_channel2_mutex
call mutex_lock
mov [IDE_Channel_2], 1
popad
ret
mov eax, [cdpos]
dec eax
shr eax, 2
 
free_cd_channel:
test eax, eax
jnz .1
 
cmp [ChannelNumber], 1
jne .IDE_Channel_2
.IDE_Channel_1:
mov [IDE_Channel_1], 0
pushad
jne @f
 
mov ecx, ide_channel1_mutex
call mutex_unlock
popad
ret
.IDE_Channel_2:
mov [IDE_Channel_2], 0
pushad
jmp .mutex_unlock
;--------------------------------------
@@:
mov ecx, ide_channel2_mutex
jmp .mutex_unlock
;--------------------------------------
.1:
dec eax
jnz .2
 
cmp [ChannelNumber], 1
jne @f
 
mov ecx, ide_channel3_mutex
jmp .mutex_unlock
;--------------------------------------
@@:
mov ecx, ide_channel4_mutex
jmp .mutex_unlock
;--------------------------------------
.2:
cmp [ChannelNumber], 1
jne @f
 
mov ecx, ide_channel5_mutex
jmp .mutex_unlock
;--------------------------------------
@@:
mov ecx, ide_channel6_mutex
.mutex_unlock:
call mutex_unlock
popad
ret
 
;-----------------------------------------------------------------------------
uglobal
cd_status dd 0
endg
 
;----------------------------------------------------------------
;-----------------------------------------------------------------------------
;
; fs_CdRead - LFN variant for reading CD disk
;
91,91 → 144,114
; ret ebx = bytes read or 0xffffffff file not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
;-----------------------------------------------------------------------------
fs_CdRead:
push edi
cmp byte [esi], 0
jnz @f
;--------------------------------------
.noaccess:
pop edi
;--------------------------------------
.noaccess_2:
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
 
;--------------------------------------
.noaccess_3:
pop eax edx ecx edi
jmp .noaccess_2
 
;--------------------------------------
@@:
call cd_find_lfn
jnc .found
 
pop edi
cmp [DevErrorCode], 0
jne .noaccess_2
 
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
 
;--------------------------------------
.found:
mov edi, [cd_current_pointer_of_input]
test byte [edi+25], 10b; do not allow read directories
jnz .noaccess
 
test ebx, ebx
jz .l1
 
cmp dword [ebx+4], 0
jz @f
 
xor ebx, ebx
;--------------------------------------
.reteof:
mov eax, 6; end of file
pop edi
ret
;--------------------------------------
@@:
mov ebx, [ebx]
;--------------------------------------
.l1:
push ecx edx
push 0
mov eax, [edi+10] ; реальный размер файловой секции
mov eax, [edi+10] ; real size of the file section
sub eax, ebx
jb .eof
 
cmp eax, ecx
jae @f
 
mov ecx, eax
mov byte [esp], 6
;--------------------------------------
@@:
mov eax, [edi+2]
mov [CDSectorAddress], eax
;--------------------------------------
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data
.new_sector:
test ecx, ecx
jz .done
 
sub ebx, 2048
jae .next
 
add ebx, 2048
jnz .incomplete_sector
 
cmp ecx, 2048
jb .incomplete_sector
; we may read and memmove complete sector
mov [CDDataBuf_pointer], edx
call ReadCDWRetr; читаем сектор файла
call ReadCDWRetr ; read sector of file
cmp [DevErrorCode], 0
jne .noaccess_3
 
add edx, 2048
sub ecx, 2048
;--------------------------------------
.next:
inc dword [CDSectorAddress]
jmp .new_sector
;--------------------------------------
.incomplete_sector:
; we must read and memmove incomplete sector
mov [CDDataBuf_pointer], CDDataBuf
call ReadCDWRetr; читаем сектор файла
call ReadCDWRetr ; read sector of file
cmp [DevErrorCode], 0
jne .noaccess_3
 
push ecx
add ecx, ebx
cmp ecx, 2048
jbe @f
 
mov ecx, 2048
;--------------------------------------
@@:
sub ecx, ebx
push edi esi ecx
189,19 → 265,19
pop ecx
xor ebx, ebx
jmp .next
 
;--------------------------------------
.done:
mov ebx, edx
pop eax edx ecx edi
sub ebx, edx
ret
;--------------------------------------
.eof:
mov ebx, edx
pop eax edx ecx
sub ebx, edx
jmp .reteof
 
;----------------------------------------------------------------
;-----------------------------------------------------------------------------
;
; fs_CdReadFolder - LFN variant for reading CD disk folder
;
215,30 → 291,37
; ret ebx = blocks read or 0xffffffff folder not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
;-----------------------------------------------------------------------------
fs_CdReadFolder:
push edi
call cd_find_lfn
jnc .found
 
pop edi
cmp [DevErrorCode], 0
jne .noaccess_1
 
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
;--------------------------------------
.found:
mov edi, [cd_current_pointer_of_input]
test byte [edi+25], 10b ; do not allow read directories
jnz .found_dir
 
pop edi
;--------------------------------------
.noaccess_1:
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
;--------------------------------------
.found_dir:
mov eax, [edi+2] ; eax=cluster
mov [CDSectorAddress], eax
mov eax, [edi+10] ; размер директрории
mov eax, [edi+10] ; directory size
;--------------------------------------
.doit:
; init header
push eax ecx
250,21 → 333,23
mov byte [edx], 1 ; version
mov [cd_mem_location], edx
add [cd_mem_location], 32
; начинаем переброску БДВК в УСВК
;.mainloop:
mov [cd_counter_block], dword 0
dec dword [CDSectorAddress]
push ecx
;--------------------------------------
.read_to_buffer:
inc dword [CDSectorAddress]
mov [CDDataBuf_pointer], CDDataBuf
call ReadCDWRetr ; читаем сектор директории
call ReadCDWRetr ; read sector of directory
cmp [DevErrorCode], 0
jne .noaccess_1
 
call .get_names_from_buffer
sub eax, 2048
; директория закончилась?
; directory is over?
ja .read_to_buffer
 
mov edi, [cd_counter_block]
mov [edx+8], edi
mov edi, [ebx]
272,24 → 357,30
xor eax, eax
dec ecx
js @f
 
mov al, ERROR_END_OF_FILE
;--------------------------------------
@@:
pop ecx edi
mov ebx, [edx+4]
ret
 
;--------------------------------------
.get_names_from_buffer:
mov [cd_current_pointer_of_input_2], CDDataBuf
push eax esi edi edx
;--------------------------------------
.get_names_from_buffer_1:
call cd_get_name
jc .end_buffer
 
inc dword [cd_counter_block]
mov eax, [cd_counter_block]
cmp [ebx], eax
jae .get_names_from_buffer_1
 
test ecx, ecx
jz .get_names_from_buffer_1
 
mov edi, [cd_counter_block]
mov [edx+4], edi
dec ecx
298,10 → 389,11
add edi, 40
test dword [ebx+4], 1; 0=ANSI, 1=UNICODE
jnz .unicode
; jmp .unicode
;--------------------------------------
.ansi:
cmp [cd_counter_block], 2
jbe .ansi_parent_directory
 
cld
lodsw
xchg ah, al
308,163 → 400,178
call uni2ansi_char
cld
stosb
; проверка конца файла
; check end of file
mov ax, [esi]
cmp ax, word 3B00h; сепаратор конца файла ';'
cmp ax, word 3B00h ; separator end of file ';'
je .cd_get_parameters_of_file_1
; проверка для файлов не заканчивающихся сепаратором
; check for files not ending with separator
movzx eax, byte [ebp-33]
add eax, ebp
sub eax, 34
cmp esi, eax
je .cd_get_parameters_of_file_1
; проверка конца папки
; check the end of the directory
movzx eax, byte [ebp-1]
add eax, ebp
cmp esi, eax
jb .ansi
;--------------------------------------
.cd_get_parameters_of_file_1:
mov [edi], byte 0
call cd_get_parameters_of_file
add [cd_mem_location], 304
jmp .get_names_from_buffer_1
 
;--------------------------------------
.ansi_parent_directory:
cmp [cd_counter_block], 2
je @f
 
mov [edi], byte '.'
inc edi
jmp .cd_get_parameters_of_file_1
;--------------------------------------
@@:
mov [edi], word '..'
add edi, 2
jmp .cd_get_parameters_of_file_1
 
;--------------------------------------
.unicode:
cmp [cd_counter_block], 2
jbe .unicode_parent_directory
 
cld
movsw
; проверка конца файла
; check end of file
mov ax, [esi]
cmp ax, word 3B00h; сепаратор конца файла ';'
cmp ax, word 3B00h; separator end of file ';'
je .cd_get_parameters_of_file_2
; проверка для файлов не заканчивающихся сепаратором
; check for files not ending with separator
movzx eax, byte [ebp-33]
add eax, ebp
sub eax, 34
cmp esi, eax
je .cd_get_parameters_of_file_2
; проверка конца папки
; check the end of the directory
movzx eax, byte [ebp-1]
add eax, ebp
cmp esi, eax
jb .unicode
;--------------------------------------
.cd_get_parameters_of_file_2:
mov [edi], word 0
call cd_get_parameters_of_file
add [cd_mem_location], 560
jmp .get_names_from_buffer_1
 
;--------------------------------------
.unicode_parent_directory:
cmp [cd_counter_block], 2
je @f
 
mov [edi], word 2E00h; '.'
add edi, 2
jmp .cd_get_parameters_of_file_2
;--------------------------------------
@@:
mov [edi], dword 2E002E00h; '..'
add edi, 4
jmp .cd_get_parameters_of_file_2
 
;--------------------------------------
.end_buffer:
pop edx edi esi eax
ret
 
;-----------------------------------------------------------------------------
cd_get_parameters_of_file:
mov edi, [cd_mem_location]
cd_get_parameters_of_file_1:
; получаем атрибуты файла
; get file attributes
xor eax, eax
; файл не архивировался
; file is not archived
inc eax
shl eax, 1
; это каталог?
; is a directory?
test [ebp-8], byte 2
jz .file
 
inc eax
;--------------------------------------
.file:
; метка тома не как в FAT, в этом виде отсутсвует
; файл не является системным
; not as a volume label in the FAT, in this form not available
; file is not a system
shl eax, 3
; файл является скрытым? (атрибут существование)
; file is hidden? (attribute of existence)
test [ebp-8], byte 1
jz .hidden
 
inc eax
;--------------------------------------
.hidden:
shl eax, 1
; файл всегда только для чтения, так как это CD
; file is always read-only, as this CD
inc eax
mov [edi], eax
; получаем время для файла
;час
; get the time to file
; hour
movzx eax, byte [ebp-12]
shl eax, 8
;минута
; minute
mov al, [ebp-11]
shl eax, 8
;секунда
; second
mov al, [ebp-10]
;время создания файла
; file creation time
mov [edi+8], eax
;время последнего доступа
; last access time
mov [edi+16], eax
;время последней записи
; last write time
mov [edi+24], eax
; получаем дату для файла
;год
; get date for file
; year
movzx eax, byte [ebp-15]
add eax, 1900
shl eax, 8
;месяц
; month
mov al, [ebp-14]
shl eax, 8
;день
; day
mov al, [ebp-13]
;дата создания файла
; file creation date
mov [edi+12], eax
;время последнего доступа
; last access date
mov [edi+20], eax
;время последней записи
; last write date
mov [edi+28], eax
; получаем тип данных имени
; get the data type of name
xor eax, eax
test dword [ebx+4], 1; 0=ANSI, 1=UNICODE
jnz .unicode_1
 
mov [edi+4], eax
jmp @f
;--------------------------------------
.unicode_1:
inc eax
mov [edi+4], eax
;--------------------------------------
@@:
; получаем размер файла в байтах
; get the file size in bytes
xor eax, eax
mov [edi+32+4], eax
mov eax, [ebp-23]
mov [edi+32], eax
ret
 
;----------------------------------------------------------------
;-----------------------------------------------------------------------------
;
; fs_CdGetFileInfo - LFN variant for CD
; get file/directory attributes structure
;
;----------------------------------------------------------------
;-----------------------------------------------------------------------------
fs_CdGetFileInfo:
cmp byte [esi], 0
jnz @f
 
mov eax, 2
ret
;--------------------------------------
@@:
push edi
call cd_find_lfn
471,16 → 578,20
pushfd
cmp [DevErrorCode], 0
jz @f
 
popfd
pop edi
mov eax, 11
ret
;--------------------------------------
@@:
popfd
jnc @f
 
pop edi
mov eax, ERROR_FILE_NOT_FOUND
ret
;--------------------------------------
@@:
 
mov edi, edx
493,8 → 604,7
pop edi
xor eax, eax
ret
 
;----------------------------------------------------------------
;-----------------------------------------------------------------------------
cd_find_lfn:
mov [cd_appl_data], 0
; in: esi+ebp -> name
501,14 → 611,13
; out: CF=1 - file not found
; else CF=0 and [cd_current_pointer_of_input] direntry
push eax esi
; 16 сектор начало набора дескрипторов томов
 
; Sector 16 - start set of volume descriptors
call WaitUnitReady
cmp [DevErrorCode], 0
jne .access_denied
 
call prevent_medium_removal
; тестовое чтение
; testing of reading
mov [CDSectorAddress], dword 16
mov [CDDataBuf_pointer], CDDataBuf
call ReadCDWRetr;_1
515,10 → 624,11
cmp [DevErrorCode], 0
jne .access_denied
 
; вычисление последней сессии
; calculation of the last session
call WaitUnitReady
cmp [DevErrorCode], 0
jne .access_denied
 
call Read_TOC
mov ah, [CDDataBuf+4+4]
mov al, [CDDataBuf+4+5]
529,7 → 639,7
mov [CDSectorAddress], eax
; mov [CDSectorAddress],dword 15
mov [CDDataBuf_pointer], CDDataBuf
 
;--------------------------------------
.start:
inc dword [CDSectorAddress]
call ReadCDWRetr;_1
537,111 → 647,128
jne .access_denied
 
.start_check:
; проверка на вшивость
; checking for "lice"
cmp [CDDataBuf+1], dword 'CD00'
jne .access_denied
 
cmp [CDDataBuf+5], byte '1'
jne .access_denied
; сектор является терминатором набор дескрипторов томов?
; sector is the terminator of set of descriptors volumes?
cmp [CDDataBuf], byte 0xff
je .access_denied
; сектор является дополнительным и улучшенным дескриптором тома?
; sector is an additional and improved descriptor of volume?
cmp [CDDataBuf], byte 0x2
jne .start
; сектор является дополнительным дескриптором тома?
; sector is an additional descriptor of volume?
cmp [CDDataBuf+6], byte 0x1
jne .start
 
; параметры root директрории
mov eax, [CDDataBuf+0x9c+2]; начало root директрории
; parameters of root directory
mov eax, [CDDataBuf+0x9c+2]; start of root directory
mov [CDSectorAddress], eax
mov eax, [CDDataBuf+0x9c+10]; размер root директрории
mov eax, [CDDataBuf+0x9c+10]; size of root directory
cmp byte [esi], 0
jnz @f
 
mov [cd_current_pointer_of_input], CDDataBuf+0x9c
jmp .done
;--------------------------------------
@@:
; начинаем поиск
; start the search
.mainloop:
dec dword [CDSectorAddress]
;--------------------------------------
.read_to_buffer:
inc dword [CDSectorAddress]
mov [CDDataBuf_pointer], CDDataBuf
call ReadCDWRetr ; читаем сектор директории
call ReadCDWRetr ; read sector of directory
cmp [DevErrorCode], 0
jne .access_denied
 
push ebp
call cd_find_name_in_buffer
pop ebp
jnc .found
 
sub eax, 2048
; директория закончилась?
; directory is over?
cmp eax, 0
ja .read_to_buffer
; нет искомого элемента цепочки
; desired element of chain is not found
.access_denied:
pop esi eax
mov [cd_appl_data], 1
stc
ret
; искомый элемент цепочки найден
;--------------------------------------
; desired element of chain found
.found:
; конец пути файла
; the end of the file path
cmp byte [esi-1], 0
jz .done
.nested:
mov eax, [cd_current_pointer_of_input]
push dword [eax+2]
pop dword [CDSectorAddress] ; начало директории
mov eax, [eax+2+8]; размер директории
pop dword [CDSectorAddress] ; beginning of the directory
mov eax, [eax+2+8] ; size of directory
jmp .mainloop
; указатель файла найден
;--------------------------------------
; file pointer found
.done:
test ebp, ebp
jz @f
 
mov esi, ebp
xor ebp, ebp
jmp .nested
;--------------------------------------
@@:
pop esi eax
mov [cd_appl_data], 1
clc
ret
 
;-----------------------------------------------------------------------------
cd_find_name_in_buffer:
mov [cd_current_pointer_of_input_2], CDDataBuf
;--------------------------------------
.start:
call cd_get_name
jc .not_found
 
call cd_compare_name
jc .start
;--------------------------------------
.found:
clc
ret
;--------------------------------------
.not_found:
stc
ret
 
;-----------------------------------------------------------------------------
cd_get_name:
push eax
mov ebp, [cd_current_pointer_of_input_2]
mov [cd_current_pointer_of_input], ebp
mov eax, [ebp]
test eax, eax ; входы закончились?
test eax, eax ; entry's is over?
jz .next_sector
cmp ebp, CDDataBuf+2048 ; буфер закончился?
 
cmp ebp, CDDataBuf+2048 ; buffer is over?
jae .next_sector
 
movzx eax, byte [ebp]
add [cd_current_pointer_of_input_2], eax; следующий вход каталога
add ebp, 33; указатель установлен на начало имени
add [cd_current_pointer_of_input_2], eax ; next entry of directory
add ebp, 33; pointer is set to the beginning of the name
pop eax
clc
ret
;--------------------------------------
.next_sector:
pop eax
stc
ret
 
;-----------------------------------------------------------------------------
cd_compare_name:
; compares ASCIIZ-names, case-insensitive (cp866 encoding)
; in: esi->name, ebp->name
650,6 → 777,7
; destroys eax
push esi eax edi
mov edi, ebp
;--------------------------------------
.loop:
cld
lodsb
666,31 → 794,37
sub edi, 2
scasw
jne .name_not_coincide
;--------------------------------------
.coincides:
cmp [esi], byte '/'; разделитель пути, конец имени текущего элемента
cmp [esi], byte '/' ; path separator is end of current element
je .done
cmp [esi], byte 0; разделитель пути, конец имени текущего элемента
 
cmp [esi], byte 0 ; path separator end of name
je .done
 
jmp .loop
;--------------------------------------
.name_not_coincide:
pop edi eax esi
stc
ret
;--------------------------------------
.done:
; проверка конца файла
cmp [edi], word 3B00h; сепаратор конца файла ';'
; check end of file
cmp [edi], word 3B00h; separator end of file ';'
je .done_1
; проверка для файлов не заканчивающихся сепаратором
; check for files not ending with separator
movzx eax, byte [ebp-33]
add eax, ebp
sub eax, 34
cmp edi, eax
je .done_1
; проверка конца папки
; check the end of directory
movzx eax, byte [ebp-1]
add eax, ebp
cmp edi, eax
jne .name_not_coincide
;--------------------------------------
.done_1:
pop edi eax
add esp, 4
697,7 → 831,7
inc esi
clc
ret
 
;-----------------------------------------------------------------------------
char_todown:
; convert character to uppercase, using cp866 encoding
; in: al=symbol
704,24 → 838,30
; 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
728,32 → 868,44
; 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
;-----------------------------------------------------------------------------