Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
632 diamond 1
; Loader of ZIP archives for KFar_Arc.
2
; Written by diamond in 2007.
3
 
4
virtual at 0
5
file_in_zip:
6
.fullname       dd      ?       ; pointer to cp866 string
7
.name           dd      ?
8
.namelen        dd      ?
9
.bIsDirectory   db      ?
10
.bPseudoFolder  db      ?
11
                rb      2
12
.parent         dd      ?       ; pointer to parent directory record
13
.subfolders     dd      ?       ; head of L2-list of subfolders [for folders]
14
.subfolders.end dd      ?
15
.subfiles       dd      ?       ; head of L2-list of files [for folders]
16
.subfiles.end   dd      ?
17
.NumSubItems    dd      ?
18
.next           dd      ?       ; next item of list of subfolders or files
19
.prev           dd      ?       ; previous item of list of subfolders or files
20
.stamp          dd      ?
21
.version_made_by dw     ?
22
.version_needed dw      ?
23
.flags          dw      ?
24
.method         dw      ?
25
.time           dw      ?
26
.date           dw      ?
27
.crc            dd      ?
28
.compressed_size dq     ?
29
.uncompressed_size dq   ?
30
.local_hdr      dq      ?
31
.disk           dd      ?
32
.attr           dd      ?
33
.size = $
34
end virtual
35
 
36
virtual at 0
37
handle_zip:
38
.type           dd      ?
39
.root.subfolders dd     ?
40
.root.subfolders.end dd ?
41
.root.subfiles  dd      ?
42
.root.subfiles.end dd   ?
43
.root.NumSubItems dd    ?
44
.curdir         dd      ?
45
.NumFiles       dd      ?
46
.names_buf      dd      ?
47
.host           dd      ?
48
.host_datetime  rd      6
49
.num_disks      dd      ?
50
.cur_disk       dd      ?
51
.cur_handle     dd      ?
52
.host_hPlugin   dd      ?
53
.host_idPlugin  dd      ?
54
.password_len   dd      ?       ; -1 if no password defined; in characters
55
.password       rb      password_maxlen
56
.basesize = $
57
end virtual
58
 
59
uglobal
60
align 4
61
zip.num_disks   dd      ?
62
zip.cur_disk    dd      ?
63
zip.cur_handle  dd      ?
64
zip.NumAllocated dd     ?
65
zip.NamesSize   dd      ?
66
zip.disk_name   rb      1024
67
 
68
zip64eocd:      ; zip64 end of central directory record
69
.sig            dd      ?       ; signature
70
.size           dq      ?       ; size of this record
71
.version_made_by dw     ?       ; version made by
72
.version_needed dw      ?       ; version needed to extract
73
.disk           dd      ?       ; number of this disk
74
.cdir_disk      dd      ?       ; number of the disk with the start
75
                                ; of the central directory
76
.cdir_entries_disk dq   ?       ; total number of entries in the central
77
                                ; directory on this disk
78
.cdir_entries   dq      ?       ; total number of entries in the central directory
79
.cdir_size      dq      ?       ; size of the central directory
80
.cdir_start     dq      ?       ; offset of start of central directory
81
.sz = $ - zip64eocd
82
 
83
zip.file_header:
84
.sig            dd      ?
85
.version_made_by dw     ?       ; (absent in local file header)
86
.version_needed dw      ?
87
.flags          dw      ?       ; general purpose bit flag
88
.method         dw      ?       ; compression method
89
.time           dw      ?       ; last modified file time
90
.date           dw      ?       ; last modified file date
91
.crc            dd      ?
92
.compressed_size dd     ?
93
.uncompressed_size dd   ?
94
.fname_len      dw      ?       ; file name length
95
.extra_len      dw      ?       ; extra field length
96
.sz_local = $ - (zip.file_header+2) ; size of local file header
97
.fcmt_len       dw      ?       ; file comment length
98
.disk           dw      ?       ; disk number start
99
.internal_attr  dw      ?
100
.external_attr  dd      ?
101
.local_hdr      dd      ?       ; relative offset of local header
102
.sz_cdir = $ - zip.file_header  ; size of file header in central directory
103
 
104
zip.extra:
105
.id     dw      ?
106
.size   dw      ?
107
zip.extra.zip64:
108
.uncompressed_size      dq      ?
109
.compressed_size        dq      ?
110
.local_hdr              dq      ?
111
.disk                   dd      ?
112
.sz = $ - zip.extra.zip64
113
endg
114
 
115
open_zip:
116
        and     [zip.cur_handle], 0
117
; look for end of central directory record
118
        push    ebp
119
        call    [filesize]
120
        sub     eax, 1024
121
        sbb     edx, 0
122
        jnb     @f
123
        xor     eax, eax
124
        xor     edx, edx
125
@@:
126
        push    edx
127
        push    eax
128
        push    0
129
        push    ebp
130
        call    [seek]
131
        push    1024
132
        push    buffer
133
        push    ebp
134
        call    [read]
135
        cmp     eax, 22
136
        jge     @f
137
        xor     eax, eax
138
.ret:
139
        ret
140
@@:
141
        mov     [inStream], ebp
142
        lea     edi, [buffer+eax-22]
143
@@:
144
        cmp     dword [edi], 0x06054B50
145
        jz      .eocd_found
146
        dec     edi
147
        cmp     edi, buffer
148
        jae     @b
149
        xor     eax, eax
150
        ret
151
.eocd_found:
152
        cmp     edi, buffer+20
153
        jb      .no_eocd64
154
        cmp     dword [edi-20], 0x07064B50
155
        jnz     .no_eocd64
156
        mov     ebx, ebp
157
        mov     ecx, [edi-16]
158
        mov     edx, [edi-4]
159
        mov     [zip.num_disks], edx
160
        dec     edx
161
        mov     [zip.cur_disk], edx
162
        cmp     edx, ecx
163
        jz      @f
164
        push    1
165
        push    dword [esp+8+28]
166
        push    dword [esp+12+24]
167
        push    dword [esp+16+20]
168
        call    zip.open_splitted
169
        test    eax, eax
170
        jz      .ret
171
        mov     ebx, eax
172
@@:
173
        push    dword [edi-8]
