forked from KolibriOS/kolibrios
66417e61bd
1) Fix - sectors read with errors now are not brought in the cache. 2) Timeout at absence of the disk in ATAPI drive is reduced about 10 seconds without lowering reliability of reading at presence of the disk. Earlier time the waiting could make 1-1.5 minutes. git-svn-id: svn://kolibrios.org@628 a494cfbc-eb01-0410-851d-a64ba20cac60
735 lines
16 KiB
PHP
735 lines
16 KiB
PHP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; ;;
|
|
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
|
;; Distributed under terms of the GNU General Public License ;;
|
|
;; ;;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
$Revision$
|
|
|
|
|
|
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
|
|
|
|
sti
|
|
call change_task
|
|
jmp reserve_cd
|
|
|
|
reserve_ok2:
|
|
|
|
push eax
|
|
mov eax,[CURRENT_TASK]
|
|
shl eax,5
|
|
mov eax,[eax+CURRENT_TASK+TASKDATA.pid]
|
|
mov [cd_status],eax
|
|
pop eax
|
|
sti
|
|
ret
|
|
|
|
reserve_cd_channel:
|
|
cmp [ChannelNumber],1
|
|
jne .IDE_Channel_2
|
|
.IDE_Channel_1:
|
|
cli
|
|
cmp [IDE_Channel_1],0
|
|
je .reserve_ok_1
|
|
sti
|
|
call change_task
|
|
jmp .IDE_Channel_1
|
|
.IDE_Channel_2:
|
|
cli
|
|
cmp [IDE_Channel_2],0
|
|
je .reserve_ok_2
|
|
sti
|
|
call change_task
|
|
jmp .IDE_Channel_1
|
|
.reserve_ok_1:
|
|
mov [IDE_Channel_1],1
|
|
ret
|
|
.reserve_ok_2:
|
|
mov [IDE_Channel_2],1
|
|
ret
|
|
|
|
free_cd_channel:
|
|
cmp [ChannelNumber],1
|
|
jne .IDE_Channel_2
|
|
.IDE_Channel_1:
|
|
mov [IDE_Channel_1],0
|
|
ret
|
|
.IDE_Channel_2:
|
|
mov [IDE_Channel_2],0
|
|
ret
|
|
|
|
uglobal
|
|
cd_status dd 0
|
|
endg
|
|
|
|
;----------------------------------------------------------------
|
|
;
|
|
; fs_CdRead - LFN variant for reading CD disk
|
|
;
|
|
; esi points to filename /dir1/dir2/.../dirn/file,0
|
|
; ebx pointer to 64-bit number = first wanted byte, 0+
|
|
; may be ebx=0 - start from first byte
|
|
; ecx number of bytes to read, 0+
|
|
; edx mem location to return data
|
|
;
|
|
; 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] ; ðåàëüíûé ðàçìåð ôàéëîâîé ñåêöèè
|
|
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 ; ÷èòàåì ñåêòîð ôàéëà
|
|
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 ; ÷èòàåì ñåêòîð ôàéëà
|
|
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
|
|
|
|
.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
|
|
;
|
|
; esi points to filename /dir1/dir2/.../dirn/file,0
|
|
; ebx pointer to structure 32-bit number = first wanted block, 0+
|
|
; & flags (bitfields)
|
|
; flags: bit 0: 0=ANSI names, 1=UNICODE names
|
|
; ecx number of blocks to read, 0+
|
|
; edx mem location to return data
|
|
;
|
|
; 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] ; ðàçìåð äèðåêòðîðèè
|
|
.doit:
|
|
; init header
|
|
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
|
|
; íà÷èíàåì ïåðåáðîñêó ÁÄÂÊ â ÓÑÂÊ
|
|
;.mainloop:
|
|
mov [cd_counter_block], dword 0
|
|
dec dword [CDSectorAddress]
|
|
push ecx
|
|
.read_to_buffer:
|
|
inc dword [CDSectorAddress]
|
|
mov [CDDataBuf_pointer], CDDataBuf
|
|
call ReadCDWRetr ; ÷èòàåì ñåêòîð äèðåêòîðèè
|
|
cmp [DevErrorCode], 0
|
|
jne .noaccess_1
|
|
call .get_names_from_buffer
|
|
sub eax,2048
|
|
; äèðåêòîðèÿ çàêîí÷èëàñü?
|
|
ja .read_to_buffer
|
|
mov edi, [cd_counter_block]
|
|
mov [edx+8], edi
|
|
mov edi, [ebx]
|
|
sub [edx+4], edi
|
|
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
|
|
mov esi,ebp
|
|
mov edi,[cd_mem_location]
|
|
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
|
|
call uni2ansi_char
|
|
cld
|
|
stosb
|
|
; ïðîâåðêà êîíöà ôàéëà
|
|
mov ax,[esi]
|
|
cmp ax,word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';'
|
|
je .cd_get_parameters_of_file_1
|
|
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì
|
|
movzx eax,byte [ebp-33]
|
|
add eax,ebp
|
|
sub eax,34
|
|
cmp esi,eax
|
|
je .cd_get_parameters_of_file_1
|
|
; ïðîâåðêà êîíöà ïàïêè
|
|
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
|
|
; ïðîâåðêà êîíöà ôàéëà
|
|
mov ax,[esi]
|
|
cmp ax,word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';'
|
|
je .cd_get_parameters_of_file_2
|
|
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì
|
|
movzx eax,byte [ebp-33]
|
|
add eax,ebp
|
|
sub eax,34
|
|
cmp esi,eax
|
|
je .cd_get_parameters_of_file_2
|
|
; ïðîâåðêà êîíöà ïàïêè
|
|
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:
|
|
; ïîëó÷àåì àòðèáóòû ôàéëà
|
|
xor eax,eax
|
|
; ôàéë íå àðõèâèðîâàëñÿ
|
|
inc eax
|
|
shl eax,1
|
|
; ýòî êàòàëîã?
|
|
test [ebp-8],byte 2
|
|
jz .file
|
|
inc eax
|
|
.file:
|
|
; ìåòêà òîìà íå êàê â FAT, â ýòîì âèäå îòñóòñâóåò
|
|
; ôàéë íå ÿâëÿåòñÿ ñèñòåìíûì
|
|
shl eax,3
|
|
; ôàéë ÿâëÿåòñÿ ñêðûòûì? (àòðèáóò ñóùåñòâîâàíèå)
|
|
test [ebp-8],byte 1
|
|
jz .hidden
|
|
inc eax
|
|
.hidden:
|
|
shl eax,1
|
|
; ôàéë âñåãäà òîëüêî äëÿ ÷òåíèÿ, òàê êàê ýòî CD
|
|
inc eax
|
|
mov [edi],eax
|
|
; ïîëó÷àåì âðåìÿ äëÿ ôàéëà
|
|
;÷àñ
|
|
movzx eax,byte [ebp-12]
|
|
shl eax,8
|
|
;ìèíóòà
|
|
mov al,[ebp-11]
|
|
shl eax,8
|
|
;ñåêóíäà
|
|
mov al,[ebp-10]
|
|
;âðåìÿ ñîçäàíèÿ ôàéëà
|
|
mov [edi+8],eax
|
|
;âðåìÿ ïîñëåäíåãî äîñòóïà
|
|
mov [edi+16],eax
|
|
;âðåìÿ ïîñëåäíåé çàïèñè
|
|
mov [edi+24],eax
|
|
; ïîëó÷àåì äàòó äëÿ ôàéëà
|
|
;ãîä
|
|
movzx eax,byte [ebp-15]
|
|
add eax,1900
|
|
shl eax,8
|
|
;ìåñÿö
|
|
mov al,[ebp-14]
|
|
shl eax,8
|
|
;äåíü
|
|
mov al,[ebp-13]
|
|
;äàòà ñîçäàíèÿ ôàéëà
|
|
mov [edi+12],eax
|
|
;âðåìÿ ïîñëåäíåãî äîñòóïà
|
|
mov [edi+20],eax
|
|
;âðåìÿ ïîñëåäíåé çàïèñè
|
|
mov [edi+28],eax
|
|
; ïîëó÷àåì òèï äàííûõ èìåíè
|
|
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
|
|
@@:
|
|
; ïîëó÷àåì ðàçìåð ôàéëà â áàéòàõ
|
|
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
|
|
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
|
|
push ebp
|
|
mov ebp, [cd_current_pointer_of_input]
|
|
add ebp, 33
|
|
call cd_get_parameters_of_file_1
|
|
pop ebp
|
|
and dword [edi+4], 0
|
|
pop edi
|
|
xor eax, eax
|
|
ret
|
|
|
|
;----------------------------------------------------------------
|
|
cd_find_lfn:
|
|
mov [cd_appl_data],0
|
|
; in: esi+ebp -> name
|
|
; out: CF=1 - file not found
|
|
; else CF=0 and [cd_current_pointer_of_input] direntry
|
|
push eax esi
|
|
; 16 ñåêòîð íà÷àëî íàáîðà äåñêðèïòîðîâ òîìîâ
|
|
mov [CDSectorAddress],dword 15
|
|
mov [CDDataBuf_pointer],CDDataBuf
|
|
|
|
call WaitUnitReady
|
|
cmp [DevErrorCode],0
|
|
jne .access_denied
|
|
|
|
call prevent_medium_removal
|
|
.start:
|
|
inc dword [CDSectorAddress]
|
|
call ReadCDWRetr ;_1
|
|
cmp [DevErrorCode],0
|
|
jne .access_denied
|
|
; ïðîâåðêà íà âøèâîñòü
|
|
cmp [CDDataBuf+1],dword 'CD00'
|
|
jne .access_denied
|
|
cmp [CDDataBuf+5],byte '1'
|
|
jne .access_denied
|
|
; ñåêòîð ÿâëÿåòñÿ òåðìèíàòîðîì íàáîð äåñêðèïòîðîâ òîìîâ?
|
|
cmp [CDDataBuf],byte 0xff
|
|
je .access_denied
|
|
; ñåêòîð ÿâëÿåòñÿ äîïîëíèòåëüíûì è óëó÷øåííûì äåñêðèïòîðîì òîìà?
|
|
cmp [CDDataBuf],byte 0x2
|
|
jne .start
|
|
; ñåêòîð ÿâëÿåòñÿ äîïîëíèòåëüíûì äåñêðèïòîðîì òîìà?
|
|
cmp [CDDataBuf+6],byte 0x1
|
|
jne .start
|
|
; ïàðàìåòðû root äèðåêòðîðèè
|
|
mov eax,[CDDataBuf+0x9c+2] ; íà÷àëî root äèðåêòðîðèè
|
|
mov [CDSectorAddress],eax
|
|
mov eax,[CDDataBuf+0x9c+10] ; ðàçìåð root äèðåêòðîðèè
|
|
cmp byte [esi], 0
|
|
jnz @f
|
|
mov [cd_current_pointer_of_input],CDDataBuf+0x9c
|
|
jmp .done
|
|
@@:
|
|
; íà÷èíàåì ïîèñê
|
|
.mainloop:
|
|
dec dword [CDSectorAddress]
|
|
.read_to_buffer:
|
|
inc dword [CDSectorAddress]
|
|
mov [CDDataBuf_pointer],CDDataBuf
|
|
call ReadCDWRetr ; ÷èòàåì ñåêòîð äèðåêòîðèè
|
|
cmp [DevErrorCode],0
|
|
jne .access_denied
|
|
push ebp
|
|
call cd_find_name_in_buffer
|
|
pop ebp
|
|
jnc .found
|
|
sub eax,2048
|
|
; äèðåêòîðèÿ çàêîí÷èëàñü?
|
|
cmp eax,0
|
|
ja .read_to_buffer
|
|
; íåò èñêîìîãî ýëåìåíòà öåïî÷êè
|
|
.access_denied:
|
|
pop esi eax
|
|
mov [cd_appl_data],1
|
|
stc
|
|
ret
|
|
; èñêîìûé ýëåìåíò öåïî÷êè íàéäåí
|
|
.found:
|
|
; êîíåö ïóòè ôàéëà
|
|
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] ; ðàçìåð äèðåêòîðèè
|
|
jmp .mainloop
|
|
; óêàçàòåëü ôàéëà íàéäåí
|
|
.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]
|
|
cmp eax,0 ; âõîäû çàêîí÷èëèñü?
|
|
je .next_sector
|
|
cmp ebp,CDDataBuf+2048 ; áóôåð çàêîí÷èëñÿ?
|
|
jae .next_sector
|
|
movzx eax, byte [ebp]
|
|
add [cd_current_pointer_of_input_2],eax ; ñëåäóþùèé âõîä êàòàëîãà
|
|
add ebp,33 ; óêàçàòåëü óñòàíîâëåí íà íà÷àëî èìåíè
|
|
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
|
|
; out: if names match: ZF=1 and esi->next component of name
|
|
; else: ZF=0, esi is not changed
|
|
; destroys eax
|
|
push esi eax edi
|
|
mov edi,ebp
|
|
.loop:
|
|
cld
|
|
lodsb
|
|
push eax
|
|
call char_todown
|
|
call ansi2uni_char
|
|
xchg ah,al
|
|
scasw
|
|
pop eax
|
|
je .coincides
|
|
call char_toupper
|
|
call ansi2uni_char
|
|
xchg ah,al
|
|
sub edi,2
|
|
scasw
|
|
jne .name_not_coincide
|
|
.coincides:
|
|
cmp [esi],byte '/' ; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà
|
|
je .done
|
|
cmp [esi],byte 0 ; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà
|
|
je .done
|
|
jmp .loop
|
|
.name_not_coincide:
|
|
pop edi eax esi
|
|
stc
|
|
ret
|
|
.done:
|
|
; ïðîâåðêà êîíöà ôàéëà
|
|
cmp [edi],word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';'
|
|
je .done_1
|
|
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì
|
|
movzx eax,byte [ebp-33]
|
|
add eax,ebp
|
|
sub eax,34
|
|
cmp edi,eax
|
|
je .done_1
|
|
; ïðîâåðêà êîíöà ïàïêè
|
|
movzx eax,byte [ebp-1]
|
|
add eax,ebp
|
|
cmp edi,eax
|
|
jne .name_not_coincide
|
|
.done_1:
|
|
pop edi eax
|
|
add esp,4
|
|
inc esi
|
|
clc
|
|
ret
|
|
|
|
char_todown:
|
|
; convert character to uppercase, using cp866 encoding
|
|
; in: al=symbol
|
|
; out: al=converted symbol
|
|
cmp al, 'A'
|
|
jb .ret
|
|
cmp al, 'Z'
|
|
jbe .az
|
|
cmp al, '€'
|
|
jb .ret
|
|
cmp al, '�'
|
|
jb .rus1
|
|
cmp al, 'Ÿ'
|
|
ja .ret
|
|
; 0x90-0x9F -> 0xE0-0xEF
|
|
add al, 'à'-'�'
|
|
.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
|
|
; 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, 'ð'
|
|
jmp .doit
|
|
.yo2:
|
|
mov al, 'ñ'
|
|
jmp .doit
|
|
.rus1:
|
|
; 0x410-0x43F -> 0x80-0xAF
|
|
add al, 0x70
|
|
jmp .doit
|
|
.rus2:
|
|
; 0x440-0x44F -> 0xE0-0xEF
|
|
add al, 0xA0
|
|
.ascii:
|
|
.doit:
|
|
ret
|