0,0 → 1,226 |
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 |
push -1 |
push -1 |
push aError |
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 |
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 |
jae .delete_dir_entry_done |
; 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: |
std |
@@: |
lodsb |
cmp al, '/' |
jnz @b |
cld |
mov byte [esi+1], 0 |
.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 |
@@: |
lodsb |
test al, al |
jnz @b |
dec esi |
dec esi |
std |
@@: |
lodsb |
cmp al, '/' |
jnz @b |
cld |
mov byte [esi+1], 0 |
jmp .return_from_recursion |
.done: |
.cancel: |
mov [dirinfo.first], 0 ; do not destroys flags |
popad |
ret |