174
        push    dword [edi-12]
175
        push    0
176
        push    ebx
177
        call    [seek]
178
        push    zip64eocd.sz
179
        push    zip64eocd
180
        push    ebx
181
        call    [read]
182
        cmp     eax, zip64eocd.sz
183
        jnz     .close_err
184
        cmp     [zip64eocd.sig], 0x06064B50
185
        jnz     .close_err
186
        mov     ecx, [zip64eocd.cdir_disk]
187
        cmp     ecx, [zip.cur_disk]
188
        jz      @f
189
        push    1
190
        push    dword [esp+8+28]
191
        push    dword [esp+12+24]
192
        push    dword [esp+16+20]
193
        call    zip.open_splitted
194
        test    eax, eax
195
        jz      .ret
196
        mov     ebx, eax
197
@@:
198
        push    dword [zip64eocd.cdir_start+4]
199
        push    dword [zip64eocd.cdir_start]
200
        push    0
201
        push    ebx
202
        call    [seek]
203
        mov     ecx, dword [zip64eocd.cdir_entries]
204
        jmp     .parse_cdir
205
.close_err:
206
        call    close_cur_handle
207
        or      eax, -1
208
        ret
209
.no_eocd64:
210
        mov     ebx, ebp
211
        movzx   ecx, word [edi+6]
212
        movzx   edx, word [edi+4]
213
        inc     edx
214
        mov     [zip.num_disks], edx
215
        dec     edx
216
        mov     [zip.cur_disk], edx
217
        cmp     edx, ecx
218
        jz      @f
219
        push    1
220
        push    dword [esp+8+28]
221
        push    dword [esp+12+24]
222
        push    dword [esp+16+20]
223
        call    zip.open_splitted
224
        test    eax, eax
225
        jz      .ret
226
        mov     ebx, eax
227
@@:
228
        push    0
229
        push    dword [edi+16]
230
        push    0
231
        push    ebx
232
        call    [seek]
233
        movzx   ecx, word [edi+10]
234
.parse_cdir:
235
        mov     [zip.NumAllocated], ecx
236
        imul    ecx, file_in_zip.size
237
        jc      .close_err
238
        add     ecx, handle_zip.basesize
239
        jc      .close_err
240
        mov     [hOut.allocated], ecx
241
        call    [pgalloc]
242
        test    eax, eax
243
        jz      .close_err
244
        mov     [hOut], eax
245
        push    eax
246
        mov     edi, eax
247
        shr     ecx, 2
248
        xor     eax, eax
249
        rep     stosd
250
        mov     edi, [esp+8+28]
251
        dec     ecx
252
        repnz   scasb
253
        not     ecx
254
        mov     [zip.NamesSize], ecx
255
        call    [pgalloc]
256
        mov     ebp, eax
257
        pop     edi
258
        test    eax, eax
259
        jz      .free_err
260
        push    edi
261
        mov     edi, ebp
262
        mov     esi, [esp+8+28]
263
        rep     movsb
264
        pop     edi
265
        mov     byte [edi+handle_zip.type], type_zip
266
        add     edi, handle_zip.basesize + file_in_zip.version_made_by
267
.cdir_loop:
268
        mov     esi, zip.file_header
269
        push    zip.file_header.sz_cdir
270
        push    esi
271
        push    ebx
272
        call    [read]
273
        cmp     eax, zip.file_header.sz_cdir
274
        jz      .cdir_item_ok
275
        mov     ecx, [zip.cur_disk]
276
        inc     ecx
277
        cmp     ecx, [zip.num_disks]
278
        jz      .cdir_done
279
        push    1
280
        push    dword [esp+8+28]
281
        push    dword [esp+12+24]
282
        push    dword [esp+16+20]
283
        call    zip.open_splitted
284
        test    eax, eax
285
        jz      .free_err
286
        mov     ebx, eax
287
        jmp     .cdir_loop
288
.cdir_item_ok:
289
        lodsd
290
        cmp     eax, 0x02014B50
291
        jnz     .cdir_done
292
        mov     eax, [hOut]
293
        inc     [eax+handle_zip.NumFiles]
294
        mov     eax, [eax+handle_zip.NumFiles]
295
        cmp     eax, [zip.NumAllocated]
296
        jbe     .norealloc
297
        inc     [zip.NumAllocated]
298
        mov     ecx, [hOut.allocated]
299
        add     ecx, file_in_zip.size
300
        push    ecx
301
        and     ecx, 0xFFF
302
        cmp     ecx, file_in_zip.size
303
        pop     ecx
304
        mov     [hOut.allocated], ecx
305
        ja      .norealloc
306
        mov     edx, [hOut]
307
        call    [pgrealloc]
308
        test    eax, eax
309
        jnz     @f
310
.free_err:
311
        mov     ecx, [hOut]
312
        call    [pgfree]
313
        mov     ecx, ebp
314
        call    [pgfree]
315
        jmp     .close_err
316
@@:
317
        mov     [hOut], eax
318
        sub     edi, edx
319
        add     edi, eax
320
.norealloc:
321
        push    5
322
        pop     ecx
323
        rep     movsd
324
        xor     eax, eax
325
        stosd
326
        movsd
327
        stosd
328
        lodsw
329
        mov     ecx, [zip.NamesSize]
330
        lea     edx, [ecx+0xFFF]
331
        and     edx, not 0xFFF
332
        lea     ecx, [ecx+eax+1]
333
        mov     [zip.NamesSize], ecx
334
        push    ecx
335
        add     ecx, 0xFFF
336
        and     ecx, not 0xFFF
337
        cmp     ecx, edx
338
        pop     ecx
339
        jz      .noreallocname
340
        mov     edx, ebp
341
        call    [pgrealloc]
342
        test    eax, eax
343
        jz      .free_err
344
        mov     ebp, eax
345
.noreallocname:
346
        movzx   eax, word [esi-2]
347
        inc     eax
348
        mov     edx, [zip.NamesSize]
349
        sub     edx, eax
350
        mov     dword [edi-(file_in_zip.uncompressed_size+8)+file_in_zip.fullname], edx
351
        add     edx, ebp
352
        dec     eax
353
        mov     byte [edx+eax], 0
