forked from KolibriOS/kolibrios
07d896f571
Added a new driver for the iso9660 file system. The driver supports the current version of the disk subsystem and is intended for further translation of IDE ATAPI devices to this driver. The basic version of ISO9660 and the Joliet extension are supported. git-svn-id: svn://kolibrios.org@10053 a494cfbc-eb01-0410-851d-a64ba20cac60
1780 lines
46 KiB
PHP
1780 lines
46 KiB
PHP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; ;;
|
|
;; Copyright (C) KolibriOS team 2004-2024. All rights reserved. ;;
|
|
;; Distributed under terms of the GNU General Public License. ;;
|
|
;; ;;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
; CD external functions
|
|
; in:
|
|
; esi -> path string in UTF-8
|
|
; ebx -> parameter structure +4
|
|
; ecx = bytes to read
|
|
; edx -> buffer
|
|
; out:
|
|
; eax, ebx = return values for sysfunc 70
|
|
iglobal
|
|
align 4
|
|
fs_CdServices:
|
|
dd fs_CdRead
|
|
dd fs_CdReadFolder
|
|
dd fs_NotImplemented
|
|
dd fs_NotImplemented
|
|
dd fs_NotImplemented
|
|
dd fs_CdGetFileInfo
|
|
dd fs_NotImplemented
|
|
dd 0
|
|
dd fs_NotImplemented
|
|
dd fs_NotImplemented
|
|
fs_NumCdServices = ($ - fs_CdServices)/4
|
|
endg
|
|
|
|
uglobal
|
|
align 4
|
|
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
|
|
cd_status dd 0
|
|
endg
|
|
|
|
;-----------------------------------------------------------------------------
|
|
fs_NotImplemented:
|
|
movi eax, ERROR_UNSUPPORTED_FS
|
|
ret
|
|
;-----------------------------------------------------------------------------
|
|
reserve_cd:
|
|
cli
|
|
cmp [cd_status], 0
|
|
je reserve_ok2
|
|
|
|
sti
|
|
call change_task
|
|
jmp reserve_cd
|
|
;-----------------------------------------------------------------------------
|
|
reserve_ok2:
|
|
push eax
|
|
mov eax, [current_slot]
|
|
mov eax, [eax + APPDATA.tid]
|
|
mov [cd_status], eax
|
|
pop eax
|
|
sti
|
|
ret
|
|
;-----------------------------------------------------------------------------
|
|
reserve_cd_channel:
|
|
pushad
|
|
mov eax, [cdpos]
|
|
dec eax
|
|
shr eax, 2
|
|
|
|
test eax, eax
|
|
jnz .1
|
|
|
|
cmp [ChannelNumber], 1
|
|
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
|
|
popad
|
|
ret
|
|
;-----------------------------------------------------------------------------
|
|
free_cd_channel:
|
|
pushad
|
|
mov eax, [cdpos]
|
|
dec eax
|
|
shr eax, 2
|
|
|
|
test eax, eax
|
|
jnz .1
|
|
|
|
cmp [ChannelNumber], 1
|
|
jne @f
|
|
|
|
mov ecx, ide_channel1_mutex
|
|
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
|
|
|
|
;-----------------------------------------------------------------------------
|
|
fs_CdRead:
|
|
call cd_find_lfn
|
|
jc .notFound
|
|
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
|
|
movi eax, ERROR_END_OF_FILE
|
|
ret
|
|
|
|
.notFound:
|
|
cmp [DevErrorCode], 0
|
|
jne .noaccess
|
|
xor ebx, ebx
|
|
movi eax, ERROR_FILE_NOT_FOUND
|
|
ret
|
|
|
|
.noaccess_3:
|
|
pop eax edx ecx
|
|
.noaccess:
|
|
xor ebx, ebx
|
|
movi eax, ERROR_ACCESS_DENIED
|
|
ret
|
|
|
|
@@:
|
|
mov ebx, [ebx]
|
|
.l1:
|
|
push ecx edx 0
|
|
mov eax, [edi+10] ; real size of the file section
|
|
sub eax, ebx
|
|
jb .eof
|
|
cmp eax, ecx
|
|
jae @f
|
|
mov ecx, eax
|
|
pop eax
|
|
push ERROR_END_OF_FILE
|
|
@@:
|
|
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
|
|
cmp [DevErrorCode], 0
|
|
jne .noaccess_3
|
|
add edx, 2048
|
|
sub ecx, 2048
|
|
.next:
|
|
inc dword [CDSectorAddress]
|
|
jmp .new_sector
|
|
|
|
.eof:
|
|
pop eax
|
|
push ERROR_END_OF_FILE
|
|
.done:
|
|
mov ebx, edx
|
|
pop eax edx ecx
|
|
sub ebx, edx
|
|
ret
|
|
|
|
.incomplete_sector: ; we must read and memmove incomplete sector
|
|
mov [CDDataBuf_pointer], CDDataBuf
|
|
call ReadCDWRetr
|
|
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
|
|
mov edi, edx
|
|
lea esi, [CDDataBuf + ebx]
|
|
cld
|
|
rep movsb
|
|
pop ecx esi edi
|
|
add edx, ecx
|
|
sub [esp], ecx
|
|
pop ecx
|
|
xor ebx, ebx
|
|
jmp .next
|
|
|
|
;-----------------------------------------------------------------------------
|
|
fs_CdReadFolder:
|
|
push edi
|
|
call cd_find_lfn
|
|
jnc .found
|
|
pop edi
|
|
cmp [DevErrorCode], 0
|
|
jne .noaccess_1
|
|
xor ebx, ebx
|
|
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:
|
|
xor ebx, ebx
|
|
mov eax, ERROR_ACCESS_DENIED
|
|
ret
|
|
|
|
.end_buffer:
|
|
pop edx eax
|
|
sub eax, 2048 ; directory is over?
|
|
ja .read_to_buffer
|
|
mov eax, [cd_counter_block]
|
|
mov [edx+8], eax
|
|
mov eax, [ebx]
|
|
sub [edx+4], eax
|
|
xor eax, eax
|
|
dec ecx
|
|
js @f
|
|
mov al, ERROR_END_OF_FILE
|
|
@@:
|
|
pop ecx edi
|
|
mov ebx, [edx+4]
|
|
ret
|
|
|
|
.found_dir:
|
|
mov eax, [edi+2] ; eax=cluster
|
|
mov [CDSectorAddress], eax
|
|
mov eax, [edi+10] ; directory size
|
|
push eax ecx
|
|
mov edi, edx
|
|
mov ecx, 32/4
|
|
xor eax, eax
|
|
rep stosd
|
|
pop ecx eax
|
|
mov byte [edx], 1 ; version
|
|
mov [cd_mem_location], edx
|
|
add [cd_mem_location], 32
|
|
mov [cd_counter_block], dword 0
|
|
dec dword [CDSectorAddress]
|
|
push ecx
|
|
.read_to_buffer:
|
|
inc dword [CDSectorAddress]
|
|
mov [CDDataBuf_pointer], CDDataBuf
|
|
call ReadCDWRetr ; read sector of directory
|
|
cmp [DevErrorCode], 0
|
|
jne .noaccess_1
|
|
mov [cd_current_pointer_of_input_2], CDDataBuf
|
|
push eax edx
|
|
.get_names_from_buffer:
|
|
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
|
|
test ecx, ecx
|
|
jz .get_names_from_buffer
|
|
mov edi, [cd_counter_block]
|
|
mov [edx+4], edi
|
|
dec ecx
|
|
mov esi, ebp
|
|
call cd_get_parameters_of_file
|
|
add edi, 40
|
|
mov ax, '.'
|
|
cmp dword[ebx+4], 2
|
|
jz .utf16
|
|
cmp dword[ebx+4], 3
|
|
jz .utf8
|
|
cmp [cd_counter_block], 2
|
|
jbe .parentDirectory
|
|
@@:
|
|
lodsw
|
|
xchg ah, al
|
|
call uni2ansi_char
|
|
stosb
|
|
call .checkForEnd
|
|
jc @b
|
|
@@:
|
|
mov [edi], byte 0
|
|
add [cd_mem_location], 304
|
|
jmp .get_names_from_buffer
|
|
|
|
.parentDirectory:
|
|
stosb
|
|
cmp [cd_counter_block], 2
|
|
jnz @b
|
|
stosb
|
|
jmp @b
|
|
|
|
.utf8:
|
|
add [cd_mem_location], 256
|
|
cmp [cd_counter_block], 2
|
|
jbe .parentDirectory
|
|
push ecx
|
|
mov ecx, 519
|
|
@@:
|
|
lodsw
|
|
xchg ah, al
|
|
call UTF16to8
|
|
js @f
|
|
call .checkForEnd
|
|
jc @b
|
|
@@:
|
|
pop ecx
|
|
mov [edi], byte 0
|
|
add [cd_mem_location], 304
|
|
jmp .get_names_from_buffer
|
|
|
|
.checkForEnd:
|
|
mov ax, [esi]
|
|
cmp ax, 3B00h ; ';'
|
|
jz @f
|
|
; check for files not ending with separator
|
|
movzx eax, byte [ebp-33]
|
|
add eax, ebp
|
|
sub eax, 34
|
|
cmp esi, eax
|
|
jz @f
|
|
; check the end of the directory
|
|
movzx eax, byte [ebp-1]
|
|
add eax, ebp
|
|
cmp esi, eax
|
|
@@:
|
|
ret
|
|
|
|
.utf16:
|
|
cmp [cd_counter_block], 2
|
|
jbe .utf16ParentDirectory
|
|
@@:
|
|
lodsw
|
|
xchg ah, al
|
|
stosw
|
|
call .checkForEnd
|
|
jc @b
|
|
@@:
|
|
mov [edi], word 0
|
|
add [cd_mem_location], 560
|
|
jmp .get_names_from_buffer
|
|
|
|
.utf16ParentDirectory:
|
|
stosw
|
|
cmp [cd_counter_block], 2
|
|
jnz @b
|
|
stosw
|
|
jmp @b
|
|
|
|
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:
|
|
; 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
|
|
; file is always read-only, as this CD
|
|
inc eax
|
|
mov [edi], eax
|
|
mov eax, [ebx+4]
|
|
mov [edi+4], 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 file size in bytes
|
|
xor eax, eax
|
|
mov [edi+32+4], eax
|
|
mov eax, [ebp-23]
|
|
mov [edi+32], eax
|
|
ret
|
|
|
|
;-----------------------------------------------------------------------------
|
|
fs_CdGetFileInfo:
|
|
call cd_find_lfn
|
|
movi eax, ERROR_FILE_NOT_FOUND
|
|
jc @f
|
|
mov edi, edx
|
|
mov eax, [ebx+4]
|
|
mov [edx+4], eax
|
|
cmp byte [esi], 0
|
|
jz .volume
|
|
mov ebp, [cd_current_pointer_of_input]
|
|
add ebp, 33
|
|
call cd_get_parameters_of_file_1
|
|
xor eax, eax
|
|
@@:
|
|
ret
|
|
|
|
.volume:
|
|
test eax, eax
|
|
jz .size
|
|
mov ecx, 16
|
|
mov esi, CDDataBuf+40
|
|
add edi, 40
|
|
cmp eax, 2
|
|
jz .utf16
|
|
cmp eax, 3
|
|
jz .utf8
|
|
@@:
|
|
lodsw
|
|
xchg al, ah
|
|
call uni2ansi_char
|
|
stosb
|
|
loop @b
|
|
jmp .size
|
|
|
|
.utf16:
|
|
lodsw
|
|
xchg al, ah
|
|
stosw
|
|
loop .utf16
|
|
jmp .size
|
|
|
|
.utf8:
|
|
mov ebx, ecx
|
|
shl ecx, 1
|
|
@@:
|
|
lodsw
|
|
xchg ah, al
|
|
call UTF16to8
|
|
dec ebx
|
|
jnz @b
|
|
.size:
|
|
mov eax, [CDDataBuf+80]
|
|
shl eax, 11
|
|
mov [edx+32], eax
|
|
xor eax, eax
|
|
mov [edx+36], eax
|
|
stosw
|
|
mov byte [edx], 8
|
|
ret
|
|
|
|
;-----------------------------------------------------------------------------
|
|
cd_find_lfn:
|
|
mov [cd_appl_data], 0
|
|
; in: esi -> path string in UTF-8
|
|
; out: [cd_current_pointer_of_input] -> direntry, CF=1 -> file not found
|
|
push eax esi
|
|
; 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
|
|
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]
|
|
shl eax, 16
|
|
mov ah, [CDDataBuf+4+6]
|
|
mov al, [CDDataBuf+4+7]
|
|
add eax, 15
|
|
mov [CDSectorAddress], eax
|
|
; mov [CDSectorAddress],dword 15
|
|
mov [CDDataBuf_pointer], CDDataBuf
|
|
;--------------------------------------
|
|
.start:
|
|
inc dword [CDSectorAddress]
|
|
call ReadCDWRetr;_1
|
|
cmp [DevErrorCode], 0
|
|
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
|
|
|
|
; parameters of root directory
|
|
mov eax, [CDDataBuf+0x9c+2]; start of root directory
|
|
mov [CDSectorAddress], eax
|
|
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 ; read sector of directory
|
|
cmp [DevErrorCode], 0
|
|
jne .access_denied
|
|
call cd_find_name_in_buffer
|
|
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
|
|
mov eax, [cd_current_pointer_of_input]
|
|
push dword [eax+2]
|
|
pop dword [CDSectorAddress] ; beginning of the directory
|
|
mov eax, [eax+2+8] ; size of directory
|
|
jmp .mainloop
|
|
;--------------------------------------
|
|
; file pointer found
|
|
.done:
|
|
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 ; entry's is over?
|
|
jz .next_sector
|
|
|
|
cmp ebp, CDDataBuf+2048 ; buffer is over?
|
|
jae .next_sector
|
|
|
|
movzx eax, byte [ebp]
|
|
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:
|
|
; in: esi -> UTF-8 name, ebp -> UTF-16BE name
|
|
; out: CF=0 -> names match, esi -> next component of name
|
|
; CF=1 -> esi is not changed
|
|
push edx edi eax esi
|
|
mov edi, ebp
|
|
.loop:
|
|
call utf8to16
|
|
call utf16toUpper
|
|
mov edx, eax
|
|
mov ax, [edi]
|
|
xchg al, ah
|
|
call utf16toUpper
|
|
cmp ax, dx
|
|
jne .name_not_coincide
|
|
add edi, 2
|
|
cmp [esi], byte '/' ; path separator is end of current element
|
|
je .done
|
|
cmp [esi], byte 0 ; path separator end of name
|
|
jne .loop
|
|
.done:
|
|
; 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 eax eax edi edx
|
|
inc esi
|
|
ret
|
|
|
|
.name_not_coincide:
|
|
pop esi eax edi edx
|
|
stc
|
|
ret
|
|
|
|
;;; New driver
|
|
|
|
DESCRIPTOR_TYPE_BOOT = 0x00 ; not used
|
|
DESCRIPTOR_TYPE_PRIMARY = 0x01
|
|
DESCRIPTOR_TYPE_SUPPLEMENTARY = 0x02
|
|
; DESCRIPTOR_TYPE_PRIMARY for Juliet(UTF-16)
|
|
DESCRIPTOR_TYPE_PARTITION = 0x02
|
|
DESCRIPTOR_TYPE_TERMANATOR = 0xff ; end scan descriptors
|
|
|
|
struct ISO9660_VOLUME_DESCRIPTOR
|
|
type rb 1
|
|
magic rb 5 ; 'CD001'
|
|
version rb 1
|
|
ends
|
|
|
|
struct ISO9660_PRIMARY_DESCRIPTOR ISO9660_VOLUME_DESCRIPTOR
|
|
rb 1
|
|
rb 32
|
|
VolumeName rb 32 ; ascii or utf-16
|
|
rb 8
|
|
VolumeSpaceSize rb 8
|
|
rb 32
|
|
rb 4 ; +120
|
|
rb 4
|
|
LBA_Size rb 4 ; +128
|
|
PathTableSize rb 8 ; Do not use it!!!
|
|
LBA_PathTable rb 4 ; +140 ; Do not use it!!!
|
|
rb 4 ; +144 ; Do not use it!!!
|
|
rb 8
|
|
root_dir_record rb 34 ;ISO9660_DIRECTORY_RECORD
|
|
rb 128*4 + 37*3
|
|
date_created rb 17
|
|
date_modiffed rb 17
|
|
rb 17
|
|
file_struct_ver rb 1 ;always 0x01
|
|
ends
|
|
|
|
struct ISO9660_DIRECTORY_RECORD
|
|
size rb 1
|
|
rb 1
|
|
lba rd 1
|
|
rd 1
|
|
data_length rd 1
|
|
rd 1
|
|
date_time rb 7
|
|
flags rb 1 ; 10b - directory 1b - hidden
|
|
rb 2+4
|
|
name_len rb 1
|
|
name rb 1 ; rb [name_len]
|
|
ends
|
|
|
|
; Internal data for every ISO9660 partition.
|
|
struct ISO9660 PARTITION
|
|
type_encoding rd 1 ; 0 - ascii 1 - UCS-2
|
|
lba_size rd 1 ; default 2048 TODO
|
|
primary_descr rd 1 ; sector num
|
|
root_dir_lba rd 1 ; lba32
|
|
root_dir_len rd 1 ;
|
|
ends
|
|
;-----------------------------------------------------------------------------
|
|
|
|
; ISO9660 external functions
|
|
; in:
|
|
; ebx -> parameter structure of sysfunc 70
|
|
; ebp -> ISO9660 structure
|
|
; esi -> path string in UTF-8
|
|
; out:
|
|
; eax, ebx = return values for sysfunc 70
|
|
iglobal
|
|
align 4
|
|
iso9660_user_functions:
|
|
dd iso9660_free
|
|
dd (.end - $ - 4) / 4
|
|
dd iso9660_Read
|
|
dd iso9660_ReadFolder
|
|
dd 0
|
|
dd 0
|
|
dd 0
|
|
dd iso9660_GetFileInfo
|
|
.end:
|
|
endg
|
|
|
|
; mount if it's a valid ISO9660 partition
|
|
iso9660_create_partition:
|
|
; in:
|
|
; ebp -> PARTITION structure
|
|
; ebx -> boot sector
|
|
; ebx + 2048 -> buffer
|
|
; esi -> DISK structure
|
|
; out:
|
|
; eax -> iso9660 partition structure, 0 = not iso9660
|
|
cmp dword [esi + DISK.MediaInfo.SectorSize], 2048 ; cd disks
|
|
jnz .fail_disk_sector
|
|
|
|
push ebx
|
|
sub esp, 4*3 ; locals value: primary_lba, encoding, select_sector
|
|
mov dword[esp], 16-1 ; sector number
|
|
mov eax, [esi + DISK.MediaInfo.LastSessionSector]
|
|
add [esp], eax
|
|
mov dword[esp + 4], 0 ; base encoding - ascii
|
|
|
|
add ebx, 2048
|
|
.new_descr:
|
|
inc dword[esp]
|
|
; read 16 sector, check header of descriptor
|
|
xor edx, edx
|
|
mov eax, [esp]
|
|
mov ecx, 1
|
|
; ebx - buffer
|
|
; edx:eax - num sector
|
|
; ebp - PARTITION
|
|
; ecx - number sectors
|
|
call fs_read64_sys
|
|
test eax, eax
|
|
jnz .err_disk_1
|
|
|
|
cmp dword[ebx + 1], 'CD00'
|
|
jnz .err_disk_1
|
|
cmp byte[ebx + 5], '1'
|
|
jnz .err_disk_1
|
|
|
|
cmp byte[ebx], DESCRIPTOR_TYPE_TERMANATOR
|
|
jz .end_scan
|
|
|
|
cmp byte[ebx], DESCRIPTOR_TYPE_PRIMARY
|
|
jnz @f
|
|
|
|
cmp dword[esp + 4], 0
|
|
jnz .new_descr
|
|
|
|
mov dword[esp + 4], 0 ; set UCS-2 encoding
|
|
mov eax, [esp]
|
|
mov dword[esp + 8], eax ; set lba address
|
|
|
|
jmp .new_descr
|
|
@@:
|
|
cmp byte[ebx], DESCRIPTOR_TYPE_SUPPLEMENTARY
|
|
jnz .new_descr
|
|
|
|
mov dword[esp + 4], 1 ; set UCS-2 encoding
|
|
mov eax, [esp]
|
|
mov dword[esp + 8], eax ; set lba address
|
|
|
|
jmp .new_descr
|
|
.end_scan:
|
|
|
|
; get root dir lba, root dir size, size lba
|
|
xor edx, edx
|
|
mov eax, [esp + 8]
|
|
mov ecx, 1
|
|
call fs_read64_sys
|
|
test eax, eax
|
|
jnz .err_disk_1
|
|
|
|
; alloc memory for ISO9660 struct
|
|
mov eax, sizeof.ISO9660
|
|
call malloc
|
|
test eax, eax
|
|
jz .err_disk_1
|
|
; copy data on struct
|
|
add esp, 4
|
|
pop dword[eax + ISO9660.type_encoding]
|
|
mov dword[eax + ISO9660.lba_size], 2048 ;TODO
|
|
pop dword[eax + ISO9660.primary_descr]
|
|
|
|
mov ecx, dword[ebx + ISO9660_PRIMARY_DESCRIPTOR.root_dir_record + ISO9660_DIRECTORY_RECORD.lba]
|
|
mov [eax + ISO9660.root_dir_lba], ecx
|
|
|
|
mov ecx, dword[ebx + ISO9660_PRIMARY_DESCRIPTOR.root_dir_record + ISO9660_DIRECTORY_RECORD.data_length]
|
|
mov [eax + ISO9660.root_dir_len], ecx
|
|
|
|
push edi esi
|
|
mov edi, eax
|
|
mov esi, ebp
|
|
mov ecx, sizeof.PARTITION/4
|
|
rep movsd
|
|
pop esi edi
|
|
mov [eax + PARTITION.FSUserFunctions], iso9660_user_functions
|
|
|
|
pop ebx
|
|
ret
|
|
.err_disk_1:
|
|
add esp, 4*3
|
|
pop ebx
|
|
.fail_disk_sector:
|
|
xor eax, eax
|
|
ret
|
|
|
|
; IN: eax - ptr PARTITION
|
|
; OUT: -
|
|
; SAVE: esi, edi
|
|
; Function free PARTITION struct and all object this structure
|
|
iso9660_free:
|
|
jmp free
|
|
|
|
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; ISO9660 external functions
|
|
; in:
|
|
; ebx -> parameter structure of sysfunc 70
|
|
; ebp -> ISO9660 structure
|
|
; esi -> path string in UTF-8
|
|
; out:
|
|
; eax, ebx = return values for sysfunc 70
|
|
iso9660_Read:
|
|
sub esp, 4 ; for ptr on memory page
|
|
call iso9660_find_file
|
|
mov esi, eax
|
|
mov edi, [ebx + 16] ; ptr to programm buffer
|
|
|
|
test byte[esi + ISO9660_DIRECTORY_RECORD.flags], 10b ; check dir
|
|
jnz iso9660_find_file.not_found
|
|
|
|
; check offset (offset <= size)
|
|
mov edx, [ebx + 4] ; low offset
|
|
cmp dword[ebx + 8], 0 ; high offset
|
|
jnz iso9660_find_file.bad_offset ; error offset > max size
|
|
|
|
cmp edx, [esi + ISO9660_DIRECTORY_RECORD.data_length]
|
|
jae iso9660_find_file.bad_offset ; error offset > file length
|
|
|
|
; good file - copy file data
|
|
sub esp, 4*4
|
|
mov dword[esp + 3*4], 0
|
|
mov [esp + 1*4], edx ; offset to start copy
|
|
mov dword[esp], 0 ; count copping byte
|
|
|
|
; check end offset (offset+size_buff <= size)
|
|
mov ecx, [esi + ISO9660_DIRECTORY_RECORD.data_length]
|
|
mov eax, [ebx + 12] ;size copy data - buffer size
|
|
sub ecx, edx
|
|
mov [esp + 2*4], eax ; set count copy = buffer size
|
|
cmp ecx, eax ; max copy size > buffer size
|
|
jae @f
|
|
|
|
mov [esp + 2*4], ecx
|
|
mov dword[esp + 3*4], ERROR_END_OF_FILE
|
|
|
|
@@:
|
|
mov esi, [esi + ISO9660_DIRECTORY_RECORD.lba]
|
|
; [esp + 4*4] = ptr temp buffer
|
|
; [esp+3*4] = fs err code [esp+2*4] = size copy data
|
|
; [esp+1*4] = offset copy [esp] = count copying data
|
|
|
|
.full_size:
|
|
; check offset mod sector_size = 0
|
|
test edx, not -2048
|
|
jz .first_align ; no creat buffer for first align
|
|
|
|
mov ebx, [esp + 4*4]
|
|
|
|
; read sector
|
|
push edx
|
|
|
|
and edx, -2048
|
|
shr edx, BSF 2048
|
|
mov eax, esi ; ISO9660_DIRECTORY_RECORD.lba
|
|
add eax, edx
|
|
mov ecx, 1
|
|
xor edx, edx
|
|
; ebx - buffer
|
|
; edx:eax - num sector
|
|
; ebp - PARTITION
|
|
; ecx - number sectors
|
|
call fs_read64_app
|
|
|
|
pop edx
|
|
test eax, eax
|
|
jnz .err_disk_1
|
|
|
|
mov ecx, edx
|
|
neg edx
|
|
and edx, not -2048
|
|
and ecx, not -2048
|
|
; create new offset
|
|
add dword[esp + 1*4], not -2048
|
|
and dword[esp + 1*4], -2048
|
|
|
|
cmp dword[esp + 2*4], edx ; copy data > read in this sector
|
|
jae @f
|
|
mov edx, [esp + 2*4]
|
|
@@:
|
|
sub dword[esp + 2*4], edx
|
|
add dword[esp], edx
|
|
|
|
;DEBUGF 1, "K : iso c=%x d=%x Hz\n", ecx, edx
|
|
push esi
|
|
; copy (2048 - offset) and -2048
|
|
mov esi, ebx ; buffer
|
|
add esi, ecx
|
|
mov ecx, edx
|
|
rep movsb
|
|
pop esi
|
|
|
|
;stdcall kernel_free, ebx
|
|
.first_align:
|
|
|
|
mov ecx, [esp + 2*4]
|
|
and ecx, -2048
|
|
|
|
cmp ecx, 2048
|
|
jb .copy_finish_block
|
|
|
|
mov eax, [esp + 1*4]
|
|
shr eax, BSF 2048
|
|
; copy main block
|
|
mov ebx, edi
|
|
add edi, ecx
|
|
sub dword[esp + 2*4], ecx
|
|
add dword[esp + 1*4], ecx
|
|
add dword[esp], ecx
|
|
|
|
shr ecx, BSF 2048
|
|
xor edx, edx
|
|
add eax, esi ; ISO9660_DIRECTORY_RECORD.lba
|
|
; ebx - buffer
|
|
; edx:eax - num sector
|
|
; ebp - PARTITION
|
|
; ecx - number sectors
|
|
call fs_read64_app
|
|
test eax, eax
|
|
jnz .err_disk
|
|
|
|
.copy_finish_block:
|
|
|
|
cmp dword[esp + 2*4], 0
|
|
jz .end_align ; creat buffer for end read sector
|
|
|
|
mov ebx, [esp + 4*4]
|
|
|
|
;copy finish block
|
|
mov eax, [esp + 1*4]
|
|
shr eax, BSF 2048
|
|
xor edx, edx
|
|
|
|
mov ecx, 1
|
|
add eax, esi ; ISO9660_DIRECTORY_RECORD.lba
|
|
; ebx - buffer
|
|
; edx:eax - num sector
|
|
; ebp - PARTITION
|
|
; ecx - number sectors
|
|
call fs_read64_app
|
|
test eax, eax
|
|
jnz .err_disk_1
|
|
|
|
mov esi, ebx
|
|
mov ecx, [esp + 2*4]
|
|
add dword[esp], ecx
|
|
rep movsb
|
|
|
|
;stdcall kernel_free, ebx
|
|
|
|
.end_align:
|
|
; set ebx size copy data
|
|
mov ebx, [esp]
|
|
mov esi, [esp + 3*4]
|
|
add esp, 4*4
|
|
call kernel_free
|
|
|
|
mov eax, esi
|
|
ret
|
|
|
|
.err_disk_1:
|
|
stdcall kernel_free, ebx
|
|
.err_disk:
|
|
add esp, 4*4
|
|
call kernel_free
|
|
xor ebx, ebx
|
|
mov eax, ERROR_DEVICE
|
|
ret
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; ISO9660 external functions
|
|
; in:
|
|
; ebx -> parameter structure of sysfunc 70
|
|
; ebp -> ISO9660 structure
|
|
; esi -> path string in UTF-8
|
|
; out:
|
|
; eax, ebx = return values for sysfunc 70
|
|
iso9660_ReadFolder:
|
|
sub esp, 4 ; for ptr on memory page
|
|
call iso9660_find_file
|
|
|
|
test byte[eax + ISO9660_DIRECTORY_RECORD.flags], 10b ; check dir
|
|
jz iso9660_find_file.not_found
|
|
|
|
mov edi, [ebx + 16] ; buffer
|
|
push dword[ebx + 16]
|
|
push dword[ebx + 4] ; first file
|
|
push dword[ebx + 8] ; encoding
|
|
push dword 0
|
|
push dword 0
|
|
push dword[ebx + 12] ; count file
|
|
push dword[eax + ISO9660_DIRECTORY_RECORD.data_length]
|
|
push dword[eax + ISO9660_DIRECTORY_RECORD.lba]
|
|
|
|
; [esp] - lba [esp + 4] - size
|
|
; [esp + 8] - max count
|
|
; [esp + 12] - counter
|
|
; [esp + 16] - all count files
|
|
; [esp + 20] - encoding
|
|
; [esp + 24] - first item 0..(2^32 -1)
|
|
; [esp + 28] - user buffer
|
|
; edi - user buffer
|
|
|
|
; set header(32 byte) in buffer
|
|
mov dword[edi], 1
|
|
add edi, 32 ;set on first item
|
|
|
|
; loop copy file info and name
|
|
.read_sector:
|
|
mov ebx, [esp + 32]
|
|
mov ecx, 1
|
|
xor edx, edx
|
|
mov eax, [esp]
|
|
; ebx - buffer
|
|
; edx:eax - num sector
|
|
; ebp - PARTITION
|
|
; ecx - number sectors
|
|
call fs_read64_sys
|
|
test eax, eax
|
|
jnz .err_disk
|
|
.new_file:
|
|
cmp byte[ebx], 0
|
|
jz .next_sector
|
|
|
|
; inc counter all files
|
|
inc dword[esp + 16]
|
|
; check copy
|
|
mov eax, [esp + 24]
|
|
cmp [esp + 16], eax
|
|
jbe .skip
|
|
|
|
mov eax, [esp + 12]
|
|
cmp [esp + 8], eax
|
|
je .skip
|
|
|
|
inc dword[esp + 12]
|
|
|
|
mov eax, ebx
|
|
mov ecx, edi
|
|
call iso9660_GetFileInfo.copy_file_info
|
|
|
|
; copy encoding
|
|
movzx eax, byte[esp + 20]
|
|
mov [edi + 4], eax
|
|
|
|
add edi, 40
|
|
;-----------------------------------------------------------------------------
|
|
; copy name
|
|
push ebx
|
|
push edi
|
|
push eax
|
|
|
|
add ebx, ISO9660_DIRECTORY_RECORD.name
|
|
mov esi, ebx
|
|
mov cl, [ebx - 1]
|
|
cmp cl, 1
|
|
jne @f
|
|
cmp byte[ebx], 0
|
|
jne @f
|
|
mov dword[edi], '.'
|
|
jmp .end_copy
|
|
@@:
|
|
cmp cl, byte[ebx]
|
|
jne @f
|
|
mov dword[edi], '..'
|
|
cmp eax, 2
|
|
jne .end_copy
|
|
mov dword[edi], ('.' shl 16) + '.'
|
|
mov word[edi+ 2], 0
|
|
jmp .end_copy
|
|
@@:
|
|
;-----------------------------------------------------------------------------
|
|
; copy real name
|
|
movzx ecx, byte[ebx - 1]
|
|
cmp [ebp + ISO9660.type_encoding], 0
|
|
jnz .ucs2
|
|
cmp eax, 2
|
|
je .ascii2utf16
|
|
@@:
|
|
sub ecx, 1 ; CF + ZF
|
|
jbe @f
|
|
movsd
|
|
cmp byte[esi], ';'
|
|
jne @b
|
|
@@:
|
|
mov byte[edi], 0
|
|
jmp .end_copy
|
|
;-----------------------------------------------------------------------------
|
|
.ascii2utf16:
|
|
lodsb
|
|
call ansi2uni_char
|
|
stosw
|
|
cmp byte[esi], ';'
|
|
je @f
|
|
loop .ascii2utf16
|
|
@@:
|
|
mov word[edi], 0
|
|
jmp .end_copy
|
|
;-----------------------------------------------------------------------------
|
|
.ucs2:
|
|
shr ecx, 1
|
|
cmp eax, 1
|
|
ja .ucs2utf16
|
|
; convert ucs2 to ascii
|
|
@@:
|
|
lodsw
|
|
cmp ax, 0x3B00
|
|
je @f
|
|
xchg al, ah
|
|
call uni2ansi_char
|
|
stosb
|
|
loop @b
|
|
@@:
|
|
mov byte[edi], 0
|
|
jmp .end_copy
|
|
;-----------------------------------------------------------------------------
|
|
.ucs2utf16:
|
|
cmp edx, 2 ; utf16 encoding
|
|
jne .ucs2utf8
|
|
; convert ucs2 to utf16LE
|
|
@@:
|
|
lodsw
|
|
cmp ax, 0x3B00
|
|
je @f
|
|
xchg al, ah
|
|
stosw
|
|
loop @b
|
|
@@:
|
|
mov word[edi], 0
|
|
jmp .end_copy
|
|
;-----------------------------------------------------------------------------
|
|
.ucs2utf8:
|
|
; convert ucs2 to utf8
|
|
mov ebx, ecx
|
|
shl ecx, 1
|
|
@@:
|
|
lodsw
|
|
cmp ax, 0x3B00
|
|
je @f
|
|
xchg ah, al
|
|
call UTF16to8
|
|
dec ebx
|
|
jnz @b
|
|
@@:
|
|
mov byte[edi], 0
|
|
;-----------------------------------------------------------------------------
|
|
.end_copy:
|
|
pop eax
|
|
pop edi
|
|
pop ebx
|
|
add edi, 264
|
|
cmp eax, 2
|
|
jb .skip
|
|
add edi, 520-264
|
|
.skip:
|
|
movzx ecx, byte[ebx]
|
|
add ebx, ecx
|
|
|
|
test ebx, 2048
|
|
jnz .next_sector
|
|
|
|
mov eax, ebx
|
|
and eax, not -2048
|
|
cmp eax, [esp + 4]
|
|
jb .new_file
|
|
|
|
mov eax, [esp + 12]
|
|
cmp eax, [esp + 8]
|
|
jb .new_file
|
|
|
|
jmp .end_loop
|
|
|
|
.next_sector:
|
|
inc dword[esp]
|
|
sub dword[esp + 4], 2048
|
|
ja .read_sector
|
|
.end_loop:
|
|
mov ecx, [esp + 28]
|
|
mov ebx, [esp + 12]
|
|
mov [ecx + 4], ebx
|
|
mov esi, [esp + 16]
|
|
mov [ecx + 8], esi
|
|
mov esi, [esp + 8] ; max count
|
|
; free buffer
|
|
add esp, 8*4
|
|
call kernel_free
|
|
|
|
xor eax, eax
|
|
cmp ebx, esi
|
|
je @f
|
|
mov eax, ERROR_END_OF_FILE
|
|
@@:
|
|
ret
|
|
.err_disk:
|
|
mov ecx, [esp + 28]
|
|
mov ebx, [esp + 12]
|
|
mov [ecx + 4], ebx
|
|
mov esi, [esp + 16]
|
|
mov [ecx + 8], esi
|
|
; free buffer
|
|
add esp, 8*4
|
|
call kernel_free
|
|
|
|
mov eax, ERROR_DEVICE
|
|
ret
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; ISO9660 external functions
|
|
; in:
|
|
; ebx -> parameter structure of sysfunc 70
|
|
; ebp -> ISO9660 structure
|
|
; esi -> path string in UTF-8
|
|
; out:
|
|
; eax, ebx = return values for sysfunc 70
|
|
iso9660_GetFileInfo:
|
|
cmp byte[esi], 0
|
|
jz .rootdir
|
|
|
|
sub esp, 4 ; for ptr on memory page
|
|
call iso9660_find_file
|
|
|
|
mov ecx, [ebx + 16] ; buffer
|
|
|
|
call .copy_file_info
|
|
|
|
call kernel_free
|
|
xor eax, eax
|
|
mov ebx, 40
|
|
ret
|
|
|
|
; IN: eax -> ISO966_DIRECTORY_RECORD
|
|
; ecx -> buffer
|
|
; destruct: edx
|
|
.copy_file_info:
|
|
; copy size
|
|
mov [ecx + 36], dword 0
|
|
mov edx, [eax + ISO9660_DIRECTORY_RECORD.data_length]
|
|
mov [ecx + 32], edx
|
|
|
|
; copy flags(dir of file)
|
|
xor edx, edx
|
|
or dl, 000001b
|
|
test byte[eax + ISO9660_DIRECTORY_RECORD.flags], 1b ; check hidden flag
|
|
jz @f
|
|
or dl, 10b
|
|
@@:
|
|
test byte[eax + ISO9660_DIRECTORY_RECORD.flags], 10b ; check dir
|
|
jz @f
|
|
or dl, 10000b ; dir flag
|
|
mov dword[ecx + 32], 0 ; size = zero
|
|
@@:
|
|
mov [ecx], edx
|
|
|
|
; copy date creat file
|
|
movzx edx, byte[eax + ISO9660_DIRECTORY_RECORD.date_time]
|
|
add edx, 1900 ; year
|
|
shl edx, 8
|
|
|
|
mov dl, byte[eax + ISO9660_DIRECTORY_RECORD.date_time + 1] ;month
|
|
shl edx, 8
|
|
mov dl, byte[eax + ISO9660_DIRECTORY_RECORD.date_time + 2] ;day
|
|
|
|
mov [ecx + 12], edx
|
|
mov [ecx + 20], edx
|
|
mov [ecx + 28], edx
|
|
|
|
; copy time creat file
|
|
movzx edx, byte[eax + ISO9660_DIRECTORY_RECORD.date_time + 3] ;hour
|
|
shl edx, 8
|
|
mov dl, byte[eax + ISO9660_DIRECTORY_RECORD.date_time + 4] ; minute
|
|
shl edx, 8
|
|
mov dl, byte[eax + ISO9660_DIRECTORY_RECORD.date_time + 5] ; second
|
|
|
|
mov [ecx + 8], edx
|
|
mov [ecx + 16], edx
|
|
mov [ecx + 24], edx
|
|
|
|
ret
|
|
|
|
.rootdir:
|
|
mov edi, [ebx + 16] ; edi = buffer
|
|
; copy flags (dir)
|
|
mov byte [edi], 8
|
|
; copy size drive
|
|
mov eax, dword[ebp + PARTITION.Length+DQ.lo]
|
|
mov edx, dword[ebp + PARTITION.Length+DQ.hi]
|
|
mov ecx, [ebp + PARTITION.Disk]
|
|
mov ecx, [ecx + DISK.MediaInfo.SectorSize]
|
|
bsf ecx, ecx
|
|
shld edx, eax, cl
|
|
shl eax, cl
|
|
mov [edi + 32], eax ; bdfe.size.lo
|
|
mov [edi + 36], edx ; bdfe.size.hi
|
|
|
|
mov eax, [ebx + 8]
|
|
; copy encoding
|
|
mov [edi + 4], eax
|
|
; check encoding on fs struct
|
|
test eax, eax ; check f70s5arg.xflags
|
|
jz .no_name
|
|
|
|
; stdcall is_region_userspace, edi, ecx
|
|
|
|
; alloc memory for read primary descriptor
|
|
stdcall kernel_alloc, PAGE_SIZE
|
|
test eax, eax
|
|
jz .no_memory
|
|
|
|
push eax
|
|
mov esi, eax
|
|
; read primary descriptor
|
|
mov ebx, eax
|
|
mov ecx, 1
|
|
xor edx, edx
|
|
mov eax, [ebp + ISO9660.primary_descr]
|
|
; ebx - buffer
|
|
; edx:eax - num sector
|
|
; ebp - PARTITION
|
|
; ecx - number sectors
|
|
call fs_read64_sys
|
|
test eax, eax
|
|
jnz .err_read_part
|
|
|
|
add esi, ISO9660_PRIMARY_DESCRIPTOR.VolumeName
|
|
mov edx, [edi + 4]
|
|
add edi, 40 ; offset partition name
|
|
mov ecx, 32
|
|
call iso9660_copy_name
|
|
|
|
; free memory
|
|
call kernel_free
|
|
.no_name:
|
|
xor eax, eax
|
|
mov ebx, 40
|
|
ret
|
|
.err_read_part:
|
|
call kernel_free
|
|
|
|
mov eax, ERROR_DEVICE
|
|
ret
|
|
.no_memory:
|
|
mov eax, TASKMAN_ERROR_OUT_OF_MEMORY
|
|
ret
|
|
|
|
|
|
;-----------------------------------------------------------------------------
|
|
|
|
; IN: esi - ptr string UTF-8 or zero for root directory
|
|
; OUT: eax - ptr to directory record
|
|
; [esp + 4] - ptr to memory page for destruct
|
|
iso9660_find_file:
|
|
|
|
stdcall kernel_alloc, 4096 ;
|
|
test eax, eax
|
|
jz .err_get_memory
|
|
|
|
mov [esp + 4], eax
|
|
|
|
cmp byte[esi], 0
|
|
jz .rootdir
|
|
|
|
push ebx ; save and buffer = esp + 8
|
|
push dword[ebp + ISO9660.root_dir_len]
|
|
push dword[ebp + ISO9660.root_dir_lba]
|
|
; [esp] - sector num [esp + 4] - size dir
|
|
; [esp + 8] - ebx [esp + 16] - buffer
|
|
; get size root dir (not record size)
|
|
.read_sector:
|
|
; get sector for directory
|
|
mov edi, [esp + 16]
|
|
mov ebx, [esp + 16]
|
|
mov ecx, 1
|
|
xor edx, edx
|
|
mov eax, [esp]
|
|
; ebx - buffer
|
|
; edx:eax - num sector
|
|
; ebp - PARTITION
|
|
; ecx - number sectors
|
|
call fs_read64_sys
|
|
test eax, eax
|
|
jnz .err_disk_1
|
|
|
|
mov ecx, [esp + 4]
|
|
.next_record:
|
|
|
|
; check size
|
|
cmp byte[edi], 0
|
|
jz .next_sector
|
|
|
|
; check file name
|
|
call iso9660_compare_name
|
|
jnc .found
|
|
|
|
movzx edx, byte[edi + ISO9660_DIRECTORY_RECORD.size]
|
|
add edi, edx
|
|
|
|
test edi, 2048 ;worked for allocate of page
|
|
jnz .next_sector
|
|
|
|
sub ecx, edx
|
|
jc .not_found_2
|
|
|
|
jmp .next_record
|
|
|
|
.next_sector:
|
|
sub dword[esp + 4], 2048
|
|
jbe .not_found_2
|
|
inc dword[esp]
|
|
jmp .read_sector
|
|
|
|
.found:
|
|
; finish name?
|
|
cmp byte[esi], '/'
|
|
jne .done
|
|
|
|
inc esi
|
|
mov edx, [edi + ISO9660_DIRECTORY_RECORD.lba]
|
|
mov dword[esp], edx
|
|
mov edx, [edi + ISO9660_DIRECTORY_RECORD.data_length]
|
|
mov dword[esp + 4], edx
|
|
jmp .read_sector
|
|
.done:
|
|
mov ebx, [esp + 8]
|
|
add esp, 4*3
|
|
mov eax, edi
|
|
ret
|
|
|
|
;-----------------------------------------------------------------------------
|
|
.rootdir:
|
|
; read primary descriptor
|
|
pusha
|
|
mov ebx, eax
|
|
mov ecx, 1
|
|
xor edx, edx
|
|
mov eax, [ebp + ISO9660.primary_descr]
|
|
; ebx - buffer
|
|
; edx:eax - num sector
|
|
; ebp - PARTITION
|
|
; ecx - number sectors
|
|
call fs_read64_sys
|
|
test eax, eax
|
|
popa
|
|
jnz .err_disk
|
|
|
|
mov eax, [esp + 4]
|
|
add eax, ISO9660_PRIMARY_DESCRIPTOR.root_dir_record
|
|
ret
|
|
|
|
; errors
|
|
.err_disk_1:
|
|
; free stack values
|
|
mov ebx, [esp + 8]
|
|
add esp, 4*3
|
|
.err_disk:
|
|
add esp, 4
|
|
call kernel_free
|
|
xor ebx, ebx
|
|
mov eax, ERROR_DEVICE
|
|
ret
|
|
|
|
.not_found_2:
|
|
mov ebx, [esp + 8]
|
|
add esp, 4*3
|
|
.not_found_1:
|
|
add esp, 4
|
|
.not_found: ; [esp] - ptr to page
|
|
call kernel_free
|
|
|
|
mov eax, ERROR_FILE_NOT_FOUND
|
|
xor ebx, ebx
|
|
ret
|
|
|
|
.bad_offset: ; [esp] - ptr to page
|
|
call kernel_free
|
|
|
|
mov eax, ERROR_END_OF_FILE
|
|
xor ebx, ebx
|
|
ret
|
|
|
|
|
|
.err_get_memory:
|
|
add esp, 8 ; skip addr return and dword for ptr to buffer
|
|
.no_memory:
|
|
mov eax, TASKMAN_ERROR_OUT_OF_MEMORY
|
|
xor ebx, ebx
|
|
ret
|
|
|
|
|
|
|
|
iso9660_compare_name:
|
|
; in: esi -> UTF-8 name, ebp -> ISO9660 struct
|
|
; edi -> ISO9660_DIRECTORY_RECORD
|
|
; out: CF=0 -> names match, esi -> next component of name
|
|
; CF=1 -> esi is not changed
|
|
push ecx eax esi edi
|
|
add edi, ISO9660_DIRECTORY_RECORD.name
|
|
.loop:
|
|
call utf8to16
|
|
call utf16toUpper
|
|
mov edx, eax
|
|
|
|
mov ax, [edi]
|
|
|
|
cmp [ebp + ISO9660.type_encoding], 0
|
|
jnz @f
|
|
shl ax, 8 ; ah=al al=0
|
|
dec edi
|
|
@@:
|
|
xchg al, ah
|
|
call utf16toUpper
|
|
|
|
cmp ax, dx
|
|
jne .name_not_coincide
|
|
|
|
add edi, 2
|
|
cmp byte[esi], '/' ; path separator is end of current element
|
|
je .done
|
|
cmp byte[esi], 0 ; path separator end of name
|
|
jne .loop
|
|
.done:
|
|
; check end of file
|
|
cmp [ebp + ISO9660.type_encoding], 0
|
|
jnz @f
|
|
cmp byte[edi], ';'
|
|
je .done_1
|
|
@@:
|
|
cmp [ebp + ISO9660.type_encoding], 0
|
|
jz @f
|
|
cmp word[edi], 0x3B00; 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
|
|
mov ecx, [esp]
|
|
movzx eax, byte [ecx + ISO9660_DIRECTORY_RECORD.name_len]
|
|
add ecx, ISO9660_DIRECTORY_RECORD.name
|
|
add eax, ecx
|
|
cmp edi, eax
|
|
jne .name_not_coincide
|
|
.done_1:
|
|
pop edi eax eax ecx
|
|
ret
|
|
|
|
.name_not_coincide:
|
|
pop edi esi eax ecx
|
|
stc
|
|
ret
|
|
|
|
|
|
|
|
|
|
;IN: ebp -> PARTITION structure
|
|
; ebx -> FS structure
|
|
; esi -> input string (ascii or ucs2)
|
|
; ecx = count bytes
|
|
; edi -> output string (buffer)
|
|
; edx = encoding output string
|
|
;OUT: edi increasing
|
|
; esi increasing
|
|
; ecx = 0 or other value
|
|
iso9660_copy_name:
|
|
cmp [ebp + ISO9660.type_encoding], 0
|
|
jnz .ucs2
|
|
|
|
cmp edx, 1 ; cp866 encoding
|
|
jne @f
|
|
; no convert chars
|
|
rep movsb
|
|
jmp .end_copy_name
|
|
@@:
|
|
cmp edx, 2 ; utf16 encoding
|
|
jne .ascii2utf8
|
|
; convert ascii to utf16LE
|
|
@@:
|
|
lodsb
|
|
call ansi2uni_char
|
|
stosw
|
|
loop @b
|
|
jmp .end_copy_name
|
|
|
|
.ascii2utf8:
|
|
cmp edx, 3 ; utf8 encoding
|
|
jne .end_copy_name
|
|
; convert ascii to utf8
|
|
call cp866toUTF8_string
|
|
jmp .end_copy_name
|
|
.ucs2:
|
|
shr ecx, 1 ; ecx/2 - ucs2 chars
|
|
|
|
cmp edx, 1 ; cp866 encoding
|
|
jne .ucs2utf16
|
|
; convert ucs2 to ascii
|
|
@@:
|
|
lodsw
|
|
xchg al, ah
|
|
call uni2ansi_char
|
|
stosb
|
|
loop @b
|
|
|
|
jmp .end_copy_name
|
|
.ucs2utf16:
|
|
cmp edx, 2 ; utf16 encoding
|
|
jne .ucs2utf8
|
|
; convert ucs2 to utf16LE
|
|
@@:
|
|
lodsw
|
|
xchg al, ah
|
|
stosw
|
|
loop @b
|
|
jmp .end_copy_name
|
|
|
|
.ucs2utf8:
|
|
cmp edx, 3 ; utf8 encoding
|
|
jne .end_copy_name
|
|
; convert ucs2 to utf8
|
|
mov ebx, ecx
|
|
shl ecx, 1
|
|
@@:
|
|
lodsw
|
|
xchg ah, al
|
|
call UTF16to8
|
|
dec ebx
|
|
jnz @b
|
|
|
|
.end_copy_name:
|
|
mov byte[edi], 0
|
|
cmp [ebp + ISO9660.type_encoding], 0
|
|
jz @f
|
|
mov word[edi], 0
|
|
@@:
|
|
ret
|
|
|