Files
KOS_qrcodes/programs/fs/kfar/trunk/filetool.inc
CleverMouse 8819a40f56 fix errors in error handling for copy operations
git-svn-id: svn://kolibrios.org@3165 a494cfbc-eb01-0410-851d-a64ba20cac60
2013-01-14 09:26:21 +00:00

2394 lines
68 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
delete_file_worker:
; in: ecx=flags: 1=deleting directory
; out: eax=0 - OK, eax=1 - retry, eax=2 - skip, eax=-1 - cancel,
; PF, ZF, CF and SF set accordingly to 'cmp eax,2' (or 'cmp al,2')
push ebx
push 70
pop eax
mov ebx, delinfo
int 0x40
pop ebx
test eax, eax
jz .ret
cmp [del_bSkipAll], 0
jz @f
push 2
pop eax
jmp .ret
@@:
push execdata
push aCannotDeleteFolder
test cl, 1
jnz @f
mov dword [esp], aCannotDeleteFile
@@:
call get_error_msg
push eax
mov eax, esp
push DeleteErrorBtn
push 4
push eax
push 3
call SayErr
add esp, 3*4
cmp al, -1
jz @f
inc eax
cmp al, 4 ; "cancel" button
jnz @f
or eax, -1
@@:
cmp al, 3 ; "skip all" button
jnz .ret
mov [del_bSkipAll], 1
dec eax
.ret:
cmp al, 2
ret
delete_file:
; in: eax->BDFE block
; out: CF and ZF not set <=> cancel job ("ja cancel_label")
pushad
mov [del_dir_stack_ptr], del_dir_stack
lea esi, [ebp + panel1_dir - panel1_data]
mov edi, execdata
@@:
lodsb
test al, al
jz @f
stosb
jmp @b
@@:
mov esi, [esp+28]
mov ecx, esi
add esi, 40
cmp byte [edi-1], '/'
jz .l1
mov al, '/'
stosb
.l1:
lodsb
cmp edi, execdataend
jb @f
call panels_OnKey.bigfilename
popad
ret
@@:
stosb
test al, al
jnz .l1
mov ecx, [esp+28]
test byte [ecx], 10h
jnz .delete_dir
.retrydel:
xor ecx, ecx
call delete_file_worker
jae @f
jp .retrydel
@@:
popad
ret
.delete_dir:
; recursive delete of directory
xor ebp, ebp ; ebp will contain number of undeletable items
.return_from_recursion:
mov ebx, dirinfo
mov [ebx+dirinfo.first-dirinfo], ebp
mov [ebx+dirinfo.size-dirinfo], del_dir_query_size
mov [ebx+dirinfo.dirdata-dirinfo], del_dir_query_area
mov [ebx+dirinfo.name-dirinfo], execdata
push 70
pop eax
int 0x40
; if we get read error, the best available action is try to delete directory itself
test eax, eax
jz @f
cmp eax, 6
jnz .do_delete_dir
@@:
; loop through a directory and delete items
mov edx, del_dir_query_area+32
imul ebx, 304
add ebx, edx
.delete_dir_entry_loop:
cmp edx, ebx
jb .do_delete_dir_entry
cmp ebx, del_dir_query_area+32+304*del_dir_query_size
jnz .delete_dir_entry_done
jmp .return_from_recursion
.do_delete_dir_entry:
; ignore special entries "." and ".."
inc ebp
cmp word [edx+40], '.'
jz .delete_dir_entry_continue
cmp word [edx+40], '..'
jnz @f
cmp byte [edx+42], 0
jz .delete_dir_entry_continue
@@:
dec ebp
mov esi, execdata
@@:
lodsb
test al, al
jnz @b
mov byte [esi-1], '/'
mov edi, esi
lea esi, [edx+40]
@@:
cmp edi, execdataend
jae .fullname_big
lodsb
stosb
test al, al
jnz @b
test byte [edx], 10h
jnz .entry_is_folder
.retry2:
xor ecx, ecx
call delete_file_worker
ja .cancel
jz .skip
jp .retry2
jmp .restore_name
.entry_is_folder:
; allocate new item in directory stack
mov eax, [del_dir_stack_ptr]
mov [eax], ebp
add eax, 4
mov [del_dir_stack_ptr], eax
; do recursive deleting
jmp .delete_dir
.fullname_big:
; we will just ignore such files and continue - in real life this situation can not happen
inc ebp
mov esi, execdataend-1
jmp .do_restore_name
.skip:
inc ebp
.restore_name:
mov esi, execdata
@@:
lodsb
test al, al
jnz @b
dec esi
dec esi
.do_restore_name:
call delete_last_name
.delete_dir_entry_continue:
add edx, 304
jmp .delete_dir_entry_loop
.delete_dir_entry_done:
.do_delete_dir:
mov cl, 1
call delete_file_worker
ja .cancel
jz @f
jp .delete_dir
@@:
; al=0 - OK, al=2 - skip this directory
; return to previous directory
; pop item from directory stack
mov ecx, [del_dir_stack_ptr]
cmp ecx, del_dir_stack
jbe .done
sub ecx, 4
mov [del_dir_stack_ptr], ecx
mov ebp, [ecx]
cmp al, 2
sbb ebp, -1
; restore prev directory name
mov esi, execdata
call delete_last_name_from_end
jmp .return_from_recursion
.done:
.cancel:
mov [dirinfo.first], 0 ; do not destroys flags
popad
ret
makedir:
; create directory with name from CopyDestEditBuf+12
; destroys eax
push ebx
push 70
pop eax
mov ebx, mkdirinfo
int 0x40
pop ebx
test eax, eax
jz .ret
cmp dword [esp+8], DeleteErrorBtn
jnz @f
cmp [copy_bSkipAll], 0
jz @f
push 1
pop eax
jmp .ret
@@:
push dword CopyDestEditBuf+12
push dword aCannotMakeFolder
call get_error_msg
push eax
mov eax, esp
push dword [eax+20]
push dword [eax+16]
push eax
push 3
call SayErr
add esp, 3*4
test eax, eax
jz makedir
.ret:
ret 8
copy_file_worker:
; in: execdata = source name, CopyDestEditBuf+12 = destination name, edx = BDFE block for source
; out: CF and ZF not set <=> cancel job ("ja cancel_label")
; destroys eax,esi,edi
lea edi, [edx+40]
and [source_hFile], 0
copy_file_worker2:
push CopyDestEditBuf+12+513
cmp [bDestIsFolder], 0
jz .noaddtoname
mov esi, CopyDestEditBuf+12
@@:
lodsb
test al, al
jnz @b
pop eax
dec esi
push esi
cmp byte [esi-1], '/'
jz @f
mov byte [esi], '/'
inc esi
@@:
xchg esi, edi
@@:
cmp edi, CopyDestEditBuf+12+513
jae .overflow
lodsb
stosb
test al, al
jnz @b
jmp .noaddtoname
.overflow:
.ret_zf:
pop esi
and byte [esi], 0 ; ZF=1
ret
.noaddtoname:
; <EFBFBD>¥«ì§ï ᪮¯¨à®¢ âì ä ©« ¯®¢¥àå á ¬®£® ᥡï!
mov esi, execdata
mov edi, CopyDestEditBuf+12
cmp [source_hModule], 0
jnz @f
push esi edi
call strcmpi
pop edi esi
jnz @f
push esi
push aCannotCopyToSelf
mov eax, esp
push ContinueBtn
push 1
push eax
push 2
call SayErr
pop eax
pop eax
jmp .ret_zf
@@:
; ‘®¡á⢥­­®, ª®¯¨à㥬
; esi->source name, edi->destination name
push ebx
mov [writeinfo.code], 2
mov [writeinfo.name], edi
and dword [writeinfo.first], 0
and dword [writeinfo.first+4], 0
mov [writeinfo.data], copy_buffer
mov ebx, readinfo
and dword [ebx+readinfo.first-readinfo], 0
and dword [ebx+readinfo.first+4-readinfo], 0
mov [ebx+readinfo.size-readinfo], copy_buffer_size
mov [ebx+readinfo.data-readinfo], copy_buffer
mov [ebx+readinfo.name-readinfo], esi
mov eax, [source_hFile]
push eax
test eax, eax
jnz .copyloop
.source_reopen:
mov eax, [source_hModule]
test eax, eax
jz .copyloop
pushad
push O_READ+O_SEQUENTIAL_ONLY
push esi
push [source_hPlugin]
call [eax+PluginInfo.open]
mov [source_hFile], eax
popad
.copyloop:
mov ebx, readinfo
mov eax, [source_hModule]
test eax, eax
jz .native
mov ecx, [source_hFile]
jecxz .readerr
pushad
push [ebx+readinfo.size-readinfo]
push [ebx+readinfo.data-readinfo]
push ecx
call [eax+PluginInfo.read]
mov [esp+28], eax
popad
cmp eax, -1
jz .readerr
mov ebx, eax
jmp .copyreadok
.native:
push 70
pop eax
int 0x40
test eax, eax
jz .copyreadok
cmp eax, 6
jz .copyreadok
.readerr:
cmp [copy_bSkipAll2], 0
jnz .copyfailed_del2
push esi
push dword aCannotReadFile
call get_error_msg
push eax
mov eax, esp
push dword DeleteErrorBtn
push 4
push eax
push 3
call SayErr
add esp, 3*4
test eax, eax
jnz .copyfailed_parseuser
cmp [source_hModule], 0
jz .copyloop
cmp [source_hFile], 0
jz .source_reopen
jmp .copyloop
.copyreadok:
add dword [readinfo.first], ebx
adc dword [readinfo.first+4], 0
mov [writeinfo.size], ebx
test ebx, ebx
jnz .copywrite
cmp byte [writeinfo.code], 2
jnz .copydone
.copywrite:
mov ebx, writeinfo
push 70
pop eax
int 0x40
test eax, eax
jz .copywriteok
cmp [copy_bSkipAll2], 0
jnz .copyfailed_del2
push edi
push dword aCannotWriteFile
call get_error_msg
push eax
mov eax, esp
push dword DeleteErrorBtn
push 4
push eax
push 3
call SayErr
add esp, 3*4
test eax, eax
jz .copywrite
.copyfailed_parseuser:
cmp al, 2
jnz @f
mov [copy_bSkipAll2], 1
dec eax
@@:
cmp al, 1
pushf
jmp .copyfailed
.copywriteok:
mov ecx, [writeinfo.size]
add dword [writeinfo.first], ecx
adc dword [writeinfo.first+4], 0
mov [writeinfo.code], 3
cmp ecx, copy_buffer_size
jz .copyloop
.copydone:
pop ecx
test ecx, ecx
jnz @f
mov eax, [source_hModule]
test eax, eax
jz @f
mov ecx, [source_hFile]
jecxz @f
push edx
push ecx
call [eax+PluginInfo.close]
pop edx
@@:
; now try to set attributes from source, ignore errors
mov edi, attrinfo.attr
mov esi, edx
push 8
pop ecx
rep movsd
; replace zero dates with default values
mov eax, [default_attr]
cmp dword [edi-32+8], 0
jnz @f
mov ecx, [eax+8]
mov [edi-32+8], ecx
mov ecx, [eax+12]
mov [edi-32+12], ecx
@@:
cmp dword [edi-32+16], 0
jnz @f
mov ecx, [eax+16]
mov [edi-32+16], ecx
mov ecx, [eax+20]
mov [edi-32+20], ecx
@@:
cmp dword [edi-32+24], 0
jnz @f
mov ecx, [eax+24]
mov [edi-32+24], ecx
mov ecx, [eax+28]
mov [edi-32+28], ecx
@@:
mov ebx, attrinfo
mov [ebx+attrinfo.name-attrinfo], CopyDestEditBuf+12
inc dword [ebx]
push 70
pop eax
push ebx
int 0x40
pop ebx
dec dword [ebx]
xor eax, eax ; ZF=1
.ret:
pop ebx
pop esi
mov byte [esi], 0
ret
.copydone2:
popf
jmp .ret
.copyfailed:
pop eax
pop ecx
push eax
test ecx, ecx
jnz @f
mov eax, [source_hModule]
test eax, eax
jz @f
mov ecx, [source_hFile]
jecxz @f
push ecx
call [eax+PluginInfo.close]
@@:
cmp [bConfirmDeleteIncomplete], 0
jz .copyfailed_del
cmp [writeinfo.code], 2
jz .copydone2
push dword aIncompleteFile
mov eax, esp
push dword DeleteOrKeepBtn
push 2
push eax
push 1
push dword aCopyCaption
call Message
add esp, 4
test eax, eax
jnz .copydone2
.copyfailed_del:
mov ebx, delinfo
push dword [ebx+21]
mov dword [ebx+21], edi
push 70
pop eax
int 0x40
; ignore errors
pop dword [delinfo+21]
jmp .copydone2
.copyfailed_del2:
xor eax, eax
pushf
jmp .copyfailed_del
copy_file:
; in: eax->BDFE block for source, CopyDestEditBuf+12 contains ASCIIZ full name for destination
; out: CF and ZF not set <=> cancel job ("ja cancel_label")
pushad
mov [copy_dir_stack_ptr], copy_dir_stack
mov [bNeedRestoreName], 0
lea esi, [ebp + panel1_dir - panel1_data]
mov edi, execdata
@@:
lodsb
test al, al
jz @f
stosb
jmp @b
@@:
mov esi, [esp+28]
add esi, 40
cmp byte [edi-1], '/'
jz .l1
mov al, '/'
stosb
.l1:
lodsb
cmp edi, execdataend
jb @f
call panels_OnKey.bigfilename
stc
popad
ret
@@:
stosb
test al, al
jnz .l1
mov edx, [esp+28]
test byte [edx], 10h
jnz .copy_dir
call copy_file_worker
.popad_ret:
popad
ret
.biiig:
mov byte [edi-1], 0
jmp .popad_ret
.copy_dir:
; recursive copy of directory
cmp [bDestIsFolder], 0
mov [bDestIsFolder], 0
jz .target_created
mov [bNeedRestoreName], 1
mov esi, CopyDestEditBuf+12
@@:
lodsb
test al, al
jnz @b
dec esi
cmp byte [esi-1], '/'
jz @f
mov byte [esi], '/'
inc esi
@@:
mov edi, esi
lea esi, [edx+40]
@@:
cmp edi, CopyDestEditBuf+12+513
jae .biiig
lodsb
stosb
test al, al
jnz @b
.create_target:
.enter_recursion:
push DeleteErrorBtn
push 4
call makedir
jz .target_created
cmp al, 2
jnz @f
dec eax
mov [copy_bSkipAll], 1
@@:
cmp al, 1
jz .copy_dir_entry_done
jmp .cancel2
.target_created:
mov edx, [source_hModule]
test edx, edx
jz .nosetdir
mov esi, execdata
push esi ; absolute_path
@@:
lodsb
test al, al
jnz @b
@@:
dec esi
cmp byte [esi-1], '/'
jnz @b
push esi ; relative_path
push [source_hPlugin] ; hPlugin
call [edx+PluginInfo.SetFolder]
test al, al
jnz .nosetdir
cmp [copy_bSkipAll3], 0
jz .skip2
push execdata
push aCannotSetFolder
mov eax, esp
push DeleteErrorBtn
push 4
push eax
push 2
call SayErr
pop ecx ecx
test al, al
jz .target_created
cmp al, 2
setz [copy_bSkipAll3]
ja .cancel2
jmp .skip2
.nosetdir:
xor ebp, ebp ; ebp will contain number of copied items
.return_from_recursion:
.read_retry:
mov ebx, dirinfo
mov [ebx+dirinfo.first-dirinfo], ebp
mov [ebx+dirinfo.size-dirinfo], copy_dir_query_size
mov [ebx+dirinfo.dirdata-dirinfo], copy_dir_query_area
mov [ebx+dirinfo.name-dirinfo], execdata
mov eax, [source_hModule]
test eax, eax
jz .readfolder_native
push ebp
push [ebx+dirinfo.dirdata-dirinfo]
push [ebx+dirinfo.size-dirinfo]
push [ebx+dirinfo.first-dirinfo]
push [source_hPlugin]
call [eax+PluginInfo.ReadFolder]
pop ebp
mov ebx, dword [copy_dir_query_area+4]
jmp @f
.readfolder_native:
push 70
pop eax
int 0x40
@@:
test eax, eax
jz .readok
cmp eax, 6
jz .readok
; read error
cmp [copy_bSkipAll], 0
jnz .skip1
mov edx, execdata
call recursive_read_folder_err
jz .read_retry
cmp al, 2
jnz @f
dec eax
mov [copy_bSkipAll], 1
@@:
cmp al, 1
jz .skip1
jmp .cancel
.readok:
; loop through a directory and copy items
mov edx, copy_dir_query_area+32
imul ebx, 304
add ebx, edx
.copy_dir_entry_loop:
cmp edx, ebx
jb .do_copy_dir_entry
cmp ebx, copy_dir_query_area+32+copy_dir_query_size*304
jz .return_from_recursion
jmp .copy_dir_entry_done
.do_copy_dir_entry:
inc ebp
; ignore special entries "." and ".."
cmp word [edx+40], '.'
jz .copy_dir_entry_continue
cmp word [edx+40], '..'
jnz @f
cmp byte [edx+42], 0
jz .copy_dir_entry_continue
@@:
mov esi, execdata
@@:
lodsb
test al, al
jnz @b
dec esi
cmp byte [esi-1], '/'
jz @f
mov byte [esi], '/'
inc esi
@@:
mov edi, esi
lea esi, [edx+40]
@@:
cmp edi, execdataend
jae .fullname_big
lodsb
stosb
test al, al
jnz @b
mov esi, CopyDestEditBuf+12
@@:
lodsb
test al, al
jnz @b
dec esi
cmp byte [esi-1], '/'
jz @f
mov byte [esi], '/'
inc esi
@@:
mov edi, esi
lea esi, [edx+40]
@@:
cmp edi, CopyDestEditBuf+513
jae .fullname2_big
lodsb
stosb
test al, al
jnz @b
test byte [edx], 10h
jnz .entry_is_folder
call copy_file_worker
ja .cancel3
jmp .restore_name
.entry_is_folder:
; allocate new item in directory stack
mov eax, [copy_dir_stack_ptr]
mov [eax], ebp
add eax, 4
mov [copy_dir_stack_ptr], eax
; do recursive copying
jmp .enter_recursion
.fullname_big:
; we will just ignore such files and continue - in real life this situation can not happen
mov esi, execdataend-1
jmp .do_restore_name2
.fullname2_big:
mov esi, CopyDestEditBuf+12+512
jmp .restore_name2
.restore_name:
mov esi, CopyDestEditBuf+12
@@:
lodsb
test al, al
jnz @b
dec esi
dec esi
.restore_name2:
call delete_last_name
mov esi, execdata
@@:
lodsb
test al, al
jnz @b
dec esi
dec esi
.do_restore_name2:
call delete_last_name
.copy_dir_entry_continue:
add edx, 304
jmp .copy_dir_entry_loop
.skip1:
.copy_dir_entry_done:
; return to previous directory
mov esi, execdata
call delete_last_name_from_end
mov eax, [source_hModule]
test eax, eax
jz @f
push execdata
push aDotDot
push [source_hPlugin]
call [eax+PluginInfo.SetFolder]
jmp @f
.skip2:
mov esi, execdata
call delete_last_name_from_end
@@:
; pop item from directory stack
mov ecx, [copy_dir_stack_ptr]
cmp ecx, copy_dir_stack
jbe .done
sub ecx, 4
mov [copy_dir_stack_ptr], ecx
mov ebp, [ecx]
; restore prev directory name
mov esi, CopyDestEditBuf+12
call delete_last_name_from_end
jmp .return_from_recursion
.done:
mov [dirinfo.first], 0 ; do not destroys flags
popad
ret
.cancel2:
sub [copy_dir_stack_ptr], 4
.cancel3:
mov esi, execdata
call delete_last_name_from_end
.cancel:
mov eax, [source_hModule]
test eax, eax
jz .cancel.ret
cmp [copy_dir_stack_ptr], copy_dir_stack
jb .cancel.ret
push execdata
push aDotDot
push [source_hPlugin]
call [eax+PluginInfo.SetFolder]
jmp .cancel2
.cancel.ret:
xor eax, eax
inc eax
jmp .done
delete_last_name_from_end:
lodsb
test al, al
jnz delete_last_name_from_end
dec esi
dec esi
delete_last_name:
std
@@:
lodsb
cmp al, '/'
jnz @b
cld
inc esi
cmp esi, execdata
jz @f
cmp esi, CopyDestEditBuf+12
jz @f
dec esi
@@:
mov byte [esi+1], 0
ret
recursive_read_folder_err:
push edx
push aCannotReadFolder
call get_error_msg
push eax
mov eax, esp
push DeleteErrorBtn
push 4
push eax
push 3
call SayErr
add esp, 3*4
test al, al
ret
recursive_read_file_err:
push edx
push aCannotReadFile
call get_error_msg
push eax
mov eax, esp
push DeleteErrorBtn
push 4
push eax
push 3
call SayErr
add esp, 3*4
test al, al
ret
copy_AddDir:
push 1
pop eax ; for "return true"
pushad
mov esi, CopyDestEditBuf+12
@@:
lodsb
test al, al
jnz @b
cmp byte [esi-2], '/'
jnz @f
dec esi
@@:
push dword [esi-1]
push esi
mov byte [esi-1], '/'
mov edi, esi
mov esi, [esp+28h+4]
.0:
lodsb
stosb
cmp edi, CopyDestEditBuf+12+512
jae .done
test al, al
jnz .0
push RetryOrCancelBtn
push 2
call makedir
jz .done
and dword [esp+8+1Ch], 0
.done:
pop esi
pop dword [esi-1]
popad
ret 8
copy_AddFile:
pushad
mov eax, [esp+20h+12]
mov [source_hFile], eax
mov edx, [esp+20h+8]
mov edi, [esp+20h+4]
call copy_file_worker2
popad
setna al
ret 12
search_dir_query_size = 32
search_filebuf_size = 32768
virtual at 0
filesearch_data:
.prev_screen_vtable dd ? ; previous in window stack
.prev_screen_data dd ?
.tid dd ? ; -1 for query stage, secondary thread id for search stage
.slot dd ? ; 0 if secondary thread is not running, it's slot otherwise
.result_blocks dd ? ; head of heap blocks for resulting data
.cur_result_ptr dd ? ; offset of free data in the current heap block for result
.stop db ? ; set to 1 when secondary thread need to be stopped
.skip_errors_mask db ?
.skip_read_folder = 1
.skip_set_folder = 2
.skip_open_file = 4
.skip_read_file = 8
.skip_bigname = 10h
.updating db ?
.datachanged db ?
.list.curitemptr dd ?
.list.numitems dd ?
.list.head dd ?
.list.curitem dd ?
.list.end dd ?
.query_dlgdata rb filesearch_query_template.size
.search_dlgdata rb filesearch_search_template.size
.mask.maxlen dd ?
.mask.pos dd ?
.mask.start dd ?
.mask rb 512
.string.maxlen dd ?
.string.pos dd ?
.string.start dd ?
.string rb 256
.caption rb 268
.statusstr rb 80
.stack rb 8192
.stacktop = $
.fs.func dd ?
.fs.pos_low dd ?
.fs.pos_high dd ?
.fs.size dd ?
.fs.ptr dd ?
.curfile rb 1024
.curdir rb 1024
.lowername rb 264
.dir_area rb 32 + 304*search_dir_query_size
.filebuf rb search_filebuf_size
.size = $
end virtual
panels_OnKey.alt_f7:
mov ecx, filesearch_data.size
mov edx, filesearch_vtable
call new_screen
test eax, eax
jnz @f
ret
@@:
mov [ebp+filesearch_data.prev_screen_vtable], panels_vtable
mov ecx, (filesearch_query_template.size + filesearch_search_template.size) / 4
mov esi, filesearch_query_template
lea edi, [ebp+filesearch_data.query_dlgdata]
rep movsd
lea eax, [ebp+filesearch_data.string.maxlen]
xor ebx, ebx
mov dword [ebp+filesearch_data.query_dlgdata+filesearch_query_template.editptr2-filesearch_query_template], eax
mov dword [eax], 253
mov [eax+4], ebx
mov [eax+8], ebx
mov [eax+12], bl
sub eax, filesearch_data.string - filesearch_data.mask
mov dword [ebp+filesearch_data.query_dlgdata+filesearch_query_template.editptr1-filesearch_query_template], eax
mov dword [eax], 511
mov [eax+8], ebx
inc ebx
mov word [eax+12], '*'
mov [eax+4], ebx
mov eax, [find_in_file_dlgdata.flags_case]
and al, 10h
or al, 8
mov dword [ebp+filesearch_data.query_dlgdata+filesearch_query_template.flags_case-filesearch_query_template], eax
mov eax, [find_in_file_dlgdata.flags_whole]
and al, 10h
or al, 8
mov dword [ebp+filesearch_data.query_dlgdata+filesearch_query_template.flags_whole-filesearch_query_template], eax
lea edi, [ebp+filesearch_data.caption]
mov dword [ebp+dlgtemplate.title+filesearch_data.search_dlgdata], edi
lea eax, [ebp+filesearch_data.list.curitemptr]
mov dword [ebp+filesearch_data.search_dlgdata+filesearch_search_template.data1-filesearch_search_template], eax
.reinit:
xor ebx, ebx
or [ebp+filesearch_data.tid], -1
mov [ebp+filesearch_data.slot], ebx
mov [ebp+filesearch_data.result_blocks], ebx
mov [ebp+filesearch_data.cur_result_ptr], 0x4000
mov [ebp+filesearch_data.list.curitemptr], ebx
mov [ebp+filesearch_data.list.numitems], ebx
mov [ebp+filesearch_data.list.head], ebx
mov [ebp+filesearch_data.list.curitem], ebx
mov [ebp+filesearch_data.list.end], ebx
mov [ebp+filesearch_data.stop], bl
mov al, [dialog_main_color]
mov [ebp+filesearch_data.query_dlgdata+dlgtemplate.main_color], al
mov [ebp+filesearch_data.search_dlgdata+dlgtemplate.main_color], al
mov al, [dialog_border_color]
mov [ebp+filesearch_data.query_dlgdata+dlgtemplate.border_color], al
mov [ebp+filesearch_data.search_dlgdata+dlgtemplate.border_color], al
mov al, [dialog_header_color]
mov [ebp+filesearch_data.query_dlgdata+dlgtemplate.header_color], al
mov [ebp+filesearch_data.search_dlgdata+dlgtemplate.header_color], al
filesearch_OnRedraw:
push ebp
mov byte [draw_image], 0xC3
mov eax, [ebp+filesearch_data.prev_screen_vtable]
mov ebp, [ebp+filesearch_data.prev_screen_data]
call dword [eax+screen_vtable.OnRedraw]
mov byte [draw_image], 0xC6
pop ebp
cmp [ebp+filesearch_data.tid], -1
jnz .prepare_search_dlg
lea ebx, [ebp+filesearch_data.query_dlgdata]
mov eax, [cur_width]
mov [ebx + dlgtemplate.x], 6
sub eax, 12
mov [ebx + dlgtemplate.width], eax
dec eax
dec eax
mov [ebx - filesearch_query_template + filesearch_query_template.width2], eax
mov [ebx - filesearch_query_template + filesearch_query_template.width3], eax
shr eax, 1
dec eax
dec eax
mov [ebx - filesearch_query_template + filesearch_query_template.search_x2], eax
sub eax, aSearchBLength-1
mov [ebx - filesearch_query_template + filesearch_query_template.search_x1], eax
add eax, aSearchBLength+3
mov [ebx - filesearch_query_template + filesearch_query_template.cnl_x1], eax
add eax, aCancelBLength-1
mov [ebx - filesearch_query_template + filesearch_query_template.cnl_x2], eax
mov eax, [cur_height]
sub eax, [ebx + dlgtemplate.height]
shr eax, 1
mov [ebx + dlgtemplate.y], eax
jmp .dlg_prepared
.prepare_search_dlg:
lea ebx, [ebp+filesearch_data.search_dlgdata]
; width: for big screens use all screen except for one column on each side,
; that is, [cur_width] - 10 (standard frame width is 4);
; if [cur_width]-10 does not contain enough place for all buttons with two spaces between them,
; but [cur_width]-2 does, use fixed size = place for all buttons with two spaces between them
; for small screens use [cur_width]-2 as maximum possible
.btnsize = 2 + aNewSearchLen + 2 + aGotoLen + 2 + aViewLen + 2 + aCancelB2Length + 2
mov eax, [cur_width]
mov edx, eax
sub eax, 10
cmp eax, .btnsize
jae @f
add eax, 8
cmp eax, .btnsize
jb @f
mov al, .btnsize
@@:
mov [ebx + dlgtemplate.width], eax
sub edx, eax
shr edx, 1
mov [ebx + dlgtemplate.x], edx
dec eax
mov [ebx + filesearch_search_template.width1 - filesearch_search_template], eax
mov [ebx + filesearch_search_template.width4 - filesearch_search_template], eax
cmp [ebp + filesearch_data.slot], 0
jnz @f
mov [ebx + filesearch_search_template.width3 - filesearch_search_template], eax
@@:
sub eax, aNewSearchLen + aGotoLen + aViewLen + aCancelB2Length - 1
cdq
push 5
pop ecx
idiv ecx
sar edx, 1
add edx, eax
inc eax
mov [ebx + filesearch_search_template.btn1x1 - filesearch_search_template], edx
add edx, aNewSearchLen-1
mov [ebx + filesearch_search_template.btn1x2 - filesearch_search_template], edx
add edx, eax
mov [ebx + filesearch_search_template.btn2x1 - filesearch_search_template], edx
add edx, aGotoLen-1
mov [ebx + filesearch_search_template.btn2x2 - filesearch_search_template], edx
add edx, eax
mov [ebx + filesearch_search_template.btn3x1 - filesearch_search_template], edx
add edx, aViewLen-1
mov [ebx + filesearch_search_template.btn3x2 - filesearch_search_template], edx
add edx, eax
mov [ebx + filesearch_search_template.btn4x1 - filesearch_search_template], edx
add edx, aCancelB2Length-1
mov [ebx + filesearch_search_template.btn4x2 - filesearch_search_template], edx
mov eax, [cur_height]
mov edx, eax
sub eax, 8
cmp eax, 6
jae @f
mov eax, 6
@@:
mov [ebx + dlgtemplate.height], eax
sub edx, eax
shr edx, 1
mov [ebx + dlgtemplate.y], edx
dec eax
mov [ebx + filesearch_search_template.btn1y - filesearch_search_template], eax
mov [ebx + filesearch_search_template.btn2y - filesearch_search_template], eax
mov [ebx + filesearch_search_template.btn3y - filesearch_search_template], eax
mov [ebx + filesearch_search_template.btn4y - filesearch_search_template], eax
dec eax
mov [ebx + filesearch_search_template.y5 - filesearch_search_template], eax
dec eax
mov [ebx + filesearch_search_template.y3 - filesearch_search_template], eax
mov [ebx + filesearch_search_template.y4 - filesearch_search_template], eax
dec eax
mov [ebx + filesearch_search_template.y2 - filesearch_search_template], eax
dec eax
mov [ebx + filesearch_search_template.height1 - filesearch_search_template], eax
.dlg_prepared:
call draw_dialog_shadow
push ebx
call DrawDialogBox
ret
filesearch_OnActivate:
mov eax, [active_screen_data]
cmp eax, ebp
jz @f
mov [ebp+filesearch_data.prev_screen_data], eax
mov eax, [active_screen_vtable]
mov [ebp+filesearch_data.prev_screen_vtable], eax
@@:
mov eax, [ebp+filesearch_data.prev_screen_data]
mov ecx, [num_screens]
mov edx, [screens]
push edx
@@:
cmp [edx+4], eax
jz @f
add edx, 8
loop @b
@@:
pop edx
jz @f
mov eax, [active_screen]
dec eax
mov ecx, [edx+eax*8+4]
mov [ebp+filesearch_data.prev_screen_data], ecx
mov ecx, [edx+eax*8]
mov [ebp+filesearch_data.prev_screen_vtable], ecx
@@:
cmp [ebp+filesearch_data.slot], 0
jz @f
mov [idle_interval], 10
@@:
; ret ; continue to filesearch_OnIdle
filesearch_OnIdle:
xor eax, eax
xchg al, [ebp+filesearch_data.datachanged]
cmp al, 1
ja .done
jz .new
.ret:
ret
.done:
call filesearch_wait_thread
call filesearch_done
.new:
jmp filesearch_OnRedraw
filesearch_OnKey:
cmp al, 0x58
jz F12
cmp [ebp+filesearch_data.tid], -1
jz .handle_generic
cmp al, 0x47
jb .notforlist
cmp al, 0x49
jbe @f
cmp al, 0x4F
jb .notforlist
cmp al, 0x51
ja .notforlist
@@:
push ebp
add ebp, filesearch_data.search_dlgdata
lea ebx, [ebp+dlgtemplate.size+12]
call listbox_key
call draw_listbox
call draw_image
pop ebp
ret
.notforlist:
cmp al, 0x3D
jz .view
.handle_generic:
push ebp
call filesearch_getcurdlg
push 0
push eax
push 2
push ebx
call ManagerDlgProc
pop ebp
test eax, eax
jz filesearch_OnIdle.ret
cmp eax, -1
jz .esc
sub eax, ebp
cmp eax, filesearch_data.query_dlgdata+filesearch_query_template.search_btn-filesearch_query_template
jz .query
cmp eax, filesearch_data.search_dlgdata+filesearch_search_template.btn1-filesearch_search_template
jz .newsearch
cmp eax, filesearch_data.search_dlgdata+filesearch_search_template.btn2-filesearch_search_template
jz .goto
cmp eax, filesearch_data.search_dlgdata+filesearch_search_template.btn3-filesearch_search_template
jz .view
.esc:
cmp dword [ebp+filesearch_data.slot], 0
jz .exit
mov [ebp+filesearch_data.stop], 2
call ConfirmCancel
setz [ebp+filesearch_data.stop]
.ret:
ret
.exit:
call filesearch_OnExit
jmp delete_active_screen
.view:
mov esi, [ebp+filesearch_data.list.curitemptr]
test esi, esi
jz .ret
add esi, 8
mov eax, esi
jmp view_file
.goto:
mov esi, [ebp+filesearch_data.list.curitemptr]
test esi, esi
jz .ret
add esi, 8
cmp byte [esi], '/'
jnz .ret
cmp byte [esi+1], 0
jz .ret
push ebp
mov ebp, [active_panel]
push esi
call close_plugin_panels
pop esi
mov ecx, esi
@@:
lodsb
test al, al
jnz @b
@@:
dec esi
cmp byte [esi], '/'
jnz @b
mov byte [esi], 0
inc esi
mov edi, saved_file_name
@@:
lodsb
stosb
test al, al
jnz @b
mov esi, ecx
lea edi, [ebp + panel1_dir - panel1_data]
push esi edi
call strcmpi
pop edi esi
jz .goto.samedir
@@:
lodsb
stosb
test al, al
jnz @b
and [ebp + panel1_start - panel1_data], 0
and [ebp + panel1_index - panel1_data], 0
.goto.samedir:
push @f
push [ebp + panel1_index - panel1_data]
jmp panels_OnKey.ctrl_r.doread
@@:
pop ebp
jmp .exit
.newsearch:
cmp [ebp+filesearch_data.slot], 0
jz .do.newsearch
call filesearch_stop_thread
.do.newsearch:
call filesearch_free_result
jmp panels_OnKey.alt_f7.reinit
.query:
mov esi, [active_panel]
cmp [esi + panel1_hPlugin - panel1_data], 0
jz @f
push aCannotSearchOnPlugin
mov eax, esp
push ContinueBtn
push 1
push eax
push 1
call SayErr
pop eax
jmp .exit
@@:
add esi, panel1_dir - panel1_data
lea edi, [ebp+filesearch_data.curdir]
@@:
lodsb
stosb
test al, al
jnz @b
push 51
pop eax
push 1
pop ebx
mov ecx, filesearch_thread
lea edx, [ebp+filesearch_data.stacktop-4]
mov [edx], ebp
int 40h
cmp eax, -1
jnz @f
push ContinueBtn
push 1
push aCannotCreateThread_ptr
push 1
call SayErr
ret
@@:
mov [ebp+filesearch_data.tid], eax
mov [ebp+filesearch_data.updating], 0
mov [ebp+filesearch_data.datachanged], 0
xchg eax, ecx
push 18
pop eax
push 21
pop ebx
int 40h
mov [ebp+filesearch_data.slot], eax
mov [idle_interval], 10
mov esi, aFileSearch
mov edi, dword [ebp+filesearch_data.search_dlgdata+dlgtemplate.title]
@@:
lodsb
stosb
test al, al
jnz @b
mov byte [edi-1], ':'
mov al, ' '
stosb
lea esi, [ebp+filesearch_data.mask]
@@:
lodsb
stosb
test al, al
jnz @b
lea edi, [ebp+filesearch_data.statusstr]
mov dword [ebp+filesearch_data.search_dlgdata+filesearch_search_template.data3-filesearch_search_template], edi
mov esi, aSearchingIn
@@:
lodsb
stosb
cmp al, '"'
jnz @b
push esi
push 10
pop ecx
lea esi, [ebp+filesearch_data.string]
@@:
lodsb
test al, al
jz @f
stosb
loop @b
@@:
pop esi
movsb
jz @f
mov byte [edi-1], '.'
mov byte [edi-2], '.'
mov byte [edi-3], '.'
mov byte [edi-4], '"'
@@:
cmp byte [edi-2], '"'
jnz @f
sub edi, 3
@@:
lodsb
stosb
test al, al
jnz @b
sub edi, dword [ebp+filesearch_data.search_dlgdata+filesearch_search_template.data3-filesearch_search_template]
mov dword [ebp+filesearch_data.search_dlgdata+filesearch_search_template.width3-filesearch_search_template], edi
inc edi
mov dword [ebp+filesearch_data.search_dlgdata+filesearch_search_template.x4-filesearch_search_template], edi
lea eax, [ebp+filesearch_data.curdir]
mov dword [ebp+filesearch_data.search_dlgdata+filesearch_search_template.data4-filesearch_search_template], eax
call filesearch_set_dlgflags ; use it? I think, yes
cmp [ebp+filesearch_data.slot], 0
jnz @f
call filesearch_done
@@:
jmp filesearch_OnRedraw
filesearch_done:
cmp [active_screen_data], ebp
jnz @f
or [idle_interval], -1
@@:
and dword [ebp+filesearch_data.search_dlgdata+filesearch_search_template.data4-filesearch_search_template], 0
mov edi, dword [ebp+filesearch_data.search_dlgdata+filesearch_search_template.data3-filesearch_search_template]
mov esi, aSearchDone
@@:
lodsb
stosb
cmp al, '?'
jnz @b
dec edi
mov eax, [ebp+filesearch_data.list.numitems]
push -'0'
push 10
pop ecx
@@:
xor edx, edx
div ecx
push edx
test eax, eax
jnz @b
@@:
pop eax
add al, '0'
jz @f
stosb
jmp @b
@@:
lodsb
stosb
test al, al
jnz @b
ret
filesearch_getname:
if lang eq ru
mov eax, '„¨ «'
stosd
mov eax, '®£ ¯'
stosd
mov eax, '®¨áª'
stosd
mov al, ' '
stosb
else
mov eax, 'Find'
stosd
mov eax, ' dia'
stosd
mov eax, 'log '
stosd
mov al, ' '
stosb
end if
ret
filesearch_stop_thread:
mov [ebp+filesearch_data.stop], 1
filesearch_wait_thread:
mov ecx, [ebp+filesearch_data.slot]
mov edx, [ebp+filesearch_data.tid]
jecxz .secondary_thread_exited
@@:
mov ebx, procinfo
push 9
pop eax
int 40h
cmp word [ebx+50], 9
jz .secondary_thread_exited
cmp dword [ebx+30], edx
jnz .secondary_thread_exited
push 5
pop eax
push 1
pop ebx
int 40h
jmp @b
.secondary_thread_exited:
and [ebp+filesearch_data.slot], 0
ret
filesearch_OnExit:
call filesearch_stop_thread
call filesearch_free_result
; call filesearch_set_dlgflags ; use it? I think, no
ret
filesearch_IsHandleUsed:
test ebp, ebp
ret
filesearch_set_dlgflags:
mov eax, dword [ebp+filesearch_data.query_dlgdata+filesearch_query_template.flags_case-filesearch_query_template]
and al, 10h
or al, 8
mov [find_in_file_dlgdata.flags_case], eax
mov eax, dword [ebp+filesearch_data.query_dlgdata+filesearch_query_template.flags_whole-filesearch_query_template]
and al, 10h
or al, 8
mov [find_in_file_dlgdata.flags_whole], eax
lea esi, [ebp+filesearch_data.string]
mov edi, SearchString
and dword [edi-4], 0
and dword [edi-8], 0
@@:
lodsb
stosb
test al, al
jnz @b
ret
filesearch_getcurdlg:
lea ebx, [ebp+filesearch_data.query_dlgdata]
cmp [ebp+filesearch_data.tid], -1
jz @f
add ebx, filesearch_data.search_dlgdata - filesearch_data.query_dlgdata
@@:
ret
filesearch_free_result:
mov ecx, [ebp+filesearch_data.result_blocks]
@@:
jecxz .ret
push dword [ecx]
call pgfree
pop ecx
jmp @b
.ret:
ret
filesearch_thread:
pop ebp
; initialize search for string
xor ecx, ecx
xor edx, edx
mov [ebp+filesearch_data.skip_errors_mask], cl
lea ebx, [ebp+filesearch_data.string]
cmp byte [ebx], dl
jz .noprepare
mov esi, tolower_table
test byte [ebp+filesearch_data.query_dlgdata+filesearch_query_template.flags_case-filesearch_query_template], 10h
jz @f
mov esi, identical_table
@@:
test byte [ebp+filesearch_data.query_dlgdata+filesearch_query_template.flags_whole-filesearch_query_template], 10h
setnz al
push eax
push ecx ; force cp866
call search_string_pre
.noprepare:
push -1
.enter_recursion:
xor esi, esi ; start position: zero
.read_folder_loop:
push esi
lea esi, [ebp+filesearch_data.curdir]
lea edi, [ebp+filesearch_data.curfile]
@@:
lodsb
stosb
test al, al
jnz @b
pop esi
.read_retry:
lea ebx, [ebp+filesearch_data.fs.func]
mov dword [ebx], 1
mov dword [ebx+4], esi
and dword [ebx+8], 0
mov dword [ebx+12], search_dir_query_size
lea eax, [ebp+filesearch_data.dir_area]
mov [ebx+16], eax
push 70
pop eax
int 40h
test eax, eax
jz .read_folder_ok
cmp eax, 6
jz .read_folder_ok
xor ebx, ebx
xchg ebx, dword [ebp+filesearch_data.dir_area+4]
test [ebp+filesearch_data.skip_errors_mask], filesearch_data.skip_read_folder
jnz .skip1
push edx
lea edx, [ebp+filesearch_data.curdir]
call recursive_read_folder_err
pop edx
jz .read_retry
cmp al, 2
jnz @f
dec eax
or [ebp+filesearch_data.skip_errors_mask], filesearch_data.skip_read_folder
@@:
cmp al, 1
jnz .cancel
.skip1:
.read_folder_ok:
imul ebx, 304
lea eax, [ebp+filesearch_data.dir_area+32]
add ebx, eax
.scan_folder_loop:
cmp eax, ebx
jae .scan_folder_done
; ignore special entries "." and ".."
cmp word [eax+40], '.'
jz .scan_folder_next
cmp word [eax+40], '..'
jnz @f
cmp byte [eax+42], 0
jz .scan_folder_next
@@:
call .check_stop
; construct name
push esi edi ebx eax
lea ebx, [ebp+filesearch_data.curfile+1023]
lea esi, [eax+40]
mov byte [edi-1], '/'
@@:
cmp edi, ebx
jae .namebig
lodsb
stosb
test al, al
jnz @b
pop eax
test byte [eax], 10h
jz .scan_file
; it is nested folder, enter recursion
; to maintain ASCIIZ string coherency, copy backward
lea esi, [edi+filesearch_data.curdir-filesearch_data.curfile]
@@:
dec edi
dec esi
mov al, [edi]
mov [esi], al
cmp al, '/'
jnz @b
mov [ebp+filesearch_data.datachanged], 1
pop ebx edi
jmp .enter_recursion
.namebig:
pop eax
mov byte [edi], 0
test [ebp+filesearch_data.skip_errors_mask], filesearch_data.skip_bigname
jnz .namebig.skip
push eax
push edi
test byte [eax], 10h
mov eax, aFileNameTooBig
jz @f
add eax, aFolderNameTooBig - aFileNameTooBig
@@:
push eax
mov eax, esp
push SkipOrCancelBtn
push 3
push eax
push 2
call SayErr
cmp al, 1
jnz @f
dec eax
or [ebp+filesearch_data.skip_errors_mask], filesearch_data.skip_bigname
@@:
test al, al
pop eax eax eax
jnz .cancel
.namebig.skip:
jmp .scan_folder_next_pop
.scan_file:
; it is a file
; first check: does file name match the mask?
push eax edx
; ®¡àî­¥â¨âì
lea esi, [eax+40]
lea edi, [ebp+filesearch_data.lowername]
push edi
xor eax, eax
@@:
lodsb
mov al, [tolower_table+eax]
stosb
test al, al
jnz @b
; ¯®¥å «¨
lea edx, [edi-1]
pop esi
lea edi, [ebp+filesearch_data.mask]
call match_mask_rev_lowercase
pop edx eax
jc .scan_folder_next_pop
; ok, second check: is the string present in this file?
jecxz .file_found
push eax
call filesearch_test_file
pop eax
jc .scan_folder_next_pop
.file_found:
push eax
; allocate memory for new result
lea esi, [ebp+filesearch_data.curfile]
mov ebx, esi
@@:
lodsb
test al, al
jnz @b
sub esi, ebx
mov eax, [ebp+filesearch_data.cur_result_ptr]
add esi, 8
push ecx
mov ecx, 0x4000
sub ecx, eax
cmp ecx, esi
jae .nonewblock
mov ecx, 0x4000
call xpgalloc
test eax, eax
jz .cancel
pushd [ebp+filesearch_data.result_blocks]
popd [eax]
mov [ebp+filesearch_data.result_blocks], eax
push 4
pop eax
mov [ebp+filesearch_data.cur_result_ptr], eax
.nonewblock:
add eax, [ebp+filesearch_data.result_blocks]
add [ebp+filesearch_data.cur_result_ptr], esi
pop ecx
; eax -> allocated memory, fill it
push eax
lea edi, [eax+8]
mov esi, ebx
@@:
lodsb
stosb
test al, al
jnz @b
pop eax
mov ebx, [ebp+filesearch_data.list.end]
mov [eax+4], ebx
and dword [eax], 0
mov [ebp+filesearch_data.list.end], eax
test ebx, ebx
jz @f
mov [ebx], eax
@@:
inc [ebp+filesearch_data.list.numitems]
cmp [ebp+filesearch_data.list.curitemptr], 0
jnz @f
mov [ebp+filesearch_data.list.curitemptr], eax
@@:
cmp [ebp+filesearch_data.list.head], 0
jnz @f
mov [ebp+filesearch_data.list.head], eax
@@:
mov [ebp+filesearch_data.datachanged], 1
pop eax
.scan_folder_next_pop:
pop ebx edi esi
mov byte [edi-1], 0
.scan_folder_next:
inc esi
add eax, 304
jmp .scan_folder_loop
.scan_folder_done:
cmp dword [ebp+filesearch_data.dir_area+4], search_dir_query_size
jz .read_folder_loop
pop esi
inc esi
jz .done
lea eax, [ebp+filesearch_data.curdir]
@@:
inc eax
cmp byte [eax], 0
jnz @b
@@:
dec eax
cmp byte [eax], '/'
jnz @b
mov byte [eax], 0
mov [ebp+filesearch_data.datachanged], 1
jmp .read_folder_loop
.cancel:
.done:
mov [ebp+filesearch_data.datachanged], 2
or eax, -1
int 40h
.check_stop:
cmp [ebp+filesearch_data.stop], 1
jz .cancel
ja @f
ret
@@:
push eax ebx
push 5
pop eax
push 1
pop ebx
int 40h
pop ebx eax
jmp .check_stop
filesearch_test_file:
lea ebx, [ebp+filesearch_data.fs.func]
lea eax, [ebp+filesearch_data.filebuf]
mov [ebx+16], eax
xor eax, eax
mov [ebx], eax
mov [ebx+4], eax
mov [ebx+8], eax
mov dword [ebx+12], search_filebuf_size
mov edi, edx
test byte [ebp+filesearch_data.query_dlgdata+filesearch_query_template.flags_whole-filesearch_query_template], 10h
jz .loop
add edi, 256
.loop:
.read_retry:
call filesearch_thread.check_stop
push 70
pop eax
lea ebx, [ebp+filesearch_data.fs.func]
int 40h
test eax, eax
jz .readok
cmp eax, 6
jz .readok
test [ebp+filesearch_data.skip_errors_mask], filesearch_data.skip_read_file
jnz .ret_failed
push edx
lea edx, [ebp+filesearch_data.curfile]
call recursive_read_file_err
pop edx
jz .read_retry
cmp al, 2
jnz @f
dec eax
or [ebp+filesearch_data.skip_errors_mask], filesearch_data.skip_read_file
@@:
cmp al, 1
jnz filesearch_thread.cancel
.ret_failed:
stc
ret
.readok:
test ebx, ebx
jz .eof
push ebx
lea esi, [ebp+filesearch_data.filebuf]
add ebx, esi
; edi = current state, edx -> FSM, ecx = last state,
; esi -> current data, ebx -> end of buffer
.scanloop: ; loop unrolled
; get current symbol
movzx eax, byte [esi]
; calculate next state
movzx edi, byte [edi+eax]
; done?
cmp edi, ecx
jz .ret_ok_pop
; no; proceed to next symbol
shl edi, 8
add edi, edx
cmp esi, ebx
jae .scandone
movzx eax, byte [esi+1]
add esi, 2
movzx edi, byte [edi+eax]
cmp edi, ecx
jz .ret_ok_pop
shl edi, 8
add edi, edx
cmp esi, ebx
jb .scanloop
.scandone:
pop ebx
.eof:
add [ebp+filesearch_data.fs.pos_low], ebx
adc [ebp+filesearch_data.fs.pos_high], 0
cmp ebx, search_filebuf_size
jz .loop
; EOF, last chance for whole-words-only search
test byte [ebp+filesearch_data.query_dlgdata+filesearch_query_template.flags_whole-filesearch_query_template], 10h
jz .ret_failed
movzx edi, byte [edi+' ']
cmp edi, ecx
jnz .ret_failed
clc
ret
.ret_ok_pop:
pop ebx
clc
ret
virtual at 0
_FILE:
.pos dq ?
.bufpos dq ?
.bufsize dd ?
.mode dd ?
.hPlugin dd ?
.hFile dd ?
.fileinfo:
.fimode dd ?
.fioffset dq ?
.fisize dd ?
.fibuf dd ?
.finame rb 1024
.attr rb 40
align 512
.buf rb 2048
.size = $
end virtual
O_READ = 1 ; allows read from file
O_WRITE = 2 ; allows write to file
O_CREATE = 4 ; if file does not exist and this flag is set, create file;
; if file does not exist and this flag is not set, fail
O_TRUNCATE = 8 ; truncate file if it exists
O_SEQUENTIAL_ONLY = 10h ; there will be no 'seek'/'setpos' calls
; HANDLE __stdcall open(const char* name, int mode);
; Opens physical file
open:
pushad
mov ecx, _FILE.size
call xpgalloc
test eax, eax
jz .ret0z
mov [esp+28], eax
mov ecx, eax
mov esi, [esp+36]
lea edi, [eax+_FILE.finame]
lea edx, [eax+_FILE.finame+1024]
@@:
lodsb
stosb
test al, al
jz @f
cmp edi, edx
jb @b
.ret0:
call pgfree
.ret0z:
popad
xor eax, eax
ret 8
@@:
mov eax, [esp+40]
mov [ecx+_FILE.mode], eax
.getattr:
lea edi, [ecx+_FILE.fileinfo]
mov ebx, edi
push 5
pop eax
stosd
xor eax, eax
stosd
stosd
stosd
lea eax, [ecx+_FILE.attr]
stosd
push 70
pop eax
int 0x40
test eax, eax
jz .found
cmp eax, 5
jnz .ret0
; file does not exist
test [ecx+_FILE.mode], O_CREATE
jz .ret0
.truncate:
lea ebx, [ecx+_FILE.fileinfo]
mov byte [ebx], 2
push 70
pop eax
int 0x40
test eax, eax
jz .getattr
jmp .ret0
.found:
test [ecx+_FILE.mode], O_TRUNCATE
jz @f
cmp dword [ecx+_FILE.attr+36], eax
jnz .truncate
cmp dword [ecx+_FILE.attr+32], eax
jnz .truncate
@@:
mov dword [ecx+_FILE.pos], eax
mov dword [ecx+_FILE.pos+4], eax
mov dword [ecx+_FILE.bufpos], eax
mov dword [ecx+_FILE.bufpos+4], eax
mov [ecx+_FILE.bufsize], eax
mov [ecx+_FILE.hPlugin], eax
mov [ecx+_FILE.hFile], eax
mov dword [ecx+_FILE.fioffset], eax
mov dword [ecx+_FILE.fioffset+4], eax
mov [esp+28], ecx
popad
ret 8
; HANDLE __stdcall open2(int plugin_id, HANDLE plugin_instance, const char* name, int mode);
; Opens file on plugin panel
open2:
cmp dword [esp+4], 0
jnz .plugin
pop eax
add esp, 8
push eax
jmp open
.plugin:
pushad
mov ecx, _FILE.size
call xpgalloc
test eax, eax
jz .ret0z
mov [esp+28], eax
mov ecx, eax
mov esi, [esp+44]
lea edi, [eax+_FILE.finame]
lea edx, [eax+_FILE.finame+1024]
@@:
lodsb
stosb
test al, al
jz @f
cmp edi, edx
jb @b
.ret0:
call pgfree
.ret0z:
popad
xor eax, eax
ret 8
@@:
mov edx, [esp+36]
mov [ecx+_FILE.hPlugin], edx
mov ebx, [esp+40]
mov eax, [esp+48]
mov [ecx+_FILE.mode], eax
push ebx ecx
push eax
lea eax, [ecx+_FILE.finame]
push eax
push ebx
call [edx+PluginInfo.open]
pop ecx ebx
test eax, eax
jz .ret0
mov [ecx+_FILE.hFile], eax
mov edx, [esp+36]
push ecx
lea edi, [ecx+_FILE.fileinfo]
push edi
xor eax, eax
push ecx
push 10
pop ecx
rep stosd
pop ecx
lea eax, [ecx+_FILE.finame]
push eax
push ebx
call [edx+PluginInfo.getattr]
pop ecx
xor eax, eax
mov dword [ecx+_FILE.pos], eax
mov dword [ecx+_FILE.pos+4], eax
mov dword [ecx+_FILE.bufpos], eax
mov dword [ecx+_FILE.bufpos+4], eax
mov [ecx+_FILE.bufsize], eax
mov dword [ecx+_FILE.fioffset], eax
mov dword [ecx+_FILE.fioffset+4], eax
mov [esp+28], ecx
popad
ret 16
; unsigned __stdcall read(HANDLE hFile, void* buf, unsigned size);
read:
xor eax, eax
pushad
mov ecx, [esp+36]
test [ecx+_FILE.mode], O_READ
jnz @f
.ret:
popad
ret 12
@@:
cmp dword [esp+44], eax
jz .ret
mov [ecx+_FILE.fimode], eax
mov ebx, [ecx+_FILE.bufsize]
mov eax, dword [ecx+_FILE.pos]
and eax, 2047
sub ebx, eax
jbe .nobuf0
cmp ebx, [esp+44]
jbe @f
mov ebx, [esp+44]
@@:
push ecx
lea esi, [ecx+eax+_FILE.buf]
mov ecx, ebx
mov edi, [esp+44]
rep movsb
pop ecx
mov [esp+40], edi
add [esp+28], ebx
add dword [ecx+_FILE.pos], ebx
adc dword [ecx+_FILE.pos+4], 0
test dword [ecx+_FILE.pos], 2047
jnz @f
and [ecx+_FILE.bufsize], 0
@@:
sub [esp+44], ebx
jz .ret
.nobuf0:
test dword [ecx+_FILE.pos], 2047
jz .aligned
cmp dword [ecx+_FILE.bufsize], 0
jnz .ret
lea ebx, [ecx+_FILE.fileinfo]
mov dword [ebx+12], 2048
lea eax, [ecx+_FILE.buf]
mov dword [ebx+16], eax
mov eax, dword [ecx+_FILE.fioffset]
mov dword [ecx+_FILE.bufpos], eax
mov eax, dword [ecx+_FILE.fioffset+4]
mov dword [ecx+_FILE.bufpos+4], eax
call .doread
test eax, eax
jnz .ret
mov [ecx+_FILE.bufsize], ebx
mov eax, dword [ecx+_FILE.pos]
and eax, 2047
sub ebx, eax
jbe .ret
cmp ebx, [esp+44]
jbe @f
mov ebx, [esp+44]
@@:
push ecx
lea esi, [ecx+eax+_FILE.buf]
mov ecx, ebx
mov edi, [esp+44]
rep movsb
pop ecx
add dword [ecx+_FILE.pos], ebx
adc dword [ecx+_FILE.pos+4], 0
mov [esp+40], edi
add [esp+28], ebx
sub [esp+44], ebx
jz .ret
test dword [ecx+_FILE.pos], 2047
jnz .ret
.aligned:
lea ebx, [ecx+_FILE.fileinfo]
mov eax, [esp+44]
and eax, not 2047
jz .finish
and [ecx+_FILE.bufsize], 0
mov [ebx+12], eax
mov eax, [esp+40]
mov [ebx+16], eax
call .doread
test eax, eax
jnz .ret
add dword [ecx+_FILE.pos], ebx
adc dword [ecx+_FILE.pos+4], 0
add [esp+28], ebx
add [esp+40], ebx
sub [esp+44], ebx
jz .ret
cmp ebx, [ecx+_FILE.fisize]
jb .ret
.finish:
lea ebx, [ecx+_FILE.fileinfo]
mov dword [ebx+12], 2048
lea eax, [ecx+_FILE.buf]
mov [ebx+16], eax
and [ecx+_FILE.bufsize], 0
mov eax, dword [ecx+_FILE.fioffset]
mov dword [ecx+_FILE.bufpos], eax
mov eax, dword [ecx+_FILE.fioffset+4]
mov dword [ecx+_FILE.bufpos+4], eax
call .doread
test eax, eax
jnz .ret
mov [ecx+_FILE.bufsize], ebx
cmp ebx, [esp+44]
jb @f
mov ebx, [esp+44]
@@:
add [esp+28], ebx
add dword [ecx+_FILE.pos], ebx
adc dword [ecx+_FILE.pos+4], 0
lea esi, [ecx+_FILE.buf]
mov edi, [esp+40]
mov ecx, ebx
rep movsb
popad
ret 12
.doread:
mov eax, [ecx+_FILE.hPlugin]
test eax, eax
jz .native
push ecx
push [ecx+_FILE.fisize]
push [ecx+_FILE.fibuf]
push [ecx+_FILE.hFile]
call [eax+PluginInfo.read]
pop ecx
cmp eax, -1
jz @f
mov ebx, eax
xor eax, eax
jmp .addpos
@@:
ret
.native:
push 70
pop eax
int 0x40
test eax, eax
jz .addpos
cmp eax, 6
jnz @b
xor eax, eax
.addpos:
add dword [ecx+_FILE.fioffset], ebx
adc dword [ecx+_FILE.fioffset+4], 0
ret
; void __stdcall seek(HANDLE hFile, int method, __int64 newpos);
seek:
pushad
mov ecx, [esp+36]
mov eax, [esp+44]
mov edx, [esp+48]
cmp dword [esp+40], 1
jb .set
ja .end
add eax, dword [ecx+_FILE.pos]
adc edx, dword [ecx+_FILE.pos+4]
jmp .set
.end:
add eax, dword [ecx+_FILE.attr+32]
adc edx, dword [ecx+_FILE.attr+36]
.set:
mov dword [ecx+_FILE.pos], eax
mov dword [ecx+_FILE.pos+4], edx
and eax, not 2047
cmp eax, dword [ecx+_FILE.bufpos]
jnz @f
cmp edx, dword [ecx+_FILE.bufpos+4]
jz .bufposok
@@:
and [ecx+_FILE.bufsize], 0
mov dword [ecx+_FILE.bufpos], eax
mov dword [ecx+_FILE.bufpos+4], edx
.bufposok:
cmp [ecx+_FILE.bufsize], 0
jnz .ret
cmp eax, dword [ecx+_FILE.fioffset]
jnz @f
cmp edx, dword [ecx+_FILE.fioffset+4]
jz .ret
@@:
mov dword [ecx+_FILE.fioffset], eax
mov dword [ecx+_FILE.fioffset+4], edx
mov eax, [ecx+_FILE.hPlugin]
test eax, eax
jz @f
push dword [ecx+_FILE.fioffset+4]
push dword [ecx+_FILE.fioffset]
push [ecx+_FILE.hFile]
call [eax+PluginInfo.setpos]
@@:
.ret:
popad
ret 16
setpos_default:
push dword [esp+12]
push dword [esp+12]
push 0
push dword [esp+16]
call seek
ret 12
; __int64 __stdcall tell(HANDLE hFile);
tell:
mov eax, [esp+4]
mov edx, dword [eax+_FILE.pos+4]
mov eax, dword [eax+_FILE.pos]
ret 4
; __int64 __stdcall filesize(HANDLE hFile);
filesize:
mov eax, [esp+4]
mov edx, dword [eax+_FILE.attr+36]
mov eax, dword [eax+_FILE.attr+32]
ret 4
; void __stdcall close(HANDLE hFile);
close:
pushad
mov ecx, [esp+24h]
mov eax, [ecx+_FILE.hPlugin]
test eax, eax
jz @f
push ecx
push [ecx+_FILE.hFile]
call [eax+PluginInfo.close]
pop ecx
@@:
call pgfree
popad
ret 4
getattr_default:
mov eax, 2
ret 12