354
        push    eax
355
        push    edx
356
        push    ebx
357
        call    [read]
358
        movzx   eax, word [esi-2]
359
        cmp     byte [edx+eax-1], '/'
360
        jnz     @f
361
        mov     byte [edx+eax-1], 0
362
        mov     byte [edi-(file_in_zip.uncompressed_size+8)+file_in_zip.bIsDirectory], 1
363
@@:
364
        mov     eax, [esi+12]
365
        mov     [edi], eax
366
        movzx   eax, word [esi+4]
367
        mov     [edi+8], eax
368
        lodsw
369
        push    esi
370
        movzx   ecx, ax
371
        mov     edx, ecx
372
.parse_extra:
373
        sub     ecx, 4
374
        jb      .extra_done
375
        mov     esi, zip.extra
376
        push    4
377
        push    esi
378
        push    ebx
379
        call    [read]
380
        cmp     eax, 4
381
        jnz     .extra_done
382
        sub     edx, eax
383
        cmp     word [esi], 1
384
        jnz     .extra_skip
385
        mov     esi, zip.extra.zip64
386
        push    esi edi
387
        sub     edi, 8
388
        xchg    esi, edi
389
        movsd
390
        movsd
391
        sub     esi, 16
392
        movsd
393
        movsd
394
        add     esi, 8
395
        movsd
396
        movsd
397
        movsd
398
        pop     edi esi
399
        movzx   eax, [zip.extra.size]
400
        cmp     eax, zip.extra.zip64.sz
401
        jb      @f
402
        mov     al, zip.extra.zip64.sz
403
@@:
404
        sub     ecx, eax
405
        jb      .extra_done
406
        push    eax
407
        push    esi
408
        push    ebx
409
        call    [read]
410
        sub     edx, eax
411
        sub     [zip.extra.size], ax
412
        sub     edi, 8
413
        movsd
414
        movsd
415
        sub     edi, 16
416
        movsd
417
        movsd
418
        add     edi, 8
419
        movsd
420
        movsd
421
        movsd
422
        sub     edi, 12
423
.extra_skip:
424
        movzx   eax, word [zip.extra.size]
425
        sub     ecx, eax
426
        jb      .extra_done
427
        sub     edx, eax
428
        push    0
429
        push    eax
430
        push    1
431
        push    ebx
432
        call    [seek]
433
        jmp     .parse_extra
434
.extra_done:
435
        pop     esi
436
        xor     eax, eax
437
        lodsw
438
        add     edx, eax
439
        jz      @f
440
        push    0
441
        push    edx
442
        push    1
443
        push    ebx
444
        call    [seek]
445
@@:
446
        mov     eax, [esi+4]
447
        mov     dword [edi+file_in_zip.attr-(file_in_zip.uncompressed_size+8)], eax
448
;        test    al, 10h
449
;        setnz   byte [edi+file_in_zip.bIsDirectory-(file_in_zip.uncompressed_size+8)]
450
        add     edi, file_in_zip.size-file_in_zip.uncompressed_size-8+file_in_zip.version_made_by
451
        jmp     .cdir_loop
452
.cdir_done:
453
        mov     edi, [hOut]
454
        mov     esi, zip.num_disks
455
        push    edi
456
        add     edi, handle_zip.num_disks
457
        movsd
458
        movsd
459
        movsd
460
        pop     edi
461
        mov     [edi+handle_zip.names_buf], ebp
462
        mov     ecx, [edi+handle_zip.NumFiles]
463
        jecxz   .nofiles
464
        add     edi, handle_zip.basesize + file_in_zip.fullname
465
@@:
466
        add     [edi], ebp
467
        add     edi, file_in_zip.size
468
        loop    @b
469
.nofiles:
470
        mov     edx, [hOut]
471
        mov     ebx, [edx+handle_zip.NumFiles]
472
        lea     edi, [edx+handle_zip.root.subfolders]
473
        add     edx, handle_zip.basesize
474
        push    file_in_zip.size
475
        call    init_file_links
476
        mov     eax, [hOut]
477
        and     [eax+handle_zip.curdir], 0      ; set root directory
478
        mov     esi, [inStream]
479
        mov     [eax+handle_zip.host], esi
480
        or      [eax+handle_zip.password_len], -1
481
        mov     esi, [esp+4+20]
482
        mov     [eax+handle_zip.host_idPlugin], esi
483
        mov     esi, [esp+4+24]
484
        mov     [eax+handle_zip.host_hPlugin], esi
485
        lea     edi, [eax+handle_zip.host_datetime]
486
        mov     esi, [esp+12]
487
        add     esi, 8
488
        mov     ecx, 6
489
        rep     movsd
490
        ret
491
 
492
close_cur_handle:
493
        mov     edx, zip.cur_handle
494
        or      dword [edx-4], -1
495
        cmp     dword [edx], 0
496
        jz      @f
497
        push    dword [edx]
498
        call    [close]
499
        and     dword [edx], 0
500
@@:
501
        ret
502
 
503
zip.open_splitted:
504
        call    close_cur_handle
505
        mov     [zip.cur_disk], ecx
506
        inc     ecx
507
        mov     edx, ecx
508
        cmp     ecx, [zip.num_disks]
509
        jnz     @f
510
        mov     ecx, [inStream]
511
        push    0
512
        push    0
513
        push    0
514
        push    ecx
515
        call    [seek]
516
        mov     eax, ecx
517
        ret     16
518
@@:
519
        push    esi edi
520
        mov     esi, [esp+8+12]
521
        mov     edi, zip.disk_name
522
        mov     [esp+8+12], edi
523
        mov     ecx, 1024
524
@@:
525
        lodsb
526
        stosb
527
        test    al, al
528
        loopnz  @b
529
        jnz     .ret0
530
        cmp     ecx, 4
531
        jb      .ret0
532
        dec     edi
533
        mov     al, '.'
534
        stosb
535
        cmp     edx, 100
536
        jae     .big
537
        mov     al, 'z'
538
        stosb
539
        mov     eax, edx
540
        aam
541
        add     ax, '00'
542
        xchg    al, ah
543
        stosw
544
        mov     byte [edi], 0
545
.nameok:
546
        pop     edi esi
