0,0 → 1,1312 |
; 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 |