kolibrios/programs/fs/kfar/trunk/kfar_arc/zip.inc
Evgeny Grechnikov (Diamond) c2d16441b9 sorry, I forgot to 'svn add' some files for 631
git-svn-id: svn://kolibrios.org@632 a494cfbc-eb01-0410-851d-a64ba20cac60
2007-09-20 16:22:12 +00:00

1313 lines
39 KiB
PHP

; Loader of ZIP archives for KFar_Arc.
; Written by diamond in 2007.
virtual at 0
file_in_zip:
.fullname dd ? ; pointer to cp866 string
.name dd ?
.namelen dd ?
.bIsDirectory db ?
.bPseudoFolder db ?
rb 2
.parent dd ? ; pointer to parent directory record
.subfolders dd ? ; head of L2-list of subfolders [for folders]
.subfolders.end dd ?
.subfiles dd ? ; head of L2-list of files [for folders]
.subfiles.end dd ?
.NumSubItems dd ?
.next dd ? ; next item of list of subfolders or files
.prev dd ? ; previous item of list of subfolders or files
.stamp dd ?
.version_made_by dw ?
.version_needed dw ?
.flags dw ?
.method dw ?
.time dw ?
.date dw ?
.crc dd ?
.compressed_size dq ?
.uncompressed_size dq ?
.local_hdr dq ?
.disk dd ?
.attr dd ?
.size = $
end virtual
virtual at 0
handle_zip:
.type dd ?
.root.subfolders dd ?
.root.subfolders.end dd ?
.root.subfiles dd ?
.root.subfiles.end dd ?
.root.NumSubItems dd ?
.curdir dd ?
.NumFiles dd ?
.names_buf dd ?
.host dd ?
.host_datetime rd 6
.num_disks dd ?
.cur_disk dd ?
.cur_handle dd ?
.host_hPlugin dd ?
.host_idPlugin dd ?
.password_len dd ? ; -1 if no password defined; in characters
.password rb password_maxlen
.basesize = $
end virtual
uglobal
align 4
zip.num_disks dd ?
zip.cur_disk dd ?
zip.cur_handle dd ?
zip.NumAllocated dd ?
zip.NamesSize dd ?
zip.disk_name rb 1024
zip64eocd: ; zip64 end of central directory record
.sig dd ? ; signature
.size dq ? ; size of this record
.version_made_by dw ? ; version made by
.version_needed dw ? ; version needed to extract
.disk dd ? ; number of this disk
.cdir_disk dd ? ; number of the disk with the start
; of the central directory
.cdir_entries_disk dq ? ; total number of entries in the central
; directory on this disk
.cdir_entries dq ? ; total number of entries in the central directory
.cdir_size dq ? ; size of the central directory
.cdir_start dq ? ; offset of start of central directory
.sz = $ - zip64eocd
zip.file_header:
.sig dd ?
.version_made_by dw ? ; (absent in local file header)
.version_needed dw ?
.flags dw ? ; general purpose bit flag
.method dw ? ; compression method
.time dw ? ; last modified file time
.date dw ? ; last modified file date
.crc dd ?
.compressed_size dd ?
.uncompressed_size dd ?
.fname_len dw ? ; file name length
.extra_len dw ? ; extra field length
.sz_local = $ - (zip.file_header+2) ; size of local file header
.fcmt_len dw ? ; file comment length
.disk dw ? ; disk number start
.internal_attr dw ?
.external_attr dd ?
.local_hdr dd ? ; relative offset of local header
.sz_cdir = $ - zip.file_header ; size of file header in central directory
zip.extra:
.id dw ?
.size dw ?
zip.extra.zip64:
.uncompressed_size dq ?
.compressed_size dq ?
.local_hdr dq ?
.disk dd ?
.sz = $ - zip.extra.zip64
endg
open_zip:
and [zip.cur_handle], 0
; look for end of central directory record
push ebp
call [filesize]
sub eax, 1024
sbb edx, 0
jnb @f
xor eax, eax
xor edx, edx
@@:
push edx
push eax
push 0
push ebp
call [seek]
push 1024
push buffer
push ebp
call [read]
cmp eax, 22
jge @f
xor eax, eax
.ret:
ret
@@:
mov [inStream], ebp
lea edi, [buffer+eax-22]
@@:
cmp dword [edi], 0x06054B50
jz .eocd_found
dec edi
cmp edi, buffer
jae @b
xor eax, eax
ret
.eocd_found:
cmp edi, buffer+20
jb .no_eocd64
cmp dword [edi-20], 0x07064B50
jnz .no_eocd64
mov ebx, ebp
mov ecx, [edi-16]
mov edx, [edi-4]
mov [zip.num_disks], edx
dec edx
mov [zip.cur_disk], edx
cmp edx, ecx
jz @f
push 1
push dword [esp+8+28]
push dword [esp+12+24]
push dword [esp+16+20]
call zip.open_splitted
test eax, eax
jz .ret
mov ebx, eax
@@:
push dword [edi-8]
push dword [edi-12]
push 0
push ebx
call [seek]
push zip64eocd.sz
push zip64eocd
push ebx
call [read]
cmp eax, zip64eocd.sz
jnz .close_err
cmp [zip64eocd.sig], 0x06064B50
jnz .close_err
mov ecx, [zip64eocd.cdir_disk]
cmp ecx, [zip.cur_disk]
jz @f
push 1
push dword [esp+8+28]
push dword [esp+12+24]
push dword [esp+16+20]
call zip.open_splitted
test eax, eax
jz .ret
mov ebx, eax
@@:
push dword [zip64eocd.cdir_start+4]
push dword [zip64eocd.cdir_start]
push 0
push ebx
call [seek]
mov ecx, dword [zip64eocd.cdir_entries]
jmp .parse_cdir
.close_err:
call close_cur_handle
or eax, -1
ret
.no_eocd64:
mov ebx, ebp
movzx ecx, word [edi+6]
movzx edx, word [edi+4]
inc edx
mov [zip.num_disks], edx
dec edx
mov [zip.cur_disk], edx
cmp edx, ecx
jz @f
push 1
push dword [esp+8+28]
push dword [esp+12+24]
push dword [esp+16+20]
call zip.open_splitted
test eax, eax
jz .ret
mov ebx, eax
@@:
push 0
push dword [edi+16]
push 0
push ebx
call [seek]
movzx ecx, word [edi+10]
.parse_cdir:
mov [zip.NumAllocated], ecx
imul ecx, file_in_zip.size
jc .close_err
add ecx, handle_zip.basesize
jc .close_err
mov [hOut.allocated], ecx
call [pgalloc]
test eax, eax
jz .close_err
mov [hOut], eax
push eax
mov edi, eax
shr ecx, 2
xor eax, eax
rep stosd
mov edi, [esp+8+28]
dec ecx
repnz scasb
not ecx
mov [zip.NamesSize], ecx
call [pgalloc]
mov ebp, eax
pop edi
test eax, eax
jz .free_err
push edi
mov edi, ebp
mov esi, [esp+8+28]
rep movsb
pop edi
mov byte [edi+handle_zip.type], type_zip
add edi, handle_zip.basesize + file_in_zip.version_made_by
.cdir_loop:
mov esi, zip.file_header
push zip.file_header.sz_cdir
push esi
push ebx
call [read]
cmp eax, zip.file_header.sz_cdir
jz .cdir_item_ok
mov ecx, [zip.cur_disk]
inc ecx
cmp ecx, [zip.num_disks]
jz .cdir_done
push 1
push dword [esp+8+28]
push dword [esp+12+24]
push dword [esp+16+20]
call zip.open_splitted
test eax, eax
jz .free_err
mov ebx, eax
jmp .cdir_loop
.cdir_item_ok:
lodsd
cmp eax, 0x02014B50
jnz .cdir_done
mov eax, [hOut]
inc [eax+handle_zip.NumFiles]
mov eax, [eax+handle_zip.NumFiles]
cmp eax, [zip.NumAllocated]
jbe .norealloc
inc [zip.NumAllocated]
mov ecx, [hOut.allocated]
add ecx, file_in_zip.size
push ecx
and ecx, 0xFFF
cmp ecx, file_in_zip.size
pop ecx
mov [hOut.allocated], ecx
ja .norealloc
mov edx, [hOut]
call [pgrealloc]
test eax, eax
jnz @f
.free_err:
mov ecx, [hOut]
call [pgfree]
mov ecx, ebp
call [pgfree]
jmp .close_err
@@:
mov [hOut], eax
sub edi, edx
add edi, eax
.norealloc:
push 5
pop ecx
rep movsd
xor eax, eax
stosd
movsd
stosd
lodsw
mov ecx, [zip.NamesSize]
lea edx, [ecx+0xFFF]
and edx, not 0xFFF
lea ecx, [ecx+eax+1]
mov [zip.NamesSize], ecx
push ecx
add ecx, 0xFFF
and ecx, not 0xFFF
cmp ecx, edx
pop ecx
jz .noreallocname
mov edx, ebp
call [pgrealloc]
test eax, eax
jz .free_err
mov ebp, eax
.noreallocname:
movzx eax, word [esi-2]
inc eax
mov edx, [zip.NamesSize]
sub edx, eax
mov dword [edi-(file_in_zip.uncompressed_size+8)+file_in_zip.fullname], edx
add edx, ebp
dec eax
mov byte [edx+eax], 0
push eax
push edx
push ebx
call [read]
movzx eax, word [esi-2]
cmp byte [edx+eax-1], '/'
jnz @f
mov byte [edx+eax-1], 0
mov byte [edi-(file_in_zip.uncompressed_size+8)+file_in_zip.bIsDirectory], 1
@@:
mov eax, [esi+12]
mov [edi], eax
movzx eax, word [esi+4]
mov [edi+8], eax
lodsw
push esi
movzx ecx, ax
mov edx, ecx
.parse_extra:
sub ecx, 4
jb .extra_done
mov esi, zip.extra
push 4
push esi
push ebx
call [read]
cmp eax, 4
jnz .extra_done
sub edx, eax
cmp word [esi], 1
jnz .extra_skip
mov esi, zip.extra.zip64
push esi edi
sub edi, 8
xchg esi, edi
movsd
movsd
sub esi, 16
movsd
movsd
add esi, 8
movsd
movsd
movsd
pop edi esi
movzx eax, [zip.extra.size]
cmp eax, zip.extra.zip64.sz
jb @f
mov al, zip.extra.zip64.sz
@@:
sub ecx, eax
jb .extra_done
push eax
push esi
push ebx
call [read]
sub edx, eax
sub [zip.extra.size], ax
sub edi, 8
movsd
movsd
sub edi, 16
movsd
movsd
add edi, 8
movsd
movsd
movsd
sub edi, 12
.extra_skip:
movzx eax, word [zip.extra.size]
sub ecx, eax
jb .extra_done
sub edx, eax
push 0
push eax
push 1
push ebx
call [seek]
jmp .parse_extra
.extra_done:
pop esi
xor eax, eax
lodsw
add edx, eax
jz @f
push 0
push edx
push 1
push ebx
call [seek]
@@:
mov eax, [esi+4]
mov dword [edi+file_in_zip.attr-(file_in_zip.uncompressed_size+8)], eax
; test al, 10h
; setnz byte [edi+file_in_zip.bIsDirectory-(file_in_zip.uncompressed_size+8)]
add edi, file_in_zip.size-file_in_zip.uncompressed_size-8+file_in_zip.version_made_by
jmp .cdir_loop
.cdir_done:
mov edi, [hOut]
mov esi, zip.num_disks
push edi
add edi, handle_zip.num_disks
movsd
movsd
movsd
pop edi
mov [edi+handle_zip.names_buf], ebp
mov ecx, [edi+handle_zip.NumFiles]
jecxz .nofiles
add edi, handle_zip.basesize + file_in_zip.fullname
@@:
add [edi], ebp
add edi, file_in_zip.size
loop @b
.nofiles:
mov edx, [hOut]
mov ebx, [edx+handle_zip.NumFiles]
lea edi, [edx+handle_zip.root.subfolders]
add edx, handle_zip.basesize
push file_in_zip.size
call init_file_links
mov eax, [hOut]
and [eax+handle_zip.curdir], 0 ; set root directory
mov esi, [inStream]
mov [eax+handle_zip.host], esi
or [eax+handle_zip.password_len], -1
mov esi, [esp+4+20]
mov [eax+handle_zip.host_idPlugin], esi
mov esi, [esp+4+24]
mov [eax+handle_zip.host_hPlugin], esi
lea edi, [eax+handle_zip.host_datetime]
mov esi, [esp+12]
add esi, 8
mov ecx, 6
rep movsd
ret
close_cur_handle:
mov edx, zip.cur_handle
or dword [edx-4], -1
cmp dword [edx], 0
jz @f
push dword [edx]
call [close]
and dword [edx], 0
@@:
ret
zip.open_splitted:
call close_cur_handle
mov [zip.cur_disk], ecx
inc ecx
mov edx, ecx
cmp ecx, [zip.num_disks]
jnz @f
mov ecx, [inStream]
push 0
push 0
push 0
push ecx
call [seek]
mov eax, ecx
ret 16
@@:
push esi edi
mov esi, [esp+8+12]
mov edi, zip.disk_name
mov [esp+8+12], edi
mov ecx, 1024
@@:
lodsb
stosb
test al, al
loopnz @b
jnz .ret0
cmp ecx, 4
jb .ret0
dec edi
mov al, '.'
stosb
cmp edx, 100
jae .big
mov al, 'z'
stosb
mov eax, edx
aam
add ax, '00'
xchg al, ah
stosw
mov byte [edi], 0
.nameok:
pop edi esi
push dword [esp+16]
push dword [esp+16]
push dword [esp+16]
push dword [esp+16]
call [open2]
mov [zip.cur_handle], eax
ret 16
.ret0:
mov byte [edi-1], 0
pop edi esi
xor eax, eax
ret 16
.big:
cmp ecx, 12
jb .ret0
push 10
pop ecx
push -'0'
mov eax, edx
@@:
xor edx, edx
div ecx
push edx
test eax, eax
jnz @b
@@:
pop eax
add al, '0'
jz .nameok
stosb
jmp @b
close_zip:
mov esi, [esp+4]
push [esi+handle_zip.host]
call [close]
mov ecx, [esi+handle_zip.names_buf]
call [pgfree]
mov ecx, [esi+handle_zip.cur_handle]
jecxz @f
push ecx
call [close]
@@:
mov ecx, esi
call [pgfree]
ret 4
; ebp=hPlugin, eax->item, edi->info
getattr_zip:
cmp [eax+file_in_zip.bPseudoFolder], 0
jnz .pseudo
mov esi, eax
mov eax, [eax+file_in_zip.attr]
stosd
xor eax, eax
stosd
stosd
stosd
stosd
stosd
movzx eax, word [esi+file_in_zip.time]
mov ecx, eax
and al, 0x1F
shr ecx, 5
add eax, eax
stosb
mov eax, ecx
and al, 0x3F
shr ecx, 6
stosb
mov eax, ecx
stosw
movzx eax, word [esi+file_in_zip.date]
mov ecx, eax
and al, 0x1F
shr ecx, 5
stosb
mov eax, ecx
and al, 0xF
shr ecx, 4
stosb
lea eax, [ecx+1980]
stosw
mov eax, dword [esi+file_in_zip.uncompressed_size]
stosd
mov eax, dword [esi+file_in_zip.uncompressed_size+4]
stosd
ret
.pseudo:
push 0x10 ; attributes: folder
pop eax
stosd
xor eax, eax
stosd
lea esi, [ebp+handle_zip.host_datetime]
push 6
pop ecx
rep movsd
stosd
stosd
ret
virtual at 0
file_handle_zip:
.type dd ?
.item dd ?
.base dd ?
.start_disk dd ?
.start dq ?
.pos dq ?
.posc dq ?
.decoder dd ?
.cur_disk dd ?
.cur_disk_start dq ?
.bError db ?
.bPassProtected db ?
.bPassInited db ?
rb 1
.keys rd 3
.saved_keys rd 3
.size = $
end virtual
iglobal
handle_table_zip dd handle_table_zip, handle_table_zip
endg
; ebp=hPlugin, eax->item, edi=mode
open_file_zip:
mov [_esp], esp
mov [_ebp], ebp
mov [error_proc], .error
mov [clear_proc], .clear
mov ecx, [ebp+handle_zip.password_len]
inc ecx
setnz [bPasswordDefined]
jz @f
dec ecx
mov [password_size], ecx
lea esi, [ebp+handle_zip.password]
mov edi, password_ansi
rep movsb
@@:
xor edi, edi
mov [hOut], edi
mov [hOut.allocated], edi
mov ebx, eax
movzx eax, [ebx+file_in_zip.method]
test eax, eax
jz .common
.notcopy:
cmp eax, 8
jz .deflate
cmp eax, 9
jz .deflate
push -'0'
push 10
pop ecx
@@:
xor edx, edx
div ecx
push edx
test eax, eax
jnz @b
mov edi, aUnknownMethod.z
mov al, ' '
stosb
@@:
pop eax
add al, '0'
stosb
jnz @b
push ContinueBtn
push 1
push aUnknownMethod_ptr
push 1
call [SayErr]
xor eax, eax
.ret1:
ret
.deflate:
mov ecx, 0x12000
call [pgalloc]
test eax, eax
jz .ret1
mov [hOut], eax
mov ecx, dword [ebx+file_in_zip.compressed_size]
mov dword [eax+streamInfo.fullSize], ecx
mov ecx, dword [ebx+file_in_zip.compressed_size+4]
mov dword [eax+streamInfo.fullSize+4], ecx
mov [eax+streamInfo.fillBuf], zipin.fillBuf
mov [eax+streamInfo.bufSize], 0x2000 - (streamInfo.size+4) - deflate_decoder.size
and [eax+streamInfo.bufDataLen], 0
lea edx, [eax+streamInfo.size+4]
mov [eax+streamInfo.bufPtr], edx
add edx, [eax+streamInfo.bufSize]
mov ecx, dword [ebx+file_in_zip.uncompressed_size]
mov dword [edx+streamInfo.fullSize], ecx
mov ecx, dword [ebx+file_in_zip.uncompressed_size+4]
mov dword [edx+streamInfo.fullSize+4], ecx
mov [edx+streamInfo.bufSize], 0x10000
and [edx+streamInfo.bufDataLen], 0
mov [edx+streamInfo.size], eax
lea eax, [edx+deflate_decoder.size]
mov [edx+streamInfo.bufPtr], eax
push ebp
mov ebp, edx
call deflate_init_decoder
mov edi, ebp
pop ebp
cmp [ebx+file_in_zip.method], 9
setz [edi+deflate_decoder.bDeflate64]
.common:
mov esi, handle_table_zip
push file_handle_zip.size
pop ecx
call alloc_handle
test eax, eax
jz return.clear
mov edx, [hOut]
mov [edx+streamInfo.size], eax
mov [eax+file_handle_zip.type], type_zip
xor edx, edx
mov dword [eax+file_handle_zip.pos], edx
mov dword [eax+file_handle_zip.pos+4], edx
mov dword [eax+file_handle_zip.posc], edx
mov dword [eax+file_handle_zip.posc+4], edx
mov [eax+file_handle_zip.item], ebx
mov [eax+file_handle_zip.base], ebp
mov [eax+file_handle_zip.decoder], edi
mov [eax+file_handle_zip.bError], dl
mov [eax+file_handle_zip.bPassInited], dl
test [ebx+file_in_zip.flags], 1
setnz [eax+file_handle_zip.bPassProtected]
mov ecx, [ebx+file_in_zip.disk]
mov [eax+file_handle_zip.start_disk], ecx
mov [eax+file_handle_zip.cur_disk], ecx
mov ecx, dword [ebx+file_in_zip.local_hdr]
mov dword [eax+file_handle_zip.start], ecx
mov ecx, dword [ebx+file_in_zip.local_hdr+4]
mov dword [eax+file_handle_zip.start+4], ecx
mov dword [eax+file_handle_zip.cur_disk_start], edx
mov dword [eax+file_handle_zip.cur_disk_start+4], edx
mov [hOut.allocated], eax
mov [hOut], edx
push ebx
mov ebx, eax
push zip.file_header.sz_local
pop ecx
mov edi, zip.file_header+2
call zip.read
cmp dword [edi-zip.file_header.sz_local], 0x04034B50
jnz return.err
movzx ecx, word [edi-4]
movzx eax, word [edi-2]
lea esi, [ecx+eax+zip.file_header.sz_local]
xor edi, edi
call zip.setpos
call zip.update_start
cmp [ebx+file_handle_zip.bPassProtected], 0
jz .nopass
.redo_pass:
call query_password
jz return.clear
call zip.init_keys
push 12
pop ecx
mov edi, buffer
call zip.read
mov eax, [ebx+file_handle_zip.item]
mov al, byte [eax+file_in_zip.crc+3]
cmp [edi-1], al
jz .passok
push CancelPassBtn
push 2
push aArchiveDataErrorPass_ptr
push 1
call [SayErr]
cmp al, 1
jnz return.clear
xor eax, eax
mov dword [ebx+file_handle_zip.posc], eax
mov dword [ebx+file_handle_zip.posc+4], eax
mov dword [ebx+file_handle_zip.cur_disk_start], eax
mov dword [ebx+file_handle_zip.cur_disk_start+4], eax
mov eax, [ebx+file_handle_zip.start_disk]
mov [ebx+file_handle_zip.cur_disk], eax
mov [bPasswordDefined], 0
jmp .redo_pass
.passok:
mov ecx, [password_size]
mov [ebp+handle_zip.password_len], ecx
mov esi, password_ansi
lea edi, [ebp+handle_zip.password]
rep movsb
lea esi, [ebx+file_handle_zip.keys]
lea edi, [ebx+file_handle_zip.saved_keys]
movsd
movsd
movsd
mov esi, 12
xor edi, edi
call zip.update_start
.nopass:
pop ebx
mov eax, [hOut.allocated]
cmp dword [ebx+file_in_zip.uncompressed_size+4], 0
jnz .ret
mov ecx, dword [ebx+file_in_zip.uncompressed_size]
if defined LIMIT_FOR_MEM_STREAM
cmp ecx, LIMIT_FOR_MEM_STREAM
ja .ret
end if
push eax ecx
add ecx, 0x3FF
shr ecx, 10 ; get size in Kb
call [getfreemem]
shr eax, 2
cmp ecx, eax
pop ecx eax
ja .ret
; create memory stream and unpack to memory
mov ebx, eax
add ecx, mem_stream.buf
call [pgalloc]
sub ecx, mem_stream.buf
test eax, eax
jz return.clear
mov edi, eax
mov [hOut], eax
xor eax, eax ; type_mem_stream
stosd ; mem_stream.type
mov eax, ecx
stosd ; mem_stream.size
xor eax, eax
stosd ; mem_stream.pos
push ecx edi
push ecx
push edi
push ebx
call read_zip
pop esi ecx
mov [_esp], esp
mov [_ebp], ebp
mov [error_proc], .error
mov [clear_proc], .clear
cmp eax, -1
jz .clear
; cmp eax, ecx
; jnz .error
; call crc
; mov edx, [ebx+file_handle_zip.item]
; cmp eax, [edx+file_in_zip.crc]
; jnz .error
call .1
mov eax, [hOut]
.ret:
ret
.error:
push ContinueBtn
push 1
push aArchiveDataError_ptr
push 1
call [SayErr]
.clear:
mov ecx, [hOut]
call [pgfree]
.1:
mov ebx, [hOut.allocated]
test ebx, ebx
jz @f
push ebx
call close_file_zip
@@:
xor eax, eax
ret
close_file_zip:
mov ecx, [ebx+file_handle_zip.decoder]
jecxz @f
mov ecx, [ecx+streamInfo.size]
call [pgfree]
@@:
mov esi, ebx
call free_handle
ret 4
zip.init_keys:
mov [ebx+file_handle_zip.keys+0], 305419896
mov [ebx+file_handle_zip.keys+4], 591751049
mov [ebx+file_handle_zip.keys+8], 878082192
mov ecx, [password_size]
jecxz .empty
mov esi, password_ansi
xor eax, eax
@@:
lodsb
call zip.update_keys
loop @b
.empty:
mov [ebx+file_handle_zip.bPassInited], 1
ret
zip.update_keys:
mov dl, byte [ebx+file_handle_zip.keys]
xor dl, al
movzx edx, dl
mov eax, [ebx+file_handle_zip.keys]
shr eax, 8
xor eax, [crc_table+edx*4]
mov [ebx+file_handle_zip.keys], eax
movzx eax, al
add eax, [ebx+file_handle_zip.keys+4]
imul eax, 134775813
inc eax
mov [ebx+file_handle_zip.keys+4], eax
shr eax, 24
mov edx, [ebx+file_handle_zip.keys+8]
xor al, dl
shr edx, 8
xor edx, [crc_table+eax*4]
mov [ebx+file_handle_zip.keys+8], edx
ret
zip.decrypt_byte:
; out: ah = result
mov eax, [ebx+file_handle_zip.keys+8]
or eax, 2
mov edx, eax
xor edx, 1
mul edx
ret
zip.get_cur_handle:
mov edx, [ebp+handle_zip.host]
mov eax, [ebp+handle_zip.num_disks]
dec eax
cmp eax, [ebx+file_handle_zip.cur_disk]
jz .handleok
inc eax
mov [zip.num_disks], eax
mov edx, [ebp+handle_zip.cur_handle]
mov eax, [ebp+handle_zip.cur_disk]
cmp eax, [ebx+file_handle_zip.cur_disk]
jz .handleok
mov [zip.cur_handle], edx
push ecx
mov ecx, [ebx+file_handle_zip.cur_disk]
push 1
push [ebp+handle_zip.names_buf]
push [ebp+handle_zip.host_hPlugin]
push [ebp+handle_zip.host_idPlugin]
call zip.open_splitted
pop ecx
mov edx, eax
test eax, eax
jnz @f
push zip.disk_name
push aCannotOpenFile
mov eax, esp
push ContinueBtn
push 1
push eax
push 2
call [SayErr]
jmp return.clear
@@:
mov [ebp+handle_zip.cur_handle], eax
mov eax, [ebx+file_handle_zip.cur_disk]
mov [ebp+handle_zip.cur_disk], eax
.handleok:
ret
zip.read:
; in: ebx=hFile, edi->buf, ecx=size
push ebp edi
mov ebp, [ebx+file_handle_zip.base]
.s:
call zip.get_cur_handle
mov eax, dword [ebx+file_handle_zip.posc]
mov esi, dword [ebx+file_handle_zip.posc+4]
sub eax, dword [ebx+file_handle_zip.cur_disk_start]
sbb esi, dword [ebx+file_handle_zip.cur_disk_start+4]
push eax
mov eax, dword [ebx+file_handle_zip.cur_disk]
cmp eax, dword [ebx+file_handle_zip.start_disk]
pop eax
jnz @f
add eax, dword [ebx+file_handle_zip.start]
adc esi, dword [ebx+file_handle_zip.start+4]
@@:
push esi
push eax
push 0
push edx
call [seek]
push ecx
push edi
push edx
call [read]
cmp eax, -1
jz .error
add edi, eax
add dword [ebx+file_handle_zip.posc], eax
adc dword [ebx+file_handle_zip.posc+4], 0
sub ecx, eax
jz .ok
inc dword [ebx+file_handle_zip.cur_disk]
mov eax, dword [ebx+file_handle_zip.posc]
mov dword [ebx+file_handle_zip.cur_disk_start], eax
mov eax, dword [ebx+file_handle_zip.posc+4]
mov dword [ebx+file_handle_zip.cur_disk_start+4], eax
jmp .s
.ok:
cmp [ebx+file_handle_zip.bPassInited], 0
jnz .decrypt
pop eax ebp
ret
.decrypt:
mov ecx, edi
pop edi
sub ecx, edi
jz .nodata
@@:
call zip.decrypt_byte
xor [edi], ah
mov al, [edi]
inc edi
call zip.update_keys
loop @b
.nodata:
pop ebp
ret
.error:
push ContinueBtn
push 1
push aReadError_ptr
push 1
call [SayErr]
jmp return.clear
zip.setpos:
; in: ebx=hFile, edi:esi=newpos
cmp [ebx+file_handle_zip.bPassInited], 0
jnz .pass
push ebp
mov ebp, [ebx+file_handle_zip.base]
push edi esi
sub esi, dword [ebx+file_handle_zip.cur_disk_start]
sbb edi, dword [ebx+file_handle_zip.cur_disk_start+4]
jae .fwd
mov eax, [ebx+file_handle_zip.start_disk]
mov [ebx+file_handle_zip.cur_disk], eax
and dword [ebx+file_handle_zip.cur_disk_start], 0
and dword [ebx+file_handle_zip.cur_disk_start+4], 0
pop esi edi
push edi esi
.fwd:
call zip.get_cur_handle
push edx
call [filesize]
push eax
mov eax, [ebx+file_handle_zip.cur_disk]
cmp eax, [ebx+file_handle_zip.start_disk]
pop eax
jnz @f
sub eax, dword [ebx+file_handle_zip.start]
sbb edx, dword [ebx+file_handle_zip.start+4]
@@:
sub esi, eax
sbb edi, edx
jb @f
inc [ebx+file_handle_zip.cur_disk]
add dword [ebx+file_handle_zip.cur_disk_start], eax
adc dword [ebx+file_handle_zip.cur_disk_start+4], edx
jmp .fwd
@@:
pop esi edi
mov dword [ebx+file_handle_zip.posc], esi
mov dword [ebx+file_handle_zip.posc+4], edi
pop ebp
ret
.pass:
push edi esi
sub esi, dword [ebx+file_handle_zip.posc]
sbb edi, dword [ebx+file_handle_zip.posc+4]
jae .pfwd
lea esi, [ebx+file_handle_zip.saved_keys]
lea edi, [ebx+file_handle_zip.keys]
movsd
movsd
movsd
and dword [ebx+file_handle_zip.posc], 0
and dword [ebx+file_handle_zip.posc+4], 0
mov eax, [ebx+file_handle_zip.start_disk]
mov [ebx+file_handle_zip.cur_disk], eax
and dword [ebx+file_handle_zip.cur_disk_start], 0
and dword [ebx+file_handle_zip.cur_disk_start+4], 0
pop esi edi
push edi esi
.pfwd:
push edi esi
mov ecx, 1024
sub esi, ecx
sbb edi, 0
jae @f
add ecx, esi
@@:
push ecx
mov edi, buffer
call zip.read
pop ecx
pop esi edi
sub esi, ecx
sbb edi, 0
mov eax, esi
or eax, edi
jnz .pfwd
pop esi edi
ret
zip.update_start:
; edi=0, esi=pos
sub esi, dword [ebx+file_handle_zip.cur_disk_start]
mov dword [ebx+file_handle_zip.cur_disk_start], edi
add dword [ebx+file_handle_zip.start], esi
adc dword [ebx+file_handle_zip.start+4], edi
mov dword [ebx+file_handle_zip.posc], edi
mov dword [ebx+file_handle_zip.posc+4], edi
mov eax, [ebx+file_handle_zip.cur_disk]
cmp eax, [ebx+file_handle_zip.start_disk]
jz @f
mov [ebx+file_handle_zip.start_disk], eax
mov dword [ebx+file_handle_zip.start], esi
mov dword [ebx+file_handle_zip.start+4], edi
@@:
ret
; unsigned __stdcall read(HANDLE hFile, void* buf, unsigned size);
read_zip:
mov [_esp], esp
mov [_ebp], ebp
mov [error_proc], .error
mov [clear_proc], .clear
cmp [ebx+file_handle_zip.bError], 0
jnz .reterr
mov edi, [esp+8]
mov ecx, [esp+12]
mov esi, [ebx+file_handle_zip.item]
mov edx, dword [esi+file_in_zip.uncompressed_size]
mov esi, dword [esi+file_in_zip.uncompressed_size+4]
sub edx, dword [ebx+file_handle_zip.pos]
sbb esi, dword [ebx+file_handle_zip.pos+4]
jnz @f
cmp edx, ecx
jae @f
mov ecx, edx
@@:
jecxz .done
mov eax, [ebx+file_handle_zip.decoder]
test eax, eax
jnz .notcopy
call zip.read
jmp .done
.notcopy:
mov dword [eax+streamInfo.fullSize], ecx
and dword [eax+streamInfo.fullSize+4], 0
call read_7z_to_buf
.done:
sub edi, [esp+8]
mov eax, edi
add dword [ebx+file_handle_zip.pos], eax
adc dword [ebx+file_handle_zip.pos+4], 0
.ret:
ret 12
.error:
push ContinueBtn
push 1
push aArchiveDataError_ptr
push 1
call [SayErr]
.clear:
mov ebx, [esp+4]
mov [ebx+file_handle_zip.bError], 1
.reterr:
or eax, -1
ret 12
zipin.fillBuf:
mov ebx, [eax+streamInfo.size]
call zip.read
popad
ret
; void __stdcall setpos(HANDLE hFile, __int64 pos);
setpos_zip:
mov [_esp], esp
mov [_ebp], ebp
mov [error_proc], read_zip.error
mov [clear_proc], read_zip.clear
cmp [ebx+file_handle_zip.decoder], 0
jnz .notcopy
mov esi, [esp+8]
mov edi, [esp+12]
call zip.setpos
mov dword [ebx+file_handle_zip.pos], esi
mov dword [ebx+file_handle_zip.pos+4], edi
ret 12
.notcopy:
cmp [ebx+file_handle_zip.bError], 0
jnz .backward
mov ecx, [esp+8]
mov edx, [esp+12]
sub ecx, dword [ebx+file_handle_zip.pos]
sbb edx, dword [ebx+file_handle_zip.pos+4]
jb .backward
mov eax, [ebx+file_handle_zip.decoder]
mov dword [eax+streamInfo.fullSize], ecx
mov dword [eax+streamInfo.fullSize+4], edx
call skip_7z
add dword [ebx+file_handle_zip.pos], ecx
adc dword [ebx+file_handle_zip.pos+4], edx
ret 12
.backward:
xor eax, eax
mov [ebx+file_handle_zip.bError], al
mov dword [ebx+file_handle_zip.pos], eax
mov dword [ebx+file_handle_zip.pos+4], eax
mov dword [ebx+file_handle_zip.posc], eax
mov dword [ebx+file_handle_zip.posc+4], eax
mov dword [ebx+file_handle_zip.cur_disk_start], eax
mov dword [ebx+file_handle_zip.cur_disk_start+4], eax
lea esi, [ebx+file_handle_zip.saved_keys]
lea edi, [ebx+file_handle_zip.keys]
movsd
movsd
movsd
mov eax, [ebx+file_handle_zip.start_disk]
mov [ebx+file_handle_zip.cur_disk], eax
mov eax, [ebx+file_handle_zip.decoder]
mov eax, [eax+deflate_decoder.inStream]
mov esi, [ebx+file_handle_zip.item]
mov ecx, dword [esi+file_in_zip.compressed_size]
mov dword [eax+streamInfo.fullSize], ecx
mov ecx, dword [esi+file_in_zip.compressed_size+4]
mov dword [eax+streamInfo.fullSize+4], ecx
and [eax+streamInfo.bufDataLen], 0
lea ebp, [eax+streamInfo.size+4]
add ebp, [eax+streamInfo.bufSize]
and [ebp+streamInfo.bufDataLen], 0
call deflate_init_decoder
cmp [esi+file_in_zip.method], 9
setz [ebp+deflate_decoder.bDeflate64]
mov eax, [esp+8]
mov dword [ebp+streamInfo.fullSize], eax
mov eax, [esp+12]
mov dword [ebp+streamInfo.fullSize+4], eax
mov eax, ebp
call skip_7z
mov eax, [esp+8]
mov dword [ebx+file_handle_zip.pos], eax
mov eax, [esp+12]
mov dword [ebx+file_handle_zip.pos+4], eax
ret 12