547
        push    dword [esp+16]
548
        push    dword [esp+16]
549
        push    dword [esp+16]
550
        push    dword [esp+16]
551
        call    [open2]
552
        mov     [zip.cur_handle], eax
553
        ret     16
554
.ret0:
555
        mov     byte [edi-1], 0
556
        pop     edi esi
557
        xor     eax, eax
558
        ret     16
559
.big:
560
        cmp     ecx, 12
561
        jb      .ret0
562
        push    10
563
        pop     ecx
564
        push    -'0'
565
        mov     eax, edx
566
@@:
567
        xor     edx, edx
568
        div     ecx
569
        push    edx
570
        test    eax, eax
571
        jnz     @b
572
@@:
573
        pop     eax
574
        add     al, '0'
575
        jz      .nameok
576
        stosb
577
        jmp     @b
578
 
579
close_zip:
580
        mov     esi, [esp+4]
581
        push    [esi+handle_zip.host]
582
        call    [close]
583
        mov     ecx, [esi+handle_zip.names_buf]
584
        call    [pgfree]
585
        mov     ecx, [esi+handle_zip.cur_handle]
586
        jecxz   @f
587
        push    ecx
588
        call    [close]
589
@@:
590
        mov     ecx, esi
591
        call    [pgfree]
592
        ret     4
593
 
594
; ebp=hPlugin, eax->item, edi->info
595
getattr_zip:
596
        cmp     [eax+file_in_zip.bPseudoFolder], 0
597
        jnz     .pseudo
598
        mov     esi, eax
599
        mov     eax, [eax+file_in_zip.attr]
600
        stosd
601
        xor     eax, eax
602
        stosd
603
        stosd
604
        stosd
605
        stosd
606
        stosd
607
        movzx   eax, word [esi+file_in_zip.time]
608
        mov     ecx, eax
609
        and     al, 0x1F
610
        shr     ecx, 5
611
        add     eax, eax
612
        stosb
613
        mov     eax, ecx
614
        and     al, 0x3F
615
        shr     ecx, 6
616
        stosb
617
        mov     eax, ecx
618
        stosw
619
        movzx   eax, word [esi+file_in_zip.date]
620
        mov     ecx, eax
621
        and     al, 0x1F
622
        shr     ecx, 5
623
        stosb
624
        mov     eax, ecx
625
        and     al, 0xF
626
        shr     ecx, 4
627
        stosb
628
        lea     eax, [ecx+1980]
629
        stosw
630
        mov     eax, dword [esi+file_in_zip.uncompressed_size]
631
        stosd
632
        mov     eax, dword [esi+file_in_zip.uncompressed_size+4]
633
        stosd
634
        ret
635
.pseudo:
636
        push    0x10    ; attributes: folder
637
        pop     eax
638
        stosd
639
        xor     eax, eax
640
        stosd
641
        lea     esi, [ebp+handle_zip.host_datetime]
642
        push    6
643
        pop     ecx
644
        rep     movsd
645
        stosd
646
        stosd
647
        ret
648
 
649
virtual at 0
650
file_handle_zip:
651
.type   dd      ?
652
.item   dd      ?
653
.base   dd      ?
654
.start_disk     dd      ?
655
.start          dq      ?
656
.pos            dq      ?
657
.posc           dq      ?
658
.decoder        dd      ?
659
.cur_disk       dd      ?
660
.cur_disk_start dq      ?
661
.bError         db      ?
662
.bPassProtected db      ?
663
.bPassInited    db      ?
664
                rb      1
665
.keys           rd      3
666
.saved_keys     rd      3
667
.size = $
668
end virtual
669
 
670
iglobal
671
handle_table_zip        dd      handle_table_zip, handle_table_zip
672
endg
673
 
674
; ebp=hPlugin, eax->item, edi=mode
675
open_file_zip:
676
        mov     [_esp], esp
677
        mov     [_ebp], ebp
678
        mov     [error_proc], .error
679
        mov     [clear_proc], .clear
680
        mov     ecx, [ebp+handle_zip.password_len]
681
        inc     ecx
682
        setnz   [bPasswordDefined]
683
        jz      @f
684
        dec     ecx
685
        mov     [password_size], ecx
686
        lea     esi, [ebp+handle_zip.password]
687
        mov     edi, password_ansi
688
        rep     movsb
689
@@:
690
        xor     edi, edi
691
        mov     [hOut], edi
692
        mov     [hOut.allocated], edi
693
        mov     ebx, eax
694
        movzx   eax, [ebx+file_in_zip.method]
695
        test    eax, eax
696
        jz      .common
697
.notcopy:
698
        cmp     eax, 8
699
        jz      .deflate
700
        cmp     eax, 9
701
        jz      .deflate
702
        push    -'0'
703
        push    10
704
        pop     ecx
705
@@:
706
        xor     edx, edx
707
        div     ecx
708
        push    edx
709
        test    eax, eax
710
        jnz     @b
711
        mov     edi, aUnknownMethod.z
712
        mov     al, ' '
713
        stosb
714
@@:
715
        pop     eax
716
        add     al, '0'
717
        stosb
718
        jnz     @b
719
        push    ContinueBtn
720
        push    1
721
        push    aUnknownMethod_ptr
722
        push    1
723
        call    [SayErr]
724
        xor     eax, eax
725
.ret1:
726
        ret
727
.deflate:
728
        mov     ecx, 0x12000
729
        call    [pgalloc]
730
        test    eax, eax
731
        jz      .ret1
732
        mov     [hOut], eax
733
        mov     ecx, dword [ebx+file_in_zip.compressed_size]
734
        mov     dword [eax+streamInfo.fullSize], ecx
735
        mov     ecx, dword [ebx+file_in_zip.compressed_size+4]
736
        mov     dword [eax+streamInfo.fullSize+4], ecx
737
        mov     [eax+streamInfo.fillBuf], zipin.fillBuf
738
        mov     [eax+streamInfo.bufSize], 0x2000 - (streamInfo.size+4) - deflate_decoder.size
739
        and     [eax+streamInfo.bufDataLen], 0
740
        lea     edx, [eax+streamInfo.size+4]
741
        mov     [eax+streamInfo.bufPtr], edx
