-
Notifications
You must be signed in to change notification settings - Fork 3
/
cZipArchive.cls
2399 lines (2251 loc) · 110 KB
/
cZipArchive.cls
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
Persistable = 0 'NotPersistable
DataBindingBehavior = 0 'vbNone
DataSourceBehavior = 0 'vbNone
MTSTransactionMode = 0 'NotAnMTSObject
END
Attribute VB_Name = "cZipArchive"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
'=========================================================================
'
' cZipArchive (c) 2017-2019 by [email protected]
'
' A single-class pure VB6 library for zip archives management
'
'=========================================================================
Option Explicit
DefObj A-Z
Private Const MODULE_NAME As String = "cZipArchive"
#Const ImplCompress = ZIP_NOCOMPRESS = 0
#Const ImplDecompress = ZIP_NOEXTRACT = 0
#Const ImplCrypto = ZIP_CRYPTO <> 0
#Const ImplUseShared = ZIP_USESHARED <> 0
#Const ImplInflate = ZIP_INFLATE <> 0
#Const ImplLogging = DEBUG_MODE
'=========================================================================
' Public events
'=========================================================================
Event Progress(ByVal FileIdx As Long, ByVal Current As Long, ByVal Total As Long, Cancel As Boolean)
Event Error(ByVal FileIdx As Long, Source As String, Description As String, Cancel As Boolean)
#If ImplCompress Then
Event BeforeCompress(ByVal FileIdx As Long, Level As Long, SkipFile As Boolean, Cancel As Boolean)
#End If ' ImplCompress
#If ImplDecompress Then
Event BeforeExtract(ByVal FileIdx As Long, File As Variant, SkipFile As Boolean, Cancel As Boolean)
Event ExtractComplete(ByVal FileIdx As Long, File As Variant)
#End If ' ImplDecompress
'=========================================================================
' Thunk data
'=========================================================================
' Auto-generated on 12.1.2018 17:15:52, CodeSize=6640, DataSize=984, ALIGN_SIZE=16
Private Const STR_THUNK1 As String = _
"UYtEJAhTi1wkEFWLbCQYVleLeEQD64tEJCSJbCQQiwD2wwN0HDvddBQPthNDD7bIM9HB6AgzBJf2wwN16IlcJByL1cdEJBgAAAAAK9OD4vyNDBqDwgPB6gI7yxvJ99EjyolMJCB0eYvpjaQkAAAAAIsbi8vB6QgPtvGLyMHpCA+2yTPxi8vB6RAPttGLyMHpEIu0twAIAAAPtskz0YvIwekYM7SXAAQAAIvTweoYM9EPtsgPtsOLXCQcM8iDwwQzNJeJXCQcM7SPAAwAAItMJBiLxkGJTCQYO811lItsJBCLzTP2K8s76xvt99Uj6XQWD7YTjVsBD7bIRjPRwegIMwSXO/V16otMJCRfXl2JAVtZwhAAzMzMzMzMzMzMzMzMVot0JBCF9n41i1QkDE6LRCQIwe4ERoMCAYsKdQP/QgSJCItKBIlIBMdACAAAAADHQAwAAAAAg8AQg+4BddhewhAAzMzMzMzMzMzMzMzMzMyLVCQMhdJ0GotEJAhWi3Qk" & _
"CCvwigwGjUABMEj/g+oBdfJewhAAzMzMzMzMzMzMzMyDfCQMAItEJASLSAyJTCQED46OAAAAU1VWi3QkFFeLfCQgi++D5QGD5wKNmwAAAACKHoXtdBWLSAiDyQKL0YPyAQ+v0cHqCDLTiBaF/3QCih4PthBGD7bLi1wkFDPRiwjB6QiLFJOLWAgz0Q+2ygNIBGnJBYQICIkQD7bTwesIQYlIBA+2SAcz0YtMJBQzHJGLTCQcSYlYCIlMJByFyX+QX15dW8IQAMzMzMzMzMzMzFaLdCQIV2oMi0Yo/9CL+FeJN+gJCQAAi04oahT/0cdAEAAAAADHQAwAAAAAiUcIi8dfXsIQAMzMzMzMzMzMzMxWi3QkCFeLPv92CItHMP/Q/3YEi0cw/9CLRzBW/9BfXsIQAMzMzMzMzMzMzMzMzMyLRCQMVot0JAxXi3wkDIXAdA1Q/3YE/zb/N+gh/f///3YcjUYM/3YY/3YU/3YQUI1GCFD/dgT/NlfoIgkAAF9e" & _
"whAAzMzMzMzMzMzMzMzMzP90JATo5w8AAMIQAMzMzMxWi3QkCItODI1GDFeLPoXJdAw7TgR0B1BW6IIRAACLThCNRhCFyXQMO04IdAdQVuhsEQAAg34UAI1GFHQHUFboXBEAAI1GBFBW6FIRAACNRghQVuhIEQAAi0cwVv/QX17CEADMzMzMzMzMzMzMzMzMi0QkCFNVi2wkDFZXjVgMU414CFf/cAT/MFXoIQkAAItMJByL8IXJdBiF9nQUiweFwHQMUf8zUP91AOgx/P//i8ZfXl1bwhAAzMzMzMzMzMxWi3QkCIPK/4uGBIAEAA+3TMYCjQTGZjvKdAkPv8FmiRTG6xCLQASD+P90CGaJlEYIgAQAi4YEgAQAi0wkEIlMxgSLhgSABABmiVTGAo0UTouOBIAEAA+3ggiABABmiQTOi4YEgAQAD78Mxg+3wGaJggiABACD+f90DGaLhgSABABmiUTOAouOBIAEAIpEJAyIhA4AAAQAi4YEgAQAQCX/" & _
"fwAAiYYEgAQAXsIMAMzMzIPsDFNVi2wkIFZXi3wkIDP2i38EiXwkGDm3DIAGAA+O4gAAAIuPDIAGAIvBK8YDxYP4BA+MnAAAAItUJCQ78X0KD7aEPgiABgDrCIvGK8EPtgQQjV4CiEQkFI1D/zvBfQoPtoQ+CYAGAOsJi8YrwQ+2RBABiEQkFTvZfQoPtoQ+CoAGAOsJi8YrwQ+2RBACiEQkFo1DATvBfQoPtoQ+C4AGAOsJi8YrwQ+2RBADiEQkF4tEJBRpyL2nNR7B6RBRUFfoiv7//0Y7twyABgAPjFH////rMYvOO7cMgAYAfSeNlwiABgDrCY2kJAAAAACL/4qEDwiABgCNUgGIQv9BO48MgAYAfOoptwyABgCF7Q+O9QEAAOsKjaQkAAAAAI1JAItcJCSD/QQPjFkBAACLhwAABAAz7YmHAIAEAGkDvac1HsHoEA+/lEcIgAQAg/r/D4QxAQAAi48EgAQAi8Irwb4AgAAAJf9/AAAr8CvOgeH/" & _
"fwAAi4Q5AAAEADsDdQ6JtK8QgAYARTtsJCx9CQ+/FNeD+v91wIXtD47pAAAAi0QkKDlEJDB+BolEJDDrBItEJDC+BAAAADvGfnGNmwAAAACKBB4zyTPbiEQkE4XtfliQi5SPEIAGAIvGK8J5GIuHBIAEACvCA8Yl/38AAIqEOAAABADrC4t8JCSKBDiLfCQYOEQkE3UIiZSfEIAGAENBO818vYP7AX4Pi0QkMEaL64tcJCQ78HyZi1wkJItsJCg79X09i5cQgAYAi84ryo0sGoXJeRiLhwSABAArwgPGJf9/AACKhDgAAAQA6wOKBBk4BCl1CEZBO3QkKHzUi2wkKFb/txCABgD/dCQo6KAOAACF9n596ziLTCQgigM8j4sRi3EID7bIi0I8dwkPtkQIMGoI6w0PtgQIagmNBEUBAAAAUFZS6EcSAAC+AQAAAItsJCiD/QR8FmkDvac1HsHoEFAPtgNQV+h1/P//6xWLjwyABgCKA4iEDwiABgD/hwyA" & _
"BgBOQ02F9n/JiWwkKIlcJCSF7Q+PF/7//19eXVuDxAzCFADMzMzMzMzMzMzMzMzMg+wUU1WLbCQoVleLfCQoM/aLfwSJfCQgObcMgAYAD47iAAAAi48MgAYAi8ErxgPFg/gED4ycAAAAi1QkLDvxfQoPtoQ+CIAGAOsIi8YrwQ+2BBCNXgKIRCQYjUP/O8F9Cg+2hD4JgAYA6wmLxivBD7ZEEAGIRCQZO9l9Cg+2hD4KgAYA6wmLxivBD7ZEEAKIRCQajUMBO8F9Cg+2hD4LgAYA6wmLxivBD7ZEEAOIRCQbi0QkGGnIvac1HsHpEFFQV+hq+///Rju3DIAGAA+MUf///+sxi847twyABgB9J42XCIAGAOsJjaQkAAAAAIv/ioQPCIAGAI1SAYhC/0E7jwyABgB86im3DIAGADPAM8mJRCQUiUwkGIlEJByF7Q+OCQIAAOsKjaQkAAAAAI1JAItcJCyD/QQPjMABAACLhwAABAAz7YmHAIAEAGkDvac1" & _
"HsHoEA+/lEcIgAQAg/r/D4SYAQAAi48EgAQAi8Irwb4AgAAAJf9/AAAr8CvOgeH/fwAAi4Q5AAAEADsDdQ6JtK8QgAYARTtsJDR9CQ+/FNeD+v91wIXtD45MAQAAi1QkMItEJDg7wn4Gi8KJRCQ4vgQAAAA7xn53igQeM8kz24hEJBOF7X5g6weNpCQAAAAAi5SPEIAGAIvGK8J5GIuHBIAEACvCA8Yl/38AAIqEOAAABADrC4t8JCyKBDiLfCQgOEQkE3UIiZSfEIAGAENBO818vYP7AX4Pi0QkOEaL64tcJCw78HyRi1wkLItUJDA78n05i5cQgAYAi84ryo0sGoXJeRiLhwSABAArwgPGJf9/AACKhDgAAAQA6wOKBBk4BCl1CEZBO3QkMHzUi2wkFIXtfl6NRQE78H5Pi0QkKIsQi2gIi0QkHDyPD7bIi0I8dwkPtkQIMGoI6w0PtgQIagmNBEUBAAAAUFVS6CAPAAAPtgOLjxCABgCJTCQYiXQk" & _
"FIlEJBzpkAAAAItEJBhVUOsli4cQgAYAiUQkGA+2A4l0JBSJRCQc63GLTCQYi2wkFIXtfjJVUf90JDDo8AoAADPAjXX/iUQkFIX2f1KLbCQwi0wkGIXtD48D/v//X15dW4PEFMIUAItMJCiKAzyPixGLcQgPtsiLQjx3CQ+2RAgwagjrDQ+2BAhqCY0ERQEAAABQVlLodg4AAL4BAAAAi2wkMIP9BHwWaQO9pzUewegQUA+2A1BX6KT4///rFYuPDIAGAIoDiIQPCIAGAP+HDIAGAE5DTYX2f8mJbCQwiVwkLOlq////zMzMzMzMzMzMVleLfCQMaLCPBgCLB4tAKP/Qi/CF9nUFX17CBACJdwSNTgK6AIAAAIPI/+sDjUkAx0EC/////41JCGaJQfhmiUH2g+oBdemNvgiABAC5AIAAAPOrX4mWBIAEAI1CAYmWDIAGAF7CBADMzMzMzMzMzFZXi3wkDLkSAAAAvgBQ51W4kCnnVfOli0wkEIPAYF9e" & _
"xwEAEOdViUEEx0EIoEDnVcdBDHhE51XCCADMzMzMzMxTi1wkCFZXaACAAACLO4tzCItHKP/QiQYzwDlEJCRqAw+VwMdGCACAAACDwALHRgQAAAAAUFZX6DQNAACDfCQoAP90JDD/dCQw/3QkIP90JCBTdAfoF/j//+sF6DD7//9qB2oAVlfoBQ0AAIN8JCQAdBiLThCFyXQRuAgAAAArwVBqAFZX6OYMAACLRCQciw5fiQiLRCQci04EXluJCLgBAAAAwiQAzMzMzMzMzMzMzFFTVVaLdCQUV2gAgAAAix6JXCQci0Mo/9CLbCQgiYakgQAAx4asgQAAAIAAAMeGqIEAAAAAAACF7X8Ng76cAQAAAA+OtgUAAIO+nAEAABiNvpwBAAB9KotUJBzrA41JAIXtfhkPtgJNiw9C0+AJhpgBAACNQQiJB4P4GHzjiVQkHItGGIXAdQnHRhgBAAAA66aD+AF1c4sXg/oDD4xdBQAAi4aYAQAAg8L90eiLyIkX" & _
"wegCiYaYAQAAg+EDdR2LysdGGAoAAACD4Qcr0dPoiReJhpgBAADpXP///4P5AXUYi0YEiUYMi0YIiUYQx0YYBgAAAOk/////g/kCD4U2////iU4Y6S7///+D+AJ1bosXg/oOD4zlBAAAi46YAQAAi8GD4B/B6QUFAQEAAMdGLAAAAACJRiCLwYPgH8HpBUDHRhgDAAAAiUYki8GD4A/B6QSDwASJjpgBAACJRiiNQvKJBzPAiUZEiUZIiUZMiUZQZolGVIhGVum7/v//g/gDdW85Bw+MdQQAAItGLDtGKH0xgz8DfCyLS0CLRiyKlpgBAACA4gcPtgQBiFQwRP9GLItGLIMH/cGumAEAAAM7Rih8z4tGLDtGKA+Faf7//2oTjUZEUFboxgkAAIlGFMdGGAQAAADHRiwAAAAA6Uf+//+D+AQPheIAAACLRiSLTiADwTlGLHw/UY1GV1BW6I8JAAD/diSJRgyLRiCDwFcDxlBW6HoJAACNfhSJRhBXVui9"
Private Const STR_THUNK2 As String = _
"BQAAxwcAAAAAx0YYBgAAAOny/f///3YUjYaYAQAAV1DoGwYAAIvIg/n/D4SeAwAAg/n+D4RiAwAAg/kQfQ+LRiyITDBX/0Ys6br9//91B7gCAAAA6w8zwIP5EQ+VwI0EhQMAAACJRjAzwIP5Eg+UwI0ExQMAAACJRjSD+RB1G4tGLIXAfhQPtkQwVolGPMdGGAUAAADpbf3//zPAx0YYBQAAAIlGPOlc/f//g/gFdVyLH4tOMDvZD4wRAwAAi4aYAQAAugEAAADT4ivZSokfI9DT6ANWNImGmAEAAIXSfhyLRiQDRiCLTiw7yH0PikY8SohEMVf/RiyF0n/ki1wkGMdGGAQAAADp+/z//4P4Bg+FnAAAAP92DI1eDFeNhpgBAABQ6BgFAACD+P8PhJ0CAACD+P4PhF0CAAA9AAEAAH0QUFboCAQAAItcJBjptvz//3VAiwPHRhgBAAAAO0YEdA1TVuhYBAAAxwMAAAAAi0YQjX4Qi1wkGDtGCA+Ehvz/" & _
"/1dW6DgEAADHBwAAAADpdPz//4tcJBg9HgEAAA+NZfz//8dGGAcAAACJRhzpVvz//4P4B3VUi0YcLQEBAACNDECLQzSNHIgPv0sCOQ8PjPsBAACLlpgBAAC4AQAAANPgSCPCA0MEiUY4D79DAikHiksCi1wkGNPqiZaYAQAAx0YYCAAAAOn9+///g/gIdTr/dhCNhpgBAABXUOghBAAAg/j/D4SmAQAAg/j+D4RqAQAAg/geD41hAQAAx0YYCQAAAIlGHOm++///g/gJD4WPAAAAi0YcixeNDECLQziNBIgPv0gCiUQkIIlMJBA70Q+MWgEAAIuGmAEAALsBAAAAK1QkENPji0wkIEsj2ANZBIkXikkC0+iDfjgAiYaYAQAAx0YYBgAAAHQsjaQkAAAAAIuGoIEAAP9OOCvDJf9/AAAPtoQwoAEAAFBW6IECAACDfjgAddv/TjiLXCQY6Sb7//+D+Ap1MYsXg/oQD4zdAAAAi46YAQAAD7fBiUZAjULw" & _
"wekQiQeJjpgBAADHRhgLAAAA6fD6//+D+At1P4sHg/gQD4ynAAAAi46YAQAAg8DwD7fRiQeB8v//AACLRkDB6RCJjpgBAAA7wnVQ99gbwIPgC0CJRhjprPr//4P4DA+Fo/r//4M/CHxlD7aGmAEAAFBW6NkBAACDB/jBrpgBAAAIg0ZA/w+FfPr//8dGGAEAAADpcPr//4tcJBj/tqSBAACLQzD/0ItEJCTHhqSBAAAAAAAAX17HAAAAAACLRCQgXVvHAAAAAAAzwFnCFACLTCQkuAEAAACLlqSBAABfiRGLlqiBAACLTCQkXl1biRFZwhQAzMzMzMzMzMzMzMzMzIHsIAEAAFNWi7QkLAEAAFdosIEAAItGKP/Qi9iNfCQMuAgICAi5JAAAAGggAQAAiTPzq7gJCQkJjbwkoAAAALkcAAAA86uNRCQQx4QkEAEAAAcHBwdQU8eEJBwBAAAHBwcHx4QkIAEAAAcHBwfHhCQkAQAABwcHB8eEJCgBAAAH" & _
"BwcHx4QkLAEAAAcHBwfHhCQwAQAACAgICMeEJDQBAAAICAgI6McEAACJQwSNRCQMaiBQU8dEJBgFBQUFx0QkHAUFBQXHRCQgBQUFBcdEJCQFBQUFx0QkKAUFBQXHRCQsBQUFBcdEJDAFBQUFx0QkNAUFBQXodwQAAF+JQwiLw17HQxgAAAAAx0MUAAAAAMdDEAAAAADHQwwAAAAAx4OYAQAAAAAAAMeDnAEAAAAAAADHg6CBAAAAAAAAW4HEIAEAAMIEAMzMzMzMzMzMzMzMzFOLXCQMVot0JAyLhqCBAACLDoicMKABAACLhqCBAABAJf9/AACJhqCBAACLhqiBAAA7hqyBAAB8GgPAUP+2pIEAAImGrIEAAItBLP/QiYakgQAAi4aogQAAi46kgQAAiBwB/4aogQAAXlvCCADMzMxTi1wkCFWLbCQQiwOJRCQMhe11CF2DyP9bwggAV4t9AIX/dEtWM/Y5N3wj6wONSQCLRwSNBPCDwASDOAB0B1BT" & _
"6Lv///9GOzd+5otEJBT/dwSLQDD/0ItEJBTHRwQAAAAAV4tAMP/Qx0UAAAAAAF5fXTPAW8IIAMzMzMzMzMzMzItEJAxTi1wkDFaLCItABIszV4t8JBCLFyPKjQTID7YIO85/Jg+2CNPqK/Fmg3gC/3Usi0AEhcB0GosIi0AEI8qNBMgPtgg7zn7aX16DyP9bwgwAX164/v///1vCDACJF4kzD79AAl9eW8IMAMzMzMyD7AiLRCQMVYsoi0AIiUQkEItEJBiJbCQEhcAPji0BAABTVlc9BAEAAH4HvgIBAADrDIvwPQIBAAB+A41w/SvGux0AAACJRCQkg8//i0U0i+iJRCQUjQQ7mSvC0fiNDEA7dI0EfQSL2OvrO3SNCH4Ei/jr4YtcJByNBECNPIUAAAAAuRcBAAAPtwQvA/2LbCQQZjvBD7/Ii0U8fwwPtoRIAP7//2oH6wcPtkQBqGoIUFNV6CkDAAAPt0cCZoXAdA0rdwSYUFZTVegTAwAAi0U4" & _
"g87/i1wkIL8eAAAAi+iL/40EN5krwtH4jQxAO1yNBH0Ei/jr6ztcjQh+BIvw6+GLfCQcjQRAjTSFAAAAAAP1i2wkEGoFD78Oi0U8D7YEyFBXVei5AgAAD7dGAmaFwHQPmFCLwytGBFBXVeihAgAAi0QkJIXAD4/Z/v//X15bXYPECMIMAMzMzMzMzMzMzMzMU1WLbCQMVldqCItFKP/Qi1wkKIv4i8u4AQAAANPgvgEAAACLTCQsSNPmiUQkKI0E9QAAAABQi0Uo/9CJRwQzyY1G/4PK/4kHhcB4I41kJACLRwRmiVTIAotHBMYEyACLRwTHRMgEAAAAAEE7D37hM+05bCQgfmmLdCQc6wONSQAPtgQuO8N+UYtEJBiLBKiLyCNMJCg7TCQkdT6Ly9P4Iwc7B380i08EZolswQKLTwQPthQuK9ONNMEPtg47yn0CiBaLdCQcugEAAAAPtgwuK8vT4gPCOwd+zEU7bCQgfKAz9jk3fGeLVCQsi2wkHIv/" & _
"i0cEjQzwD7YBO8J+S4PI/2aJQQKLRwSNDPAPtgErwoP4B34FuAcAAABQjQQTiBFQi8uLxtPgC0QkLFD/dCQsVf90JCz/dCQs6MP+//+LTwSLVCQsiUTxBEY7N36ji8dfXl1bwhwAzMzMzMzMzMzMzIHsBAUAADPAM9JVi6wkFAUAAIlUJASJRCQMiUQkEIlEJBSJRCQYiUQkHIlEJCCJRCQkiUQkKIlEJCyJRCQwiUQkNIlEJDiJRCQ8iUQkQIlEJERWi7QkFAUAAIXtfhmL/w+2DDD/RIwMO9F9AovRQDvFfO2JVCQIM9IzyesDjUkAiVQMUANUDBCDwQQD0oP5PHzuVzP/he1+SVONnCSUAAAAD7Y0N8cDAAAAAItUtFSNQgGJRLRUhfZ0GDPAjWQkAIvKA8CD4QHR+gvBg+4BdfCJA4u0JBwFAABHg8MEO/18wFuLRCQMX4P4CXwFuAkAAABQagBqAFX/tCQkBQAAjYQkoAAAAFCLhCQoBQAA/zDo" & _
"jP3//15dgcQEBQAAwgwAzItEJAxWi3QkDItOENPgCUYMi0QkFAPBiUYQg/gIfDlXi3wkDItGCDlGBHwPA8BQ/zaJRgiLRyz/0IkGi1YEiw6KRgyIBAr/RgTBbgwIg0YQ+IN+EAh9zV9ewhAAVYvsiwCAQMAgoGDgEJBQ0DCwcPAIiEjIKKho6BiYWNg4uHj4BIRExCSkZOQUlFTUNLR09AyMTMwsrGzsHJxc3Dy8fPwCgkLCIqJi4hKSUtIysnLyCopKyiqqauoamlraOrp6+gaGRsYmpmbmFpZW1ja2dvYOjk7OLq5u7h6eXt4+vn7+AYFBwSGhYeERkVHRMbFx8QmJSckpqWnpGZlZ2Tm5efkFhUXFJaVl5RWVVdU1tXX1DY1NzS2tbe0dnV3dPb19/QODQ8Mjo2PjE5NT0zOzc/MLi0vLK6tr6xubW9s7u3v7B4dHxyenZ+cXl1fXN7d39w+PT88vr2/vH59f3z+/f/8BAQAAAwAAAAMAAAACAQAA" & _
"BAAAAAQAAAADAQAABQAAAAUAAAAEAQAABgAAAAYAAAAFAQAABwAAAAcAAAAGAQAACAAAAAgAAAAHAQAACQAAAAkAAAAIAQAACgAAAAoAAAAJAQEACwAAAAwAAAAKAQEADQAAAA4AAAALAQEADwAAABAAAAAMAQEAEQAAABIAAAANAQIAEwAAABYAAAAOAQIAFwAAABoAAAAPAQIAGwAAAB4AAAAQAQIAHwAAACIAAAARAQMAIwAAACoAAAASAQMAKwAAADIAAAATAQMAMwAAADoAAAAUAQMAOwAAAEIAAAAVAQQAQwAAAFIAAAAWAQQAUwAAAGIAAAAXAQQAYwAAAHIAAAAYAQQAcwAAAIIAAAAZAQUAgwAAAKIAAAAaAQUAowAAAMIAAAAbAQUAwwAAAOIAAAAcAQUA4wAAAAEBAAAdAQAAAgEAAAIBAAAQERIACAcJBgoFCwQMAw0CDgEPAAAAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAADAAAA" & _
"AwAAAAMAAAAEAAAABAAAAAQAAQAFAAAABgAAAAUAAQAHAAAACAAAAAYAAgAJAAAADAAAAAcAAgANAAAAEAAAAAgAAwARAAAAGAAAAAkAAwAZAAAAIAAAAAoABAAhAAAAMAAAAAsABAAxAAAAQAAAAAwABQBBAAAAYAAAAA0ABQBhAAAAgAAAAA4ABgCBAAAAwAAAAA8ABgDBAAAAAAEAABAABwABAQAAgAEAABEABwCBAQAAAAIAABIACAABAgAAAAMAABMACAABAwAAAAQAABQACQABBAAAAAYAABUACQABBgAAAAgAABYACgABCAAAAAwAABcACgABDAAAABAAABgACwABEAAAABgAABkACwABGAAAACAAABoADAABIAAAADAAABsADAABMAAAAEAAABwADQABQAAAAGAAAB0ADQABYAAAAIAAAA=="
Private Const STR_THUNK_OFFSETS As String = "592|656|704|784|800|912|0|288|368|416|0|0|0|6896|7264|6640|7244"
Private Const STR_THUNK_BUILDDATE As String = "12.1.2018 17:15:52"
' end of generated code
'=========================================================================
' API
'=========================================================================
Private Const VT_BYREF As Long = &H4000
'--- for FindFirstFile
Private Const MAX_PATH As Long = 260
Private Const INVALID_HANDLE_VALUE As Long = -1
'--- for CreateFile
Private Const CREATE_ALWAYS As Long = 2
Private Const OPEN_EXISTING As Long = &H3
Private Const GENERIC_WRITE As Long = &H40000000
Private Const GENERIC_READ As Long = &H80000000
Private Const FILE_SHARE_READ As Long = &H1
Private Const FILE_SHARE_WRITE As Long = &H2
'--- for VirtualAlloc
Private Const PAGE_EXECUTE_READWRITE As Long = &H40
Private Const MEM_COMMIT As Long = &H1000
'--- for SetFilePointer
Private Const FILE_BEGIN As Long = 0
Private Const FILE_CURRENT As Long = 1
Private Const FILE_END As Long = 2
'--- for MultiByteToWideChar
Private Const CP_UTF8 As Long = 65001
Private Const CP_OEMCP As Long = 1
'--- for FormatMessage
Private Const FORMAT_MESSAGE_FROM_SYSTEM As Long = &H1000
Private Const FORMAT_MESSAGE_IGNORE_INSERTS As Long = &H200
'--- for SetFilePointer
Private Const INVALID_SET_FILE_POINTER As Long = -1
'--- for CryptBinaryToString/CryptStringToBinary
Private Const CRYPT_STRING_BASE64 As Long = 1
'--- for CNG
Private Const MS_PRIMITIVE_PROVIDER As String = "Microsoft Primitive Provider"
Private Const BCRYPT_SHA1_ALGORITHM As String = "SHA1"
Private Const BCRYPT_AES_ALGORITHM As String = "AES"
Private Const BCRYPT_HASH_LENGTH As String = "HashDigestLength"
Private Const BCRYPT_OBJECT_LENGTH As String = "ObjectLength"
Private Const BCRYPT_CHAINING_MODE As String = "ChainingMode"
Private Const BCRYPT_CHAIN_MODE_ECB As String = "ChainingModeECB"
Private Const BCRYPT_ALG_HANDLE_HMAC_FLAG As Long = 8
'--- for GetStdHandle
Private Const STD_INPUT_HANDLE As Long = -10&
Private Const STD_OUTPUT_HANDLE As Long = -11&
Private Const STD_ERROR_HANDLE As Long = -12&
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileW" (ByVal lpFileName As Long, ByVal lpFindFileData As Long) As Long
Private Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Long) As Long
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileW" (ByVal lpFileName As Long, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal NoSecurity As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, ByVal lpOverlapped As Long) As Long
Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, ByVal lpOverlapped As Long) As Long
Private Declare Function SetFilePointer Lib "kernel32" (ByVal hFile As Long, ByVal lDistanceToMove As Long, ByVal lpDistanceToMoveHigh As Long, ByVal dwMoveMethod As Long) As Long
Private Declare Function SetEndOfFile Lib "kernel32" (ByVal hFile As Long) As Long
Private Declare Function FileTimeToSystemTime Lib "kernel32" (lpFileTime As FILETIME, lpSystemTime As SYSTEMTIME) As Long
Private Declare Function SystemTimeToFileTime Lib "kernel32" (lpSystemTime As SYSTEMTIME, lpFileTime As FILETIME) As Long
Private Declare Function FileTimeToLocalFileTime Lib "kernel32" (lpFileTime As Any, lpLocalFileTime As FILETIME) As Long
Private Declare Function LocalFileTimeToFileTime Lib "kernel32" (lpLocalFileTime As FILETIME, lpFileTime As FILETIME) As Long
Private Declare Function VirtualAlloc Lib "kernel32" (ByVal lpAddress As Long, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long
Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, Optional ByVal Msg As Long, Optional ByVal wParam As Long, Optional ByVal lParam As Long) As Long
Private Declare Sub CoTaskMemFree Lib "ole32" (ByVal pv As Long)
Private Declare Function MultiByteToWideChar Lib "kernel32" (ByVal CodePage As Long, ByVal dwFlags As Long, lpMultiByteStr As Any, ByVal cbMultiByte As Long, lpWideCharStr As Any, ByVal cchWideChar As Long) As Long
Private Declare Function WideCharToMultiByte Lib "kernel32" (ByVal CodePage As Long, ByVal dwFlags As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long, ByVal lpMultiByteStr As Long, ByVal cchMultiByte As Long, ByVal lpDefaultChar As Long, ByVal lpUsedDefaultChar As Long) As Long
Private Declare Function GetStdHandle Lib "kernel32" (ByVal nStdHandle As Long) As Long
#If ImplCompress Then
Private Declare Function FileTimeToDosDateTime Lib "kernel32" (lpFileTime As FILETIME, ByVal lpFatDate As Long, ByVal lpFatTime As Long) As Long
Private Declare Function ApiEmptyByteArray Lib "oleaut32" Alias "SafeArrayCreateVector" (Optional ByVal VarType As VbVarType = vbByte, Optional ByVal Low As Long = 0, Optional ByVal Count As Long = 0) As Byte()
Private Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileW" (ByVal hFindFile As Long, ByVal lpFindFileData As Long) As Long
#End If ' ImplCompress
#If ImplDecompress Then
Private Declare Function DosDateTimeToFileTime Lib "kernel32" (ByVal wFatDate As Long, ByVal wFatTime As Long, lpFileTime As FILETIME) As Long
#End If ' ImplDecompress
#If ImplCrypto Then
Private Declare Function CoCreateGuid Lib "ole32" (pguid As Any) As Long
Private Declare Function BCryptOpenAlgorithmProvider Lib "bcrypt" (phAlgorithm As Long, ByVal pszAlgId As Long, ByVal pszImplementation As Long, ByVal dwFlags As Long) As Long
Private Declare Function BCryptCloseAlgorithmProvider Lib "bcrypt" (ByVal hAlgorithm As Long, ByVal dwFlags As Long) As Long
Private Declare Function BCryptGetProperty Lib "bcrypt" (ByVal hObject As Long, ByVal pszProperty As Long, pbOutput As Any, ByVal cbOutput As Long, cbResult As Long, ByVal dwFlags As Long) As Long
Private Declare Function BCryptSetProperty Lib "bcrypt" (ByVal hObject As Long, ByVal pszProperty As Long, ByVal pbInput As Long, ByVal cbInput As Long, ByVal dwFlags As Long) As Long
Private Declare Function BCryptGenerateSymmetricKey Lib "bcrypt" (ByVal hAlgorithm As Long, phKey As Long, pbKeyObject As Any, ByVal cbKeyObject As Long, pbSecret As Any, ByVal cbSecret As Long, ByVal dwFlags As Long) As Long
Private Declare Function BCryptDestroyKey Lib "bcrypt" (ByVal hKey As Long) As Long
Private Declare Function BCryptEncrypt Lib "bcrypt" (ByVal hKey As Long, pbInput As Any, ByVal cbInput As Long, ByVal pPaddingInfo As Long, ByVal pbIV As Long, ByVal cbIV As Long, pbOutput As Any, ByVal cbOutput As Long, pcbResult As Long, ByVal dwFlags As Long) As Long
Private Declare Function BCryptDeriveKeyPBKDF2 Lib "bcrypt" (ByVal pPrf As Long, pbPassword As Any, ByVal cbPassword As Long, pbSalt As Any, ByVal cbSalt As Long, ByVal cIterations As Long, ByVal dwDummy As Long, pbDerivedKey As Any, ByVal cbDerivedKey As Long, ByVal dwFlags As Long) As Long
Private Declare Function BCryptCreateHash Lib "bcrypt" (ByVal hAlgorithm As Long, phHash As Long, ByVal pbHashObject As Long, ByVal cbHashObject As Long, pbSecret As Any, ByVal cbSecret As Long, ByVal dwFlags As Long) As Long
Private Declare Function BCryptDestroyHash Lib "bcrypt" (ByVal hHash As Long) As Long
Private Declare Function BCryptHashData Lib "bcrypt" (ByVal hHash As Long, pbInput As Any, ByVal cbInput As Long, ByVal dwFlags As Long) As Long
Private Declare Function BCryptFinishHash Lib "bcrypt" (ByVal hHash As Long, pbOutput As Any, ByVal cbOutput As Long, ByVal dwFlags As Long) As Long
#End If ' ImplCrypto
#If ImplUseShared = 0 Then
Private Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" (ByVal dwFlags As Long, lpSource As Long, ByVal dwMessageId As Long, ByVal dwLanguageId As Long, ByVal lpBuffer As String, ByVal nSize As Long, Args As Any) As Long
Private Declare Function GetFileAttributes Lib "kernel32" Alias "GetFileAttributesW" (ByVal lpFileName As Long) As Long
Private Declare Function CreateDirectory Lib "kernel32" Alias "CreateDirectoryW" (ByVal lpPathName As Long, ByVal lpSecurityAttributes As Long) As Long
Private Declare Function CryptBinaryToString Lib "crypt32" Alias "CryptBinaryToStringW" (ByVal pbBinary As Long, ByVal cbBinary As Long, ByVal dwFlags As Long, ByVal pszString As Long, ByRef pcchString As Long) As Long
Private Declare Function CryptStringToBinary Lib "crypt32" Alias "CryptStringToBinaryW" (ByVal pszString As Long, ByVal cchString As Long, ByVal dwFlags As Long, ByVal pbBinary As Long, ByRef pcbBinary As Long, ByRef pdwSkip As Long, ByRef pdwFlags As Long) As Long
#End If ' Not ImplUseShared
Private Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type
Private Type SYSTEMTIME
wYear As Integer
wMonth As Integer
wDayOfWeek As Integer
wDay As Integer
wHour As Integer
wMinute As Integer
wSecond As Integer
wMilliseconds As Integer
End Type
Private Type WIN32_FIND_DATA
dwFileAttributes As Long
ftCreationTime As FILETIME
ftLastAccessTime As FILETIME
ftLastWriteTime As FILETIME
nFileSizeHigh As Long
nFileSizeLow As Long
dwReserved0 As Long
dwReserved1 As Long
cFileName As String * MAX_PATH
cAlternate As String * 14
End Type
'=========================================================================
' Constants and member variables
'=========================================================================
Private Const LNG_SIG_LOCAL As Long = &H4034B50
Private Const LNG_SIG_CENTRAL As Long = &H2014B50
Private Const LNG_SIG_END As Long = &H6054B50
Private Const LNG_SIG_DATADESC As Long = &H7064B50
Private Const LNG_LEN_LOCAL As Long = 30
Private Const LNG_LEN_CENTRAL As Long = 46
Private Const LNG_LEN_END As Long = 22
Private Const LNG_VER_DEFAULT As Long = 10
Private Const LNG_VER_DEFLATE As Long = 20
Private Const LNG_VER_ZIP64 As Long = 45
Private Const LNG_METHOD_DEFLATE As Long = 8
Private Const LNG_METHOD_STORE As Long = 0
Private Const LNG_IOBUF_SIZE As Long = 65536
Private Const LNG_METHOD_AES As Long = 99
Private Const LNG_EXTRADATA_AES_HEADER As Integer = &H9901
Private Const LNG_EXTRADATA_AES_VENDOR As Integer = &H4541 '-- "AE"
Private Const LNG_EXTRADATA_AES_SIZE As Long = 11
Private Const LNG_EXTRADATA_AE_2_MAXSIZE As Long = 20
Private Const LNG_ENC_HEADER_SIZE As Long = 12
Private Const LNG_AES_AUTHCODE_SIZE As Long = 10
Private Const LNG_AES_BLOCK_SIZE As Long = 16
Private Const LNG_PIPE_ENDED_ERROR As Long = 109
Private Const ERR_USER_CANCEL As String = "User cancelled"
Private Const ERR_INIT_COMPRESSOR As String = "Cannot init deflate compressor"
Private Const ERR_COMPRESSING As String = "Error compressing"
Private Const ERR_EMPTY_ARCHIVE As String = "Empty archive"
Private Const ERR_INVALID_ARCHIVE As String = "Invalid archive"
Private Const ERR_ARCHIVE_NOT_OPEN As String = "Archive not opened"
Private Const ERR_INVALID_LOCALHDR As String = "Invalid local header"
Private Const ERR_UNSUPPORTED_METHOD As String = "Unsupported compression method %1"
Private Const ERR_INIT_DECOMPRESSOR As String = "Cannot init inflate decompressor"
Private Const ERR_READING_ARCHIVE As String = "Error reading archive"
Private Const ERR_DECOMPRESSING As String = "Error decompressing"
Private Const ERR_CRC_CHECK As String = "CRC check failed"
Private Const ERR_ENTRY_INVALID_SIG As String = "Entry %1 has invalid signature"
Private Const ERR_ENTRY_NO_FILENAME As String = "Entry %1 has no filename"
Private Const ERR_MISSING_ECD_RECORD As String = "Missing end-of-central-directory record"
Private Const ERR_UNSUPPORTED_ENCRYPTION As String = "Unsupported encryption"
Private Const ERR_PASSWORD_REQUIRED As String = "Password required"
Private Const ERR_INVALID_PASSWORD As String = "Invalid password"
Private Const ERR_INVALID_AUTHCODE As String = "Invalid authentication code"
Private Const ERR_INVALID_BYTEARRAY As String = "Invalid byte array"
Private Const STR_BUFFER As String = "[buffer]"
Private Const STR_STREAM As String = "[stream]"
Private Const STR_ENTRY As String = "[entry %1]"
Private m_uRtbl As UcsZlibRelocTableType
Private m_sLastError As String
Private m_bCancel As Boolean
Private m_lFileCount As Long
Private m_uFiles() As UcsFileInfo
Private m_lCurrentFile As Long
#If ImplDecompress Then
Private m_sComment As String
Private m_vArchiveFile As Variant
#End If ' ImplDecompress
#If ImplCrypto Then
Private m_uCrypto As UcsZipCryptoType
#End If ' ImplCrypto
Private Type UcsVfsFileType
Handle As Long
Stream As Object
BufferArray As Variant
BufferBase As Long
BufferSize As Long
BufferPtr As Long
Data As WIN32_FIND_DATA
FileName As String
End Type
Private Type UcsZlibRelocTableType
CompressInit As Long
CompressCleanup As Long
CompressBlock As Long
DecompressInit As Long
DecompressCleanup As Long
DecompressBlock As Long
CalcCrc32 As Long
MemNonce As Long
MemXor As Long
ZipCrypt As Long
MallocImpl As Long
ReallocImpl As Long
FreeImpl As Long
LenCodes As Long
DistCodes As Long
MirrorBytes As Long
LenLenMap As Long
Crc32Table As Long
End Type
Private Type UcsZlibBuffersType
InBlock As Long
InLen As Long
OutBlock As Long
OutLen As Long
Final As Long
Greedy As Long
MaxMatch As Long
NiceLen As Long
End Type
Private Enum UcsRelocIndexesEnum
ucsIdx_CompressInit = 0
ucsIdx_CompressCleanup
ucsIdx_CompressBlock
ucsIdx_DecompressInit
ucsIdx_DecompressCleanup
ucsIdx_DecompressBlock
ucsIdx_CalcCrc32
ucsIdx_MemNonce
ucsIdx_MemXor
ucsIdx_ZipCrypt
ucsIdx_MallocImpl
ucsIdx_ReallocImpl
ucsIdx_FreeImpl
ucsIdx_LenCodes
ucsIdx_DistCodes
ucsIdx_MirrorBytes
ucsIdx_LenLenMap
End Enum
Private Enum UcsHeaderFlagsEnum
ucsZcfEncrypted = 2 ^ 0 ' If set, indicates that the file is encrypted
ucsZcfCompressOptionMask = 2 ^ 1 Or 2 ^ 2 ' 0 - normal, 1 - maximum, 2 - fast, 3 - super fast
ucsZcfHasDataDescriptor = 2 ^ 3 ' Values are put in the data descriptor immediately following the compressed data
ucsZcfStrongEncrypted = 2 ^ 6 ' Strong encryption
ucsZcfUseUtf8 = 2 ^ 11 ' Language encoding flag (EFS)
End Enum
Private Type UcsLocalHeaderType
Signature As Long ' Signature
VerExt As Integer ' version needed to extract
Flags As Integer ' encrypt and compression flags
Method As Integer ' compression method
FTime As Integer ' time last modifies, dos format
FDate As Integer ' date last modifies, dos format
'--- padding
Crc32 As Long ' CRC32 for uncompressed file
CSize As Long ' compressed size
USize As Long ' uncompressed size
LenFname As Integer ' Length filename
LenExt As Integer ' Length for extra field
End Type
Private Type UcsCentralHeaderType
Signature As Long ' Signature
VerMade As Integer ' version made by
VerExt As Integer ' version needed to extract
Flags As Integer ' encrypt and compression flags
Method As Integer ' compression method
FTime As Integer ' time last modifies, dos format
FDate As Integer ' date last modifies, dos format
'--- padding
Crc32 As Long ' CRC32 for uncompressed file
CSize As Long ' compressed size
USize As Long ' uncompressed size
LenFname As Integer ' Length filename
LenExt As Integer ' Length for extra field
LenCom As Integer ' Length for comment field
DiskStart As Integer ' start disk number
AttribI As Integer ' internal file attributes
'--- padding
AttribX As Long ' external file attributes
Offset As Long ' relative offset of local header
End Type
Private Type UcsEndHeaderType
Signature As Long ' Signature
DiskNum As Integer ' This disk number
DiskStart As Integer ' Start disk number
Entries As Integer ' Entries on this disk
TotEntr As Integer ' Number of total entries
CenSize As Long ' Size of entire cetral directory
CenOff As Long ' Offset of central on starting disk
LenCom As Integer ' Length of comment field
End Type
Private Type UcsAesExtraDataType
HeaderId As Integer ' Extra field header ID (0x9901)
Size As Integer ' Data size (currently 7, but subject to possible increase in the future)
Version As Integer ' Integer version number specific to the zip vendor
VendorId As Integer ' 2-character vendor ID
Strength As Byte ' Integer mode value indicating AES encryption strength
'--- padding
Method As Integer ' The actual compression method used to compress the file
End Type
Private Type UcsFileInfo
FileName As String
Attributes As Long
Crc32 As Long
Size As Long
CompressedSize As Long
Comment As String
LastModified As Date
Method As Long
Offset As Long
Flags As Long
Extra() As Byte
SourceFile As Variant
Level As Long
#If ImplCrypto Then
Aes As UcsAesExtraDataType
DecDat As Byte
Password As String
#End If ' ImplCrypto
End Type
Private Type UcsZipCryptoType
hPbkdf2Alg As Long
hHmacAlg As Long
hHmacHash As Long
HmacHashLen As Long
hAesAlg As Long
hAesKey As Long
AesKeyObjData() As Byte
AesKeyObjLen As Long
Nonce(0 To 1) As Long
EncrData() As Byte
EncrPos As Long
TradKey(0 To 3) As Long
End Type
'=========================================================================
' Properties
'=========================================================================
Property Get SemVersion() As String
SemVersion = "0.2.7"
End Property
Property Get ThunkBuildDate() As String
ThunkBuildDate = STR_THUNK_BUILDDATE
End Property
Property Get LastError() As String
LastError = m_sLastError
End Property
Property Get FileCount() As Long
FileCount = m_lFileCount
End Property
Property Get FileInfo(ByVal FileIdx As Long) As Variant
If FileIdx >= 0 And FileIdx < m_lFileCount Then
With m_uFiles(FileIdx)
FileInfo = Array(.FileName, .Attributes, .Crc32, .Size, .CompressedSize, .Comment, .LastModified, .Method, .Offset, .Flags)
End With
End If
End Property
#If ImplDecompress Then
Public Property Get Comment() As String
Comment = m_sComment
End Property
#End If ' ImplDecompress
'=========================================================================
' Methods
'=========================================================================
#If ImplCompress Then
Public Function AddFile( _
File As Variant, _
Optional Name As String, _
Optional Comment As String, _
Optional Password As String, _
Optional EncrStrength As Long, _
Optional Level As Long = -1) As Boolean
Const FUNC_NAME As String = "AddFile"
Dim uFile As UcsVfsFileType
On Error GoTo EH
pvSetError
If m_lFileCount = 0 Then
ReDim m_uFiles(0 To 2) As UcsFileInfo
ElseIf m_lFileCount > UBound(m_uFiles) Then
ReDim Preserve m_uFiles(0 To 2 * UBound(m_uFiles)) As UcsFileInfo
End If
uFile = pvVfsOpen(File)
With m_uFiles(m_lFileCount)
If LenB(Name) <> 0 Then
.FileName = Name
Else
.FileName = Mid$(uFile.FileName, InStrRev(uFile.FileName, "\") + 1)
End If
.Size = IIf(Right$(.FileName, 1) = "\", 0, uFile.Data.nFileSizeLow)
.Attributes = IIf(Right$(.FileName, 1) = "\", vbDirectory, uFile.Data.dwFileAttributes)
.Comment = Comment
.LastModified = pvFromFileTime(uFile.Data.ftLastWriteTime)
.Extra = vbNullString
If IsObject(File) Then
'--- remove VT_BYREF if any
Set .SourceFile = C_Obj(File)
Else
.SourceFile = File
End If
.Level = Level
#If ImplCrypto Then
.Password = Password
.Aes.Strength = EncrStrength
#End If
End With
m_lFileCount = m_lFileCount + 1
'--- success
AddFile = True
QH:
On Error Resume Next
pvVfsClose uFile
Exit Function
EH:
pvSetError MODULE_NAME & "." & FUNC_NAME & vbCrLf & Err.Source, Err.Description
Resume QH
End Function
Public Function CompressArchive( _
ArchiveFile As Variant, _
Optional Comment As String, _
Optional ByVal Level As Long = 6, _
Optional ByVal UseUtf8 As VbTriState = vbUseDefault) As Boolean
Const FUNC_NAME As String = "CompressArchive"
Dim baBuffer() As Byte
Dim baNext() As Byte
Dim uArchiveFile As UcsVfsFileType
Dim uLocal As UcsLocalHeaderType
Dim lIdx As Long
Dim uFile As UcsVfsFileType
Dim lSize As Long
Dim lBeginOffset As Long
Dim hCtx As Long
Dim uBuf As UcsZlibBuffersType
Dim lResult As Long
Dim uCentral As UcsCentralHeaderType
Dim uEndHdr As UcsEndHeaderType
Dim lEntries As Long
Dim lComprLevel As Long
Dim bSkip As Boolean
#If ImplCrypto Then
Dim lSaltSize As Long
Dim baSalt() As Byte
Dim nPassVer As Integer
Dim lJdx As Long
Dim uAes As UcsAesExtraDataType
#End If
On Error GoTo EH
pvSetError
m_lCurrentFile = -1
ReDim baBuffer(0 To LNG_IOBUF_SIZE - 1) As Byte
ReDim baNext(0 To LNG_IOBUF_SIZE - 1) As Byte
uArchiveFile = pvVfsCreate(ArchiveFile)
uLocal.Signature = LNG_SIG_LOCAL
uCentral.VerExt = LNG_VER_DEFAULT
For lIdx = 0 To m_lFileCount - 1
m_lCurrentFile = lIdx
With m_uFiles(lIdx)
lComprLevel = IIf(.Level >= 0, .Level, Level)
RaiseEvent BeforeCompress(lIdx, lComprLevel, bSkip, m_bCancel)
If m_bCancel Then
m_sLastError = ERR_USER_CANCEL
GoTo QH
End If
If bSkip Then
GoTo SkipFile
End If
lComprLevel = LimitLong(lComprLevel, 0, 9)
uBuf.Greedy = (lComprLevel <= 4)
uBuf.MaxMatch = At(Array(0, 2, 6, 12, 24, 8, 16, 32, 64, 1000), lComprLevel)
uBuf.NiceLen = At(Array(0, 8, 10, 14, 24, 30, 65, 130, 200, 32768), lComprLevel)
.Offset = pvVfsSeek(uArchiveFile, 0, FILE_CURRENT)
On Error GoTo EH_Continue
uFile = pvVfsOpen(.SourceFile)
pvToDosDateTime .LastModified, uLocal.FDate, uLocal.FTime
uLocal.Method = LNG_METHOD_DEFLATE
uLocal.VerExt = LNG_VER_DEFLATE
uLocal.Crc32 = -1
uLocal.USize = 0
uLocal.CSize = 0
If UseUtf8 = vbUseDefault Then
uLocal.Flags = IIf(pvFromOemString(pvToOemString(.FileName)) <> .FileName, ucsZcfUseUtf8, 0)
Else
uLocal.Flags = IIf(UseUtf8 = vbTrue, ucsZcfUseUtf8, 0)
End If
#If ImplCrypto Then
If LenB(.Password) <> 0 Then
uLocal.Flags = uLocal.Flags Or ucsZcfEncrypted
If .Aes.Strength = 0 Then
uLocal.Flags = uLocal.Flags Or ucsZcfHasDataDescriptor
If Not pvCryptoTradInit(ToUtf8Array(.Password)) Then
Err.Raise vbObjectError, , m_sLastError
End If
'--- encrypt 12-byte random header w/ last byte used for password check
baSalt = pvCryptoAesGetRandomSalt(LNG_ENC_HEADER_SIZE)
Call CopyMemory(baSalt(LNG_ENC_HEADER_SIZE - 1), ByVal UnsignedAdd(VarPtr(uLocal.FDate), -1), 1)
If Not pvCryptoTradCrypt(baSalt) Then
Err.Raise vbObjectError, , m_sLastError
End If
Else
lSaltSize = (.Aes.Strength + 1) * 4
baSalt = pvCryptoAesGetRandomSalt(lSaltSize)
If Not pvCryptoAesInit(ToUtf8Array(.Password), baSalt, lSaltSize * 2, nPassVer) Then
Err.Raise vbObjectError, , m_sLastError
End If
'--- reserve space in extra data for AE-1/2
lJdx = UBound(.Extra) + 1
ReDim Preserve .Extra(0 To lJdx + LNG_EXTRADATA_AES_SIZE - 1) As Byte
End If
End If
#End If
pvOutputLocalHeader uArchiveFile, uLocal, .FileName, .Extra
#If ImplCrypto Then
If LenB(.Password) <> 0 Then
'--- prepend salt/enc_header before file data
pvVfsWrite uArchiveFile, VarPtr(baSalt(0)), UBound(baSalt) + 1
If .Aes.Strength > 0 Then
'--- prepend Password Verification Value for AES
pvVfsWrite uArchiveFile, VarPtr(nPassVer), 2
End If
End If
#End If
lBeginOffset = pvVfsSeek(uArchiveFile, 0, FILE_CURRENT)
If (.Attributes And vbDirectory + vbVolume) = 0 Then
If lComprLevel > 0 Then
hCtx = CallWindowProc(m_uRtbl.CompressInit, VarPtr(m_uRtbl))
If hCtx = 0 Then
Err.Raise vbObjectError, , ERR_INIT_COMPRESSOR
End If
lSize = pvVfsRead(uFile, VarPtr(baNext(0)), LNG_IOBUF_SIZE)
Do
Call CopyMemory(baBuffer(0), baNext(0), lSize)
uBuf.InBlock = VarPtr(baBuffer(0))
uBuf.InLen = lSize
lSize = pvVfsRead(uFile, VarPtr(baNext(0)), LNG_IOBUF_SIZE)
uBuf.Final = (lSize = 0)
lResult = CallWindowProc(m_uRtbl.CompressBlock, hCtx, VarPtr(uBuf), VarPtr(uLocal.Crc32), lComprLevel) '--- level ignored
If lResult = 0 Or uBuf.OutBlock = 0 Then
Err.Raise vbObjectError, , ERR_COMPRESSING
End If
#If ImplCrypto Then
If LenB(.Password) <> 0 Then
If UBound(baBuffer) < uBuf.OutLen Then
ReDim baBuffer(0 To (uBuf.OutLen And -2048) + 2047) As Byte
End If
Call CopyMemory(baBuffer(0), ByVal uBuf.OutBlock, uBuf.OutLen)
If .Aes.Strength = 0 Then
If Not pvCryptoTradCrypt(baBuffer, Size:=uBuf.OutLen) Then
Err.Raise vbObjectError, , m_sLastError
End If
Else
If Not pvCryptoAesCrypt(baBuffer, Size:=uBuf.OutLen, HashAfter:=True) Then
Err.Raise vbObjectError, , m_sLastError
End If
End If
pvVfsWrite uArchiveFile, VarPtr(baBuffer(0)), uBuf.OutLen
Call CoTaskMemFree(uBuf.OutBlock)
uBuf.OutBlock = 0
End If
#End If
If uBuf.OutBlock <> 0 Then
pvVfsWrite uArchiveFile, uBuf.OutBlock, uBuf.OutLen
Call CoTaskMemFree(uBuf.OutBlock)
uBuf.OutBlock = 0
End If
uLocal.USize = uLocal.USize + uBuf.InLen
uLocal.CSize = uLocal.CSize + uBuf.OutLen
.CompressedSize = uLocal.CSize
RaiseEvent Progress(lIdx, uLocal.USize, .Size, m_bCancel)
If m_bCancel Then
m_sLastError = ERR_USER_CANCEL
GoTo QH
End If
Loop While lSize <> 0
If hCtx <> 0 Then
Call CallWindowProc(m_uRtbl.CompressCleanup, hCtx)
hCtx = 0
End If
If uLocal.CSize = 0 And uLocal.USize = 0 Then
uLocal.Method = LNG_METHOD_STORE
uLocal.VerExt = LNG_VER_DEFAULT
End If
End If
'--- if data is incompressible -> store file
If lComprLevel = 0 Or uLocal.CSize > uLocal.USize Then
pvVfsSeek uFile, 0, FILE_BEGIN
pvVfsSeek uArchiveFile, lBeginOffset, FILE_BEGIN
uLocal.Method = LNG_METHOD_STORE
uLocal.VerExt = LNG_VER_DEFAULT
uLocal.Crc32 = -1
uLocal.USize = 0
uLocal.CSize = 0
#If ImplCrypto Then
If LenB(.Password) <> 0 Then
If .Aes.Strength = 0 Then
If Not pvCryptoTradInit(ToUtf8Array(.Password)) Then
Err.Raise vbObjectError, , m_sLastError
End If
Else
If Not pvCryptoAesInit(ToUtf8Array(.Password), baSalt, lSaltSize * 2, nPassVer) Then
Err.Raise vbObjectError, , m_sLastError
End If
End If
End If
#End If
Do
RaiseEvent Progress(lIdx, uLocal.USize, .Size, m_bCancel)
If m_bCancel Then
m_sLastError = ERR_USER_CANCEL
GoTo QH
End If
lSize = pvVfsRead(uFile, VarPtr(baBuffer(0)), LNG_IOBUF_SIZE)
If lSize = 0 Then
Exit Do
End If
Call CallWindowProc(m_uRtbl.CalcCrc32, VarPtr(m_uRtbl), VarPtr(baBuffer(0)), lSize, VarPtr(uLocal.Crc32))
#If ImplCrypto Then
If LenB(.Password) <> 0 Then
If .Aes.Strength = 0 Then
If Not pvCryptoTradCrypt(baBuffer, Size:=lSize) Then
Err.Raise vbObjectError, , m_sLastError
End If
Else
If Not pvCryptoAesCrypt(baBuffer, Size:=lSize, HashAfter:=True) Then
Err.Raise vbObjectError, , m_sLastError
End If
End If
End If
#End If
pvVfsWrite uArchiveFile, VarPtr(baBuffer(0)), lSize
uLocal.USize = uLocal.USize + lSize
uLocal.CSize = uLocal.CSize + lSize
Loop
End If
End If
pvVfsClose uFile
uLocal.Crc32 = uLocal.Crc32 Xor -1
#If ImplCrypto Then
If LenB(.Password) <> 0 Then
If .Aes.Strength = 0 Then
uLocal.CSize = uLocal.CSize + LNG_ENC_HEADER_SIZE
Else
'--- append HMAC SHA1 authetication code after file data
baSalt = pvCryptoAesGetFinalHash(LNG_AES_AUTHCODE_SIZE)
pvVfsWrite uArchiveFile, VarPtr(baSalt(0)), LNG_AES_AUTHCODE_SIZE
'--- update AE-1/2 in extra data
uAes.HeaderId = LNG_EXTRADATA_AES_HEADER
uAes.Size = LNG_EXTRADATA_AES_SIZE - 4
uAes.Version = IIf(.Size <= LNG_EXTRADATA_AE_2_MAXSIZE, 2, 1)
uAes.VendorId = LNG_EXTRADATA_AES_VENDOR
uAes.Strength = lSaltSize / 4 - 1
uAes.Method = uLocal.Method
lJdx = UBound(.Extra) + 1 - LNG_EXTRADATA_AES_SIZE
Debug.Assert VarPtr(uAes.Strength) + 1 - VarPtr(uAes) = 9
Call CopyMemory(.Extra(lJdx), uAes, 9)
Call CopyMemory(.Extra(lJdx + 9), uAes.Method, 2)
'--- update local header
uLocal.Method = LNG_METHOD_AES
uLocal.CSize = uLocal.CSize + lSaltSize + 2 + LNG_AES_AUTHCODE_SIZE
If uAes.Version = 2 Then
uLocal.Crc32 = 0
End If
End If
End If
#End If
.Crc32 = uLocal.Crc32
Debug.Assert .Size = uLocal.USize
.Size = uLocal.USize
.CompressedSize = uLocal.CSize
.Method = uLocal.Method
.Flags = uLocal.Flags
If (uLocal.Flags And ucsZcfHasDataDescriptor) <> 0 Then
lBeginOffset = LNG_SIG_DATADESC
pvVfsWrite uArchiveFile, VarPtr(lBeginOffset), 4
pvVfsWrite uArchiveFile, VarPtr(uLocal.Crc32), 12
uLocal.Crc32 = 0
uLocal.CSize = 0
uLocal.USize = 0
End If
If uLocal.VerExt > uCentral.VerExt Then
uCentral.VerExt = uLocal.VerExt
End If
lBeginOffset = pvVfsSeek(uArchiveFile, 0, FILE_CURRENT)
pvVfsSeek uArchiveFile, .Offset, FILE_BEGIN
pvOutputLocalHeader uArchiveFile, uLocal, .FileName, .Extra
pvVfsSeek uArchiveFile, lBeginOffset, FILE_BEGIN
If False Then
SkipFile:
On Error GoTo EH
pvVfsSeek uArchiveFile, .Offset, FILE_BEGIN
.Offset = -1
If hCtx <> 0 Then
Call CallWindowProc(m_uRtbl.CompressCleanup, hCtx)
hCtx = 0
End If
End If
On Error GoTo EH
End With
Next
m_lCurrentFile = -1
lBeginOffset = pvVfsSeek(uArchiveFile, 0, FILE_CURRENT)
uCentral.Signature = LNG_SIG_CENTRAL
uCentral.VerMade = LNG_VER_ZIP64
For lIdx = 0 To m_lFileCount - 1
m_lCurrentFile = lIdx
With m_uFiles(lIdx)
If .Offset >= 0 Then
uCentral.Method = .Method
pvToDosDateTime .LastModified, uCentral.FDate, uCentral.FTime
uCentral.Crc32 = .Crc32
uCentral.CSize = .CompressedSize
uCentral.USize = .Size
uCentral.AttribX = .Attributes
uCentral.Offset = .Offset
uCentral.Flags = .Flags
pvOutputCentralHeader uArchiveFile, uCentral, .FileName, .Extra, .Comment
lEntries = lEntries + 1
End If
End With
Next
m_lCurrentFile = -1
If lEntries = 0 Then
Err.Raise vbObjectError, , ERR_EMPTY_ARCHIVE
End If
uEndHdr.Signature = LNG_SIG_END
uEndHdr.Entries = lEntries
uEndHdr.TotEntr = lEntries
uEndHdr.CenSize = pvVfsSeek(uArchiveFile, 0, FILE_CURRENT) - lBeginOffset
uEndHdr.CenOff = lBeginOffset
pvOutputEndHeader uArchiveFile, uEndHdr, Comment
pvVfsSetEof uArchiveFile, "[output_archive]"
'--- success
CompressArchive = True
QH:
On Error Resume Next
If uBuf.OutBlock <> 0 Then
Call CoTaskMemFree(uBuf.OutBlock)
uBuf.OutBlock = 0
End If
If hCtx <> 0 Then
Call CallWindowProc(m_uRtbl.CompressCleanup, hCtx)
hCtx = 0
End If
pvVfsClose uFile
pvVfsClose uArchiveFile
Exit Function
EH:
pvSetError MODULE_NAME & "." & FUNC_NAME & vbCrLf & Err.Source, Err.Description
Resume QH
EH_Continue:
If pvSetError(MODULE_NAME & "." & FUNC_NAME & vbCrLf & Err.Source, Err.Description, CanContinue:=True) Then
Resume QH
Else
Resume SkipFile
End If
End Function
Public Function AddFromFolder( _
sFolderAndMask As String, _
Optional Recursive As Boolean, _
Optional TargetFolder As String, _
Optional IncludeEmptyFolders As Boolean, _
Optional Password As String, _
Optional EncrStrength As Long, _
Optional Level As Long = -1) As Boolean
Const FUNC_NAME As String = "AddFromFolder"
Dim lIdx As Long
Dim sFolder As String
Dim sMask As String
Dim lRootOffset As Long
Dim cFolders As Collection
Dim vElem As Variant
Dim sName As String
On Error GoTo EH
pvSetError
Set cFolders = New Collection
lIdx = InStrRev(sFolderAndMask, "\")
If lIdx > 0 Then
sFolder = Left$(sFolderAndMask, lIdx - 1)
End If
sMask = Mid$(sFolderAndMask, lIdx + 1)
If LenB(sFolder) = 0 Then
sFolder = CurDir$()
End If
lRootOffset = Len(sFolder)
cFolders.Add sFolder
Do While cFolders.Count > 0
sFolder = cFolders.Item(1)
cFolders.Remove 1
lIdx = 0
For Each vElem In pvEnumFiles(sFolder, sMask, -vbDirectory)
If AddFile(vElem, PathCombine(TargetFolder, Mid$(vElem, lRootOffset + 2)), Password:=Password, EncrStrength:=EncrStrength, Level:=Level) Then
lIdx = lIdx + 1
'--- success (entries added)
AddFromFolder = True
End If
Next
If lIdx = 0 And IncludeEmptyFolders Then
sName = PathCombine(TargetFolder, Mid$(sFolder, lRootOffset + 2))
If LenB(sName) <> 0 Then
If AddFile(sFolder & "\", sName & "\", Password:=Password, EncrStrength:=EncrStrength, Level:=Level) Then
'--- success (entries added)
AddFromFolder = True
End If
End If
End If
If Recursive Then
For Each vElem In pvEnumFiles(sFolder, "*.*", vbDirectory)
cFolders.Add vElem
Next
End If
Loop
QH:
Exit Function
EH:
pvSetError MODULE_NAME & "." & FUNC_NAME & vbCrLf & Err.Source, Err.Description
Resume QH
End Function
Private Function pvEnumFiles(sFolder As String, sMask As String, ByVal eAttrib As VbFileAttribute) As Collection
Dim sFile As String
Dim hFind As Long
Dim uData As WIN32_FIND_DATA
On Error GoTo EH
Set pvEnumFiles = New Collection
sFile = PathCombine(sFolder, sMask)
hFind = FindFirstFile(StrPtr(sFile), VarPtr(uData))
If hFind = INVALID_HANDLE_VALUE Then
If Err.LastDllError <> 2 Then
On Error GoTo 0
Err.Raise vbObjectError, "pvEnumFiles", GetSystemMessage(Err.LastDllError) & " (" & sFile & ")"
End If
Else
Do
If eAttrib > 0 And (uData.dwFileAttributes And eAttrib) <> 0 _
Or eAttrib < 0 And (uData.dwFileAttributes And -eAttrib) = 0 Then
sFile = Left$(uData.cFileName, InStr(uData.cFileName, Chr$(0)) - 1)
If sFile <> "." And sFile <> ".." Then
pvEnumFiles.Add PathCombine(sFolder, sFile)
End If
End If
Loop While FindNextFile(hFind, VarPtr(uData)) <> 0
Call FindClose(hFind)
hFind = 0
End If
Exit Function
EH:
If hFind <> 0 And hFind <> INVALID_HANDLE_VALUE Then
Call FindClose(hFind)
hFind = 0
End If
Err.Raise Err.Number, Err.Source, Err.Description
End Function
Private Sub pvOutputLocalHeader(uFile As UcsVfsFileType, uHdr As UcsLocalHeaderType, FileName As String, baExtra() As Byte)
Dim baFName() As Byte
baFName = pvToOemString(Replace(FileName, "\", "/"), IIf((uHdr.Flags And ucsZcfUseUtf8) <> 0, CP_UTF8, CP_OEMCP))
uHdr.LenFname = UBound(baFName) + 1
uHdr.LenExt = UBound(baExtra) + 1
Debug.Assert VarPtr(uHdr.FDate) + 2 - VarPtr(uHdr.Signature) + VarPtr(uHdr.LenExt) + 2 - VarPtr(uHdr.Crc32) = LNG_LEN_LOCAL
Debug.Assert VarPtr(uHdr.FDate) + 2 - VarPtr(uHdr.Signature) = 14
pvVfsWrite uFile, VarPtr(uHdr.Signature), 14
Debug.Assert VarPtr(uHdr.LenExt) + 2 - VarPtr(uHdr.Crc32) = 16
pvVfsWrite uFile, VarPtr(uHdr.Crc32), 16
Debug.Assert uHdr.LenFname > 0
If uHdr.LenFname > 0 Then
pvVfsWrite uFile, VarPtr(baFName(0)), uHdr.LenFname
End If
If uHdr.LenExt > 0 Then
pvVfsWrite uFile, VarPtr(baExtra(0)), uHdr.LenExt
End If
End Sub
Private Sub pvOutputCentralHeader(uFile As UcsVfsFileType, uHdr As UcsCentralHeaderType, FileName As String, baExtra() As Byte, Comment As String)
Dim lCodePage As Long
Dim baFName() As Byte
Dim baComment() As Byte
lCodePage = IIf((uHdr.Flags And ucsZcfUseUtf8) <> 0, CP_UTF8, CP_OEMCP)
baFName = pvToOemString(Replace(FileName, "\", "/"), lCodePage)
baComment = pvToOemString(Comment, lCodePage)
uHdr.LenFname = UBound(baFName) + 1
uHdr.LenExt = UBound(baExtra) + 1
uHdr.LenCom = UBound(baComment) + 1
Debug.Assert VarPtr(uHdr.FDate) + 2 - VarPtr(uHdr.Signature) + VarPtr(uHdr.AttribI) + 2 - VarPtr(uHdr.Crc32) + VarPtr(uHdr.Offset) + 4 - VarPtr(uHdr.AttribX) = LNG_LEN_CENTRAL
Debug.Assert VarPtr(uHdr.FDate) + 2 - VarPtr(uHdr.Signature) = 16
pvVfsWrite uFile, VarPtr(uHdr.Signature), 16