742
        add     edx, [eax+streamInfo.bufSize]
743
        mov     ecx, dword [ebx+file_in_zip.uncompressed_size]
744
        mov     dword [edx+streamInfo.fullSize], ecx
745
        mov     ecx, dword [ebx+file_in_zip.uncompressed_size+4]
746
        mov     dword [edx+streamInfo.fullSize+4], ecx
747
        mov     [edx+streamInfo.bufSize], 0x10000
748
        and     [edx+streamInfo.bufDataLen], 0
749
        mov     [edx+streamInfo.size], eax
750
        lea     eax, [edx+deflate_decoder.size]
751
        mov     [edx+streamInfo.bufPtr], eax
752
        push    ebp
753
        mov     ebp, edx
754
        call    deflate_init_decoder
755
        mov     edi, ebp
756
        pop     ebp
757
        cmp     [ebx+file_in_zip.method], 9
758
        setz    [edi+deflate_decoder.bDeflate64]
759
.common:
760
        mov     esi, handle_table_zip
761
        push    file_handle_zip.size
762
        pop     ecx
763
        call    alloc_handle
764
        test    eax, eax
765
        jz      return.clear
766
        mov     edx, [hOut]
767
        mov     [edx+streamInfo.size], eax
768
        mov     [eax+file_handle_zip.type], type_zip
769
        xor     edx, edx
770
        mov     dword [eax+file_handle_zip.pos], edx
771
        mov     dword [eax+file_handle_zip.pos+4], edx
772
        mov     dword [eax+file_handle_zip.posc], edx
773
        mov     dword [eax+file_handle_zip.posc+4], edx
774
        mov     [eax+file_handle_zip.item], ebx
775
        mov     [eax+file_handle_zip.base], ebp
776
        mov     [eax+file_handle_zip.decoder], edi
777
        mov     [eax+file_handle_zip.bError], dl
778
        mov     [eax+file_handle_zip.bPassInited], dl
779
        test    [ebx+file_in_zip.flags], 1
780
        setnz   [eax+file_handle_zip.bPassProtected]
781
        mov     ecx, [ebx+file_in_zip.disk]
782
        mov     [eax+file_handle_zip.start_disk], ecx
783
        mov     [eax+file_handle_zip.cur_disk], ecx
784
        mov     ecx, dword [ebx+file_in_zip.local_hdr]
785
        mov     dword [eax+file_handle_zip.start], ecx
786
        mov     ecx, dword [ebx+file_in_zip.local_hdr+4]
787
        mov     dword [eax+file_handle_zip.start+4], ecx
788
        mov     dword [eax+file_handle_zip.cur_disk_start], edx
789
        mov     dword [eax+file_handle_zip.cur_disk_start+4], edx
790
        mov     [hOut.allocated], eax
791
        mov     [hOut], edx
792
        push    ebx
793
        mov     ebx, eax
794
        push    zip.file_header.sz_local
795
        pop     ecx
796
        mov     edi, zip.file_header+2
797
        call    zip.read
798
        cmp     dword [edi-zip.file_header.sz_local], 0x04034B50
799
        jnz     return.err
800
        movzx   ecx, word [edi-4]
801
        movzx   eax, word [edi-2]
802
        lea     esi, [ecx+eax+zip.file_header.sz_local]
803
        xor     edi, edi
804
        call    zip.setpos
805
        call    zip.update_start
806
        cmp     [ebx+file_handle_zip.bPassProtected], 0
807
        jz      .nopass
808
.redo_pass:
809
        call    query_password
810
        jz      return.clear
811
        call    zip.init_keys
812
        push    12
813
        pop     ecx
814
        mov     edi, buffer
815
        call    zip.read
816
        mov     eax, [ebx+file_handle_zip.item]
817
        mov     al, byte [eax+file_in_zip.crc+3]
818
        cmp     [edi-1], al
819
        jz      .passok
820
        push    CancelPassBtn
821
        push    2
822
        push    aArchiveDataErrorPass_ptr
823
        push    1
824
        call    [SayErr]
825
        cmp     al, 1
826
        jnz     return.clear
827
        xor     eax, eax
828
        mov     dword [ebx+file_handle_zip.posc], eax
829
        mov     dword [ebx+file_handle_zip.posc+4], eax
830
        mov     dword [ebx+file_handle_zip.cur_disk_start], eax
831
        mov     dword [ebx+file_handle_zip.cur_disk_start+4], eax
832
        mov     eax, [ebx+file_handle_zip.start_disk]
833
        mov     [ebx+file_handle_zip.cur_disk], eax
834
        mov     [bPasswordDefined], 0
835
        jmp     .redo_pass
836
.passok:
837
        mov     ecx, [password_size]
838
        mov     [ebp+handle_zip.password_len], ecx
839
        mov     esi, password_ansi
840
        lea     edi, [ebp+handle_zip.password]
841
        rep     movsb
842
        lea     esi, [ebx+file_handle_zip.keys]
843
        lea     edi, [ebx+file_handle_zip.saved_keys]
844
        movsd
845
        movsd
846
        movsd
847
        mov     esi, 12
848
        xor     edi, edi
849
        call    zip.update_start
850
.nopass:
851
        pop     ebx
852
        mov     eax, [hOut.allocated]
853
        cmp     dword [ebx+file_in_zip.uncompressed_size+4], 0
854
        jnz     .ret
855
        mov     ecx, dword [ebx+file_in_zip.uncompressed_size]
856
if defined LIMIT_FOR_MEM_STREAM
857
        cmp     ecx, LIMIT_FOR_MEM_STREAM
858
        ja      .ret
859
end if
860
        push    eax ecx
861
        add     ecx, 0x3FF
862
        shr     ecx, 10         ; get size in Kb
863
        call    [getfreemem]
864
        shr     eax, 2
865
        cmp     ecx, eax
866
        pop     ecx eax
867
        ja      .ret
868
; create memory stream and unpack to memory
869
        mov     ebx, eax
870
        add     ecx, mem_stream.buf
871
        call    [pgalloc]
872
        sub     ecx, mem_stream.buf
873
        test    eax, eax
874
        jz      return.clear
875
        mov     edi, eax
876
        mov     [hOut], eax
877
        xor     eax, eax        ; type_mem_stream
878
        stosd                   ; mem_stream.type
879
        mov     eax, ecx
880
        stosd                   ; mem_stream.size
881
        xor     eax, eax
882
        stosd                   ; mem_stream.pos
883
        push    ecx edi
884
        push    ecx
885
        push    edi
886
        push    ebx
887
        call    read_zip
888
        pop     esi ecx
889
        mov     [_esp], esp
890
        mov     [_ebp], ebp
891
        mov     [error_proc], .error
892
        mov     [clear_proc], .clear
893
        cmp     eax, -1
894
        jz      .clear
895
;        cmp     eax, ecx
896
;        jnz     .error
897
;        call    crc
898
;        mov     edx, [ebx+file_handle_zip.item]
899
;        cmp     eax, [edx+file_in_zip.crc]
900
;        jnz     .error
901
        call    .1
902
        mov     eax, [hOut]
903
.ret:
904
        ret
905
 
906
.error:
907
        push    ContinueBtn
908
        push    1
909
        push    aArchiveDataError_ptr
910
        push    1
911
        call    [SayErr]
912
.clear:
913
        mov     ecx, [hOut]
914
        call    [pgfree]
915
.1:
916
        mov     ebx, [hOut.allocated]
917
        test    ebx, ebx
918
        jz      @f
919
        push    ebx
920
        call    close_file_zip
921
@@:
922
        xor     eax, eax
923
        ret
924
 
925
close_file_zip:
926
        mov     ecx, [ebx+file_handle_zip.decoder]
927
        jecxz   @f
928
        mov     ecx, [ecx+streamInfo.size]
929
        call    [pgfree]
930
@@:
931
        mov     esi, ebx
932
        call    free_handle
933
        ret     4
934
 
935
zip.init_keys:
936
        mov     [ebx+file_handle_zip.keys+0], 305419896
937
        mov     [ebx+file_handle_zip.keys+4], 591751049
938
        mov     [ebx+file_handle_zip.keys+8], 878082192
939
        mov     ecx, [password_size]
940
        jecxz   .empty
941
        mov     esi, password_ansi
942
        xor     eax, eax
943
@@:
944
        lodsb
945
        call    zip.update_keys
946
        loop    @b
947
.empty:
948
        mov     [ebx+file_handle_zip.bPassInited], 1
949
        ret
950
 
951
zip.update_keys:
952
        mov     dl, byte [ebx+file_handle_zip.keys]
953
        xor     dl, al
954
        movzx   edx, dl
955
        mov     eax, [ebx+file_handle_zip.keys]
956
        shr     eax, 8
957
        xor     eax, [crc_table+edx*4]
958
        mov     [ebx+file_handle_zip.keys], eax
959
        movzx   eax, al
960
        add     eax, [ebx+file_handle_zip.keys+4]
961
        imul    eax, 134775813
962
        inc     eax
963
        mov     [ebx+file_handle_zip.keys+4], eax
964
        shr     eax, 24
965
        mov     edx, [ebx+file_handle_zip.keys+8]
966
        xor     al, dl
967
        shr     edx, 8
968
        xor     edx, [crc_table+eax*4]
969
        mov     [ebx+file_handle_zip.keys+8], edx
970
        ret
971
 
972
zip.decrypt_byte:
973
; out: ah = result
974
        mov     eax, [ebx+file_handle_zip.keys+8]
975
        or      eax, 2
976
        mov     edx, eax
977
        xor     edx, 1
978
        mul     edx
979
        ret
980
 
981
zip.get_cur_handle:
982
        mov     edx, [ebp+handle_zip.host]
983
        mov     eax, [ebp+handle_zip.num_disks]
984
        dec     eax
985
        cmp     eax, [ebx+file_handle_zip.cur_disk]
986
        jz      .handleok
987
        inc     eax
988
        mov     [zip.num_disks], eax
989
        mov     edx, [ebp+handle_zip.cur_handle]
990
        mov     eax, [ebp+handle_zip.cur_disk]
991
        cmp     eax, [ebx+file_handle_zip.cur_disk]
992
        jz      .handleok
993
        mov     [zip.cur_handle], edx
994
        push    ecx
995
        mov     ecx, [ebx+file_handle_zip.cur_disk]
996
        push    1
997
        push    [ebp+handle_zip.names_buf]
998
        push    [ebp+handle_zip.host_hPlugin]
999
        push    [ebp+handle_zip.host_idPlugin]
1000
        call    zip.open_splitted
1001
        pop     ecx
1002
        mov     edx, eax
1003
        test    eax, eax
1004
        jnz     @f
1005
        push    zip.disk_name
1006
        push    aCannotOpenFile
1007
        mov     eax, esp
1008
        push    ContinueBtn
1009
        push    1
1010
        push    eax
1011
        push    2
1012
        call    [SayErr]
1013
        jmp     return.clear
1014
@@:
1015
        mov     [ebp+handle_zip.cur_handle], eax
1016
        mov     eax, [ebx+file_handle_zip.cur_disk]
1017
        mov     [ebp+handle_zip.cur_disk], eax
1018
.handleok:
1019
        ret
1020
 
1021
zip.read:
1022
; in: ebx=hFile, edi->buf, ecx=size
1023
        push    ebp edi
1024
        mov     ebp, [ebx+file_handle_zip.base]
1025
.s:
1026
        call    zip.get_cur_handle
1027
        mov     eax, dword [ebx+file_handle_zip.posc]
1028
        mov     esi, dword [ebx+file_handle_zip.posc+4]
1029
        sub     eax, dword [ebx+file_handle_zip.cur_disk_start]
1030
        sbb     esi, dword [ebx+file_handle_zip.cur_disk_start+4]
1031
        push    eax
1032
        mov     eax, dword [ebx+file_handle_zip.cur_disk]
1033
        cmp     eax, dword [ebx+file_handle_zip.start_disk]
1034
        pop     eax
1035
        jnz     @f
1036
        add     eax, dword [ebx+file_handle_zip.start]
1037
        adc     esi, dword [ebx+file_handle_zip.start+4]
1038
@@:
1039
        push    esi
1040
        push    eax
1041
        push    0
1042
        push    edx
1043
        call    [seek]
1044
        push    ecx
1045
        push    edi
1046
        push    edx
1047
        call    [read]
1048
        cmp     eax, -1
1049
        jz      .error
1050
        add     edi, eax
1051
        add     dword [ebx+file_handle_zip.posc], eax
1052
        adc     dword [ebx+file_handle_zip.posc+4], 0
1053
        sub     ecx, eax
1054
        jz      .ok
1055
        inc     dword [ebx+file_handle_zip.cur_disk]
1056
        mov     eax, dword [ebx+file_handle_zip.posc]
1057
        mov     dword [ebx+file_handle_zip.cur_disk_start], eax
1058
        mov     eax, dword [ebx+file_handle_zip.posc+4]
1059
        mov     dword [ebx+file_handle_zip.cur_disk_start+4], eax
1060
        jmp     .s
1061
.ok:
1062
        cmp     [ebx+file_handle_zip.bPassInited], 0
1063
        jnz     .decrypt
1064
        pop     eax ebp
1065
        ret
1066
.decrypt:
1067
        mov     ecx, edi
1068
        pop     edi
1069
        sub     ecx, edi
1070
        jz      .nodata
1071
@@:
1072
        call    zip.decrypt_byte
1073
        xor     [edi], ah
1074
        mov     al, [edi]
1075
        inc     edi
1076
        call    zip.update_keys
1077
        loop    @b
1078
.nodata:
1079
        pop     ebp
1080
        ret
1081
.error:
1082
        push    ContinueBtn
1083
        push    1
1084
        push    aReadError_ptr
1085
        push    1
1086
        call    [SayErr]
1087
        jmp     return.clear
1088
 
1089
zip.setpos:
1090
; in: ebx=hFile, edi:esi=newpos
1091
        cmp     [ebx+file_handle_zip.bPassInited], 0
1092
        jnz     .pass
1093
        push    ebp
1094
        mov     ebp, [ebx+file_handle_zip.base]
1095
        push    edi esi
1096
        sub     esi, dword [ebx+file_handle_zip.cur_disk_start]
1097
        sbb     edi, dword [ebx+file_handle_zip.cur_disk_start+4]
1098
        jae     .fwd
1099
        mov     eax, [ebx+file_handle_zip.start_disk]
1100
        mov     [ebx+file_handle_zip.cur_disk], eax
1101
        and     dword [ebx+file_handle_zip.cur_disk_start], 0
1102
        and     dword [ebx+file_handle_zip.cur_disk_start+4], 0
1103
        pop     esi edi
1104
        push    edi esi
1105
.fwd:
1106
        call    zip.get_cur_handle
1107
        push    edx
1108
        call    [filesize]
1109
        push    eax
1110
        mov     eax, [ebx+file_handle_zip.cur_disk]
1111
        cmp     eax, [ebx+file_handle_zip.start_disk]
1112
        pop     eax
1113
        jnz     @f
1114
        sub     eax, dword [ebx+file_handle_zip.start]
1115
        sbb     edx, dword [ebx+file_handle_zip.start+4]
1116
@@:
1117
        sub     esi, eax
1118
        sbb     edi, edx
1119
        jb      @f
1120
        inc     [ebx+file_handle_zip.cur_disk]
1121
        add     dword [ebx+file_handle_zip.cur_disk_start], eax
1122
        adc     dword [ebx+file_handle_zip.cur_disk_start+4], edx
1123
        jmp     .fwd
1124
@@:
1125
        pop     esi edi
1126
        mov     dword [ebx+file_handle_zip.posc], esi
1127
        mov     dword [ebx+file_handle_zip.posc+4], edi
1128
        pop     ebp
1129
        ret
1130
.pass:
1131
        push    edi esi
1132
        sub     esi, dword [ebx+file_handle_zip.posc]
1133
        sbb     edi, dword [ebx+file_handle_zip.posc+4]
1134
        jae     .pfwd
1135
        lea     esi, [ebx+file_handle_zip.saved_keys]
1136
        lea     edi, [ebx+file_handle_zip.keys]
1137
        movsd
1138
        movsd
1139
        movsd
1140
        and     dword [ebx+file_handle_zip.posc], 0
1141
        and     dword [ebx+file_handle_zip.posc+4], 0
1142
        mov     eax, [ebx+file_handle_zip.start_disk]
1143
        mov     [ebx+file_handle_zip.cur_disk], eax
1144
        and     dword [ebx+file_handle_zip.cur_disk_start], 0
1145
        and     dword [ebx+file_handle_zip.cur_disk_start+4], 0
1146
        pop     esi edi
1147
        push    edi esi
1148
.pfwd:
1149
        push    edi esi
1150
        mov     ecx, 1024
1151
        sub     esi, ecx
1152
        sbb     edi, 0
1153
        jae     @f
1154
        add     ecx, esi
1155
@@:
1156
        push    ecx
1157
        mov     edi, buffer
1158
        call    zip.read
1159
        pop     ecx
1160
        pop     esi edi
1161
        sub     esi, ecx
1162
        sbb     edi, 0
1163
        mov     eax, esi
1164
        or      eax, edi
1165
        jnz     .pfwd
1166
        pop     esi edi
1167
        ret
1168
 
1169
zip.update_start:
1170
; edi=0, esi=pos
1171
        sub     esi, dword [ebx+file_handle_zip.cur_disk_start]
1172
        mov     dword [ebx+file_handle_zip.cur_disk_start], edi
1173
        add     dword [ebx+file_handle_zip.start], esi
1174
        adc     dword [ebx+file_handle_zip.start+4], edi
1175
        mov     dword [ebx+file_handle_zip.posc], edi
1176
        mov     dword [ebx+file_handle_zip.posc+4], edi
1177
        mov     eax, [ebx+file_handle_zip.cur_disk]
1178
        cmp     eax, [ebx+file_handle_zip.start_disk]
1179
        jz      @f
1180
        mov     [ebx+file_handle_zip.start_disk], eax
1181
        mov     dword [ebx+file_handle_zip.start], esi
1182
        mov     dword [ebx+file_handle_zip.start+4], edi
1183
@@:
1184
        ret
1185
 
1186
; unsigned __stdcall read(HANDLE hFile, void* buf, unsigned size);
1187
read_zip:
1188
        mov     [_esp], esp
1189
        mov     [_ebp], ebp
1190
        mov     [error_proc], .error
1191
        mov     [clear_proc], .clear
1192
        cmp     [ebx+file_handle_zip.bError], 0
1193
        jnz     .reterr
1194
        mov     edi, [esp+8]
1195
        mov     ecx, [esp+12]
1196
        mov     esi, [ebx+file_handle_zip.item]
1197
        mov     edx, dword [esi+file_in_zip.uncompressed_size]
1198
        mov     esi, dword [esi+file_in_zip.uncompressed_size+4]
1199
        sub     edx, dword [ebx+file_handle_zip.pos]
1200
        sbb     esi, dword [ebx+file_handle_zip.pos+4]
1201
        jnz     @f
1202
        cmp     edx, ecx
1203
        jae     @f
1204
        mov     ecx, edx
1205
@@:
1206
        jecxz   .done
1207
        mov     eax, [ebx+file_handle_zip.decoder]
1208
        test    eax, eax
1209
        jnz     .notcopy
1210
        call    zip.read
1211
        jmp     .done
1212
.notcopy:
1213
        mov     dword [eax+streamInfo.fullSize], ecx
1214
        and     dword [eax+streamInfo.fullSize+4], 0
1215
        call    read_7z_to_buf
1216
.done:
1217
        sub     edi, [esp+8]
1218
        mov     eax, edi
1219
        add     dword [ebx+file_handle_zip.pos], eax
1220
        adc     dword [ebx+file_handle_zip.pos+4], 0
1221
.ret:
1222
        ret     12
1223
 
1224
.error:
1225
        push    ContinueBtn
1226
        push    1
1227
        push    aArchiveDataError_ptr
1228
        push    1
1229
        call    [SayErr]
1230
.clear:
1231
        mov     ebx, [esp+4]
1232
        mov     [ebx+file_handle_zip.bError], 1
1233
.reterr:
1234
        or      eax, -1
1235
        ret     12
1236
 
1237
zipin.fillBuf:
1238
        mov     ebx, [eax+streamInfo.size]
1239
        call    zip.read
1240
        popad
1241
        ret
1242
 
1243
; void __stdcall setpos(HANDLE hFile, __int64 pos);
1244
setpos_zip:
1245
        mov     [_esp], esp
1246
        mov     [_ebp], ebp
1247
        mov     [error_proc], read_zip.error
1248
        mov     [clear_proc], read_zip.clear
1249
        cmp     [ebx+file_handle_zip.decoder], 0
1250
        jnz     .notcopy
1251
        mov     esi, [esp+8]
1252
        mov     edi, [esp+12]
1253
        call    zip.setpos
1254
        mov     dword [ebx+file_handle_zip.pos], esi
1255
        mov     dword [ebx+file_handle_zip.pos+4], edi
1256
        ret     12
1257
.notcopy:
1258
        cmp     [ebx+file_handle_zip.bError], 0
1259
        jnz     .backward
1260
        mov     ecx, [esp+8]
1261
        mov     edx, [esp+12]
1262
        sub     ecx, dword [ebx+file_handle_zip.pos]
1263
        sbb     edx, dword [ebx+file_handle_zip.pos+4]
1264
        jb      .backward
1265
        mov     eax, [ebx+file_handle_zip.decoder]
1266
        mov     dword [eax+streamInfo.fullSize], ecx
1267
        mov     dword [eax+streamInfo.fullSize+4], edx
1268
        call    skip_7z
1269
        add     dword [ebx+file_handle_zip.pos], ecx
1270
        adc     dword [ebx+file_handle_zip.pos+4], edx
1271
        ret     12
1272
.backward:
1273
        xor     eax, eax
1274
        mov     [ebx+file_handle_zip.bError], al
1275
        mov     dword [ebx+file_handle_zip.pos], eax
1276
        mov     dword [ebx+file_handle_zip.pos+4], eax
1277
        mov     dword [ebx+file_handle_zip.posc], eax
1278
        mov     dword [ebx+file_handle_zip.posc+4], eax
1279
        mov     dword [ebx+file_handle_zip.cur_disk_start], eax
1280
        mov     dword [ebx+file_handle_zip.cur_disk_start+4], eax
1281
        lea     esi, [ebx+file_handle_zip.saved_keys]
1282
        lea     edi, [ebx+file_handle_zip.keys]
1283
        movsd
1284
        movsd
1285
        movsd
1286
        mov     eax, [ebx+file_handle_zip.start_disk]
1287
        mov     [ebx+file_handle_zip.cur_disk], eax
1288
        mov     eax, [ebx+file_handle_zip.decoder]
1289
        mov     eax, [eax+deflate_decoder.inStream]
1290
        mov     esi, [ebx+file_handle_zip.item]
1291
        mov     ecx, dword [esi+file_in_zip.compressed_size]
1292
        mov     dword [eax+streamInfo.fullSize], ecx
1293
        mov     ecx, dword [esi+file_in_zip.compressed_size+4]
1294
        mov     dword [eax+streamInfo.fullSize+4], ecx
1295
        and     [eax+streamInfo.bufDataLen], 0
1296
        lea     ebp, [eax+streamInfo.size+4]
1297
        add     ebp, [eax+streamInfo.bufSize]
1298
        and     [ebp+streamInfo.bufDataLen], 0
1299
        call    deflate_init_decoder
1300
        cmp     [esi+file_in_zip.method], 9
1301
        setz    [ebp+deflate_decoder.bDeflate64]
1302
        mov     eax, [esp+8]
1303
        mov     dword [ebp+streamInfo.fullSize], eax
1304
        mov     eax, [esp+12]
1305
        mov     dword [ebp+streamInfo.fullSize+4], eax
1306
        mov     eax, ebp
1307
        call    skip_7z
1308
        mov     eax, [esp+8]
1309
        mov     dword [ebx+file_handle_zip.pos], eax
1310
        mov     eax, [esp+12]
1311
        mov     dword [ebx+file_handle_zip.pos+4], eax
1312
        ret     12