Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b39f7a0e89 | ||
|
|
d7e6aa00c7 | ||
|
|
071d297e2f | ||
|
|
5fb912b825 | ||
|
|
5be3472def | ||
|
|
416c59dbf8 | ||
|
|
163352fb5b | ||
|
|
9c5849f3fc | ||
|
|
60a07e9c87 | ||
|
|
cec7468e0d | ||
|
|
d868ac0c04 | ||
|
|
58b37d35e5 | ||
|
|
4d76c8b508 | ||
|
|
082c59a801 | ||
|
|
d49fc77083 | ||
|
|
53617b364a | ||
|
|
41fcda94f6 | ||
|
|
a008833eca | ||
|
|
8dae95b53e | ||
|
|
6c87ff43fc | ||
|
|
2e5717c80b | ||
|
|
d011482ec7 | ||
|
|
4b35a2777f | ||
|
|
b596ab6b34 | ||
|
|
370ab036f3 | ||
|
|
4b5bd87b68 | ||
|
|
d9500db041 | ||
|
|
736e165966 | ||
|
|
b83550fc01 | ||
|
|
2be4dc08c7 | ||
|
|
7e42ddda12 | ||
|
|
137b6ebde1 | ||
|
|
39440d01a2 | ||
|
|
f286b831d0 | ||
|
|
daae8acc64 | ||
|
|
354903bce8 | ||
|
|
2dc530f72f | ||
|
|
4d33e1d434 | ||
|
|
15507efd00 | ||
|
|
2f4f41b8a6 | ||
|
|
5813cf5048 | ||
|
|
fa995f73bc | ||
|
|
150cff6b98 | ||
|
|
3be7dae3c0 | ||
|
|
31afe5e1bd | ||
|
|
c4f415aab3 | ||
|
|
f767b8f3ed | ||
|
|
b1264e4caa | ||
|
|
5d56544c57 | ||
|
|
d0d1d68b96 | ||
|
|
d82ea2c654 | ||
|
|
e22948c731 | ||
|
|
106d0ee136 | ||
|
|
e3bd6e8e8b | ||
|
|
8d6875d9c2 | ||
|
|
75741f4b2c | ||
|
|
296489b206 | ||
|
|
828823443f | ||
|
|
57cbcd2fbd | ||
|
|
545d729594 | ||
|
|
28d87dd8b8 | ||
|
|
3d736ceff4 | ||
|
|
0cbc7b146d | ||
|
|
be483d8b6e | ||
|
|
a44fae3b0c | ||
|
|
933e5cf6d6 | ||
|
|
c88ce6d42c | ||
|
|
d3fcde51b1 | ||
|
|
5da54ee63f | ||
|
|
30f45f2bbb | ||
|
|
69f1b973a1 | ||
|
|
ad24015718 | ||
|
|
f77766b102 | ||
|
|
0e1fd89746 | ||
|
|
e3c9fe7556 | ||
|
|
5cc8a54813 | ||
|
|
cf8707ccf9 | ||
|
|
6ae07cb4f2 | ||
|
|
334dc2b05b | ||
|
|
59fe7dcff0 | ||
|
|
5cb124c0b6 | ||
|
|
fee75ebd89 | ||
|
|
6f9a9c6b11 | ||
|
|
8b3892497a | ||
|
|
a656116d39 | ||
|
|
864cdc97a1 | ||
|
|
50cc1adaed | ||
|
|
1abb40fc3a | ||
|
|
6f8c73c516 | ||
|
|
cce6a2c3fb | ||
|
|
d942eab627 | ||
|
|
10ac291d91 | ||
|
|
cc3aa21c2d | ||
|
|
b4d17e6d9d | ||
|
|
fe33c3d1b6 | ||
|
|
8f397f826d | ||
|
|
b11be60c0c | ||
|
|
8bba5e3fdf | ||
|
|
899ceef295 | ||
|
|
15909a58ea | ||
|
|
a9f88d4b78 | ||
|
|
58dfe87d1d | ||
|
|
17447aac42 | ||
|
|
25e76a213f | ||
|
|
938936c285 | ||
|
|
10cd8b86b9 | ||
|
|
e33afe4012 | ||
|
|
e9c8709b3f | ||
|
|
35ed7354b7 | ||
|
|
b7b90c3d19 | ||
|
|
88cb25164c | ||
|
|
84a398027d | ||
|
|
1e1227b18e | ||
|
|
28f78ffcc2 | ||
|
|
edebe6891d | ||
|
|
2cbffcdb47 | ||
|
|
32fd805440 | ||
|
|
84498c7601 | ||
|
|
74354ebfb3 | ||
|
|
1aef5b4661 | ||
|
|
e3a0c2569f | ||
|
|
2e1ca271d7 | ||
|
|
0ed30b6bd8 | ||
|
|
fbfd4e82f7 | ||
|
|
46ac718c70 | ||
|
|
641b0bcb55 | ||
|
|
27687efc01 | ||
|
|
65447dd38a | ||
|
|
cf076661a9 | ||
|
|
8ef4540e68 | ||
|
|
64c4c7f868 | ||
|
|
1d9f8aacf0 | ||
|
|
78859aa714 | ||
|
|
034d7e6896 | ||
|
|
7d94b1ffa1 | ||
|
|
c164ddf5c8 | ||
|
|
aa0c293f71 | ||
|
|
3a941ef473 | ||
|
|
0ecc3f68a6 | ||
|
|
837eec8473 | ||
|
|
3506cb31e5 | ||
|
|
426543d2c4 | ||
|
|
3318d15d00 | ||
|
|
971d7de4c9 | ||
|
|
b3f1c2c512 | ||
|
|
aeb6cdd545 | ||
|
|
8d2cf92af6 | ||
|
|
880be2eaae | ||
|
|
eeaf283658 | ||
|
|
cb4f9f6960 | ||
|
|
a5a1d5d272 | ||
|
|
6496d23578 | ||
|
|
9cb3cb14b2 | ||
|
|
02eb8cda22 | ||
|
|
27f1e9e1e5 | ||
|
|
5f8e2be461 | ||
|
|
36f61523a3 | ||
|
|
2397b51366 | ||
|
|
6d7160f3d8 | ||
|
|
3249eac087 | ||
|
|
595318d7e7 | ||
|
|
8f7474c8d4 | ||
|
|
cf20c09016 | ||
|
|
58daeb9497 | ||
|
|
9482920d4c | ||
|
|
305ffa14e4 | ||
|
|
4072f3e3bf | ||
|
|
a7ec00138a | ||
|
|
ecacfc200d | ||
|
|
f191087fdf | ||
|
|
cb3b920a04 | ||
|
|
3507a9050f | ||
|
|
61f224aacd | ||
|
|
aca3c6c17e | ||
|
|
5b0b83c2b8 | ||
|
|
8193682eac | ||
|
|
c6e5588e15 | ||
|
|
fce162e6b1 | ||
|
|
98b489b267 | ||
|
|
b409efde8d | ||
|
|
7eb820cdca | ||
|
|
f6b6f05c8b | ||
|
|
c558b1a902 | ||
|
|
462ed6474c | ||
|
|
7a9a1f6741 | ||
|
|
5c997ffb6f | ||
|
|
2e0a20a82a | ||
|
|
c1b7a73561 | ||
|
|
cd3e9e12d2 | ||
|
|
b9cb4e6a4d | ||
|
|
bdff1fc438 | ||
|
|
f162fd715a | ||
|
|
3c438164bd | ||
|
|
51f6f1438f | ||
|
|
64faa259d5 | ||
|
|
4fe0687243 | ||
|
|
ba5d8dc8b5 | ||
|
|
98a34fe11a | ||
|
|
a76a47889a | ||
|
|
8df8559202 | ||
|
|
c9c23c7266 | ||
|
|
c28a9f452f | ||
|
|
2e7c11eb5e | ||
|
|
82999bf96d | ||
|
|
488f20ff1b | ||
|
|
e54d842759 | ||
|
|
cf822aab24 | ||
|
|
9c70a4838c | ||
|
|
85cf8563c9 | ||
|
|
a7e69c76be | ||
|
|
066157e9b0 | ||
|
|
febe69a9de | ||
|
|
53b5e2f8c3 | ||
|
|
8fb80888f3 | ||
|
|
09725906c9 | ||
|
|
35ff149086 | ||
|
|
3717ece26f | ||
|
|
991f91ad14 | ||
|
|
37fbcb4c45 | ||
|
|
86ae4be61f | ||
|
|
83d8f4ae53 | ||
|
|
edfe614184 | ||
|
|
ca5551c49d | ||
|
|
9805ab4117 | ||
|
|
9ee875d2ad | ||
|
|
d484eca50e | ||
|
|
6be7b59732 | ||
|
|
ba49029b54 | ||
|
|
6b220aa5fb | ||
|
|
303e6f365b | ||
|
|
49ee078edd | ||
|
|
a044b7ee04 | ||
|
|
92b0d46d8d | ||
|
|
c5b292e5c8 | ||
|
|
bfe9d6498c | ||
|
|
720d95a461 | ||
|
|
db21e42a05 | ||
|
|
73d3da0c8c | ||
|
|
fac5012bf5 | ||
|
|
33485822c0 | ||
|
|
cd7646ab60 | ||
|
|
2e2f995eda | ||
|
|
e54bf2821b | ||
|
|
840464bc01 | ||
|
|
e282739da2 | ||
|
|
0512fd4771 | ||
|
|
40ab797fed | ||
|
|
38837cbec7 | ||
|
|
d0605392e6 | ||
|
|
aec922930f | ||
|
|
ce5be0f669 | ||
|
|
1fc153481a | ||
|
|
a6ecab5fdc | ||
|
|
554d3ab702 | ||
|
|
226d905220 | ||
|
|
91b2502219 | ||
|
|
288b484caa | ||
|
|
009a37a512 | ||
|
|
84ec941f15 | ||
|
|
cdedc087e7 | ||
|
|
e51dd48a91 | ||
|
|
208a051c36 | ||
|
|
e4968653f4 | ||
|
|
e71e3e3445 | ||
|
|
e7ede97c07 | ||
|
|
2ca7f3950c | ||
|
|
b150432588 | ||
|
|
c78c782f63 | ||
|
|
1ff40343b5 | ||
|
|
c1fd2edbd2 | ||
|
|
2df1ecbce4 | ||
|
|
a893e6f678 | ||
|
|
8ff664da01 | ||
|
|
d931843012 | ||
|
|
b99b3bf3fc | ||
|
|
f2b2dad2c9 | ||
|
|
9df028d532 | ||
|
|
d058fdb3a1 | ||
|
|
6675c44613 | ||
|
|
4ff891a638 | ||
|
|
f9e344888f | ||
|
|
9e9d0299f1 | ||
|
|
5a16351708 | ||
|
|
5cb88b8f09 | ||
|
|
536a250734 | ||
|
|
e8c94b0570 | ||
|
|
9bd8e85399 | ||
|
|
41eaa4c0ab | ||
|
|
025212f6dc | ||
|
|
6295dcf005 | ||
|
|
62f435adbb | ||
|
|
fa0c9c8edc | ||
|
|
7f73943486 | ||
|
|
2ce1fe2732 | ||
|
|
6b64b924af | ||
|
|
2eb2907823 | ||
|
|
b4d88d426b | ||
|
|
ba1db16a28 | ||
|
|
6ac5fe69d0 | ||
|
|
4c642fc296 | ||
|
|
d8f00c57cb | ||
|
|
54b9939845 | ||
|
|
13a51b9389 | ||
|
|
1b6fcaca41 | ||
|
|
cdac37e1fe | ||
|
|
9897259b04 | ||
|
|
e9ae46ba27 | ||
|
|
3e2d07451c | ||
|
|
d31c5de5b0 | ||
|
|
ad82950a53 | ||
|
|
39365dd10d | ||
|
|
76fb8903e1 | ||
|
|
e849627093 | ||
|
|
6f3a0a6ad0 | ||
|
|
b066fd9677 | ||
|
|
b578fa5ba5 | ||
|
|
bacef206da | ||
|
|
d96f23f925 | ||
|
|
a5bc018ecc | ||
|
|
83aa562e32 | ||
|
|
8a35deab70 | ||
|
|
783d258c68 | ||
|
|
b16ab566ef | ||
|
|
ddeeae3388 | ||
|
|
e231cfd9d8 | ||
|
|
f96e8636a4 | ||
|
|
f4207b7a23 | ||
|
|
02c9edb3af | ||
|
|
d4f27376aa | ||
|
|
9475829f15 | ||
|
|
19cdb10201 | ||
|
|
d46559398f | ||
|
|
90d31c791d | ||
|
|
0a60d2ca2a | ||
|
|
0c59898b2d | ||
|
|
53c3d0ae2f | ||
|
|
1ee609b759 | ||
|
|
0ecfd22443 | ||
|
|
7de94cf921 | ||
|
|
c1e07aaeb0 | ||
|
|
329ac651d8 | ||
|
|
4d0897361b | ||
|
|
fd2fb24b4e | ||
|
|
82fa1b39c0 | ||
|
|
2d37e12f36 | ||
|
|
fe9ec41c49 | ||
|
|
a8b23065cd | ||
|
|
08b01ca7b7 | ||
|
|
bc64e9f899 | ||
|
|
abb508eabe | ||
|
|
1139b468c1 | ||
|
|
c4916c971a | ||
|
|
d8b232a6e9 | ||
|
|
fb8a1cc220 | ||
|
|
a2a3858e05 | ||
|
|
ea2bd795a3 | ||
|
|
51b050e0b8 | ||
|
|
09e41030a5 | ||
|
|
7817f5c8d5 | ||
|
|
a4549e0689 | ||
|
|
4d29ba4782 | ||
|
|
4d4c9db5b0 | ||
|
|
a93a2ad678 | ||
|
|
e0b2477114 | ||
|
|
264dc189b3 | ||
|
|
b2b082c67d | ||
|
|
12d03f4e61 | ||
|
|
dd103f4fc1 | ||
|
|
d82579a400 | ||
|
|
98cbf2296a | ||
|
|
9320beab03 | ||
|
|
f47e75303d | ||
|
|
11a44ecf33 | ||
|
|
5498bb6c4f | ||
|
|
278770c5f3 | ||
|
|
e71d8776be | ||
|
|
3c2b4da788 | ||
|
|
c6443ff336 | ||
|
|
a7af82f8cf | ||
|
|
146fa3a663 | ||
|
|
96b401b2c5 | ||
|
|
771856888c | ||
|
|
5502aeaeb2 | ||
|
|
2805bd4688 | ||
|
|
4d6530cd88 | ||
|
|
1f9efeae4f | ||
|
|
0687386d8b | ||
|
|
d5911f4524 | ||
|
|
23b9d094d7 | ||
|
|
258d42c566 | ||
|
|
8ce54b4a8d | ||
|
|
f07057a85e | ||
|
|
e440f1e9d5 | ||
|
|
6fab9297d2 | ||
|
|
1d6d183af6 | ||
|
|
f274ae0649 | ||
|
|
95fec96e05 | ||
|
|
3c7568fa67 | ||
|
|
05a45d61ab | ||
|
|
d4d49df0b1 | ||
|
|
f9b4d20535 | ||
|
|
cf622bb55c | ||
|
|
57b65f8a15 | ||
|
|
effc1428ff | ||
|
|
286a8174f6 | ||
|
|
b08bd9a3fa | ||
|
|
07b0ecadc6 | ||
|
|
0dfcdf91ba | ||
|
|
23342c44d4 | ||
|
|
65dbda889d | ||
|
|
e39032376e | ||
|
|
30a5288bf4 | ||
|
|
4cceb2f6c8 | ||
|
|
2ff079d5d8 | ||
|
|
0d85193f89 | ||
|
|
c000e8f1f8 | ||
|
|
761d28e30d | ||
|
|
6000844769 | ||
|
|
51834cd9f9 | ||
|
|
c47090678d | ||
|
|
79138fe17c | ||
|
|
9e8d7a8c76 | ||
|
|
79244df024 | ||
|
|
87a668fd64 | ||
|
|
a18f49f6d3 | ||
|
|
aacf87304e | ||
|
|
130f0591ba | ||
|
|
c8501a4216 | ||
|
|
a90e29704a | ||
|
|
69e3549034 | ||
|
|
a4fc2c5e85 | ||
|
|
8edafb620a | ||
|
|
b4923cd155 | ||
|
|
71295ce78d | ||
|
|
088b819ec0 | ||
|
|
a8f23236e8 | ||
|
|
b11b6cfe63 | ||
|
|
feb86c551a | ||
|
|
826113fd6c | ||
|
|
4d5a9a66c9 | ||
|
|
25634010c9 | ||
|
|
6cda2a7e76 | ||
|
|
7c2005dcf0 | ||
|
|
cb5798a6b9 | ||
|
|
cdef32b909 | ||
|
|
8721aaf7ec | ||
|
|
d15b704c85 | ||
|
|
1b87a5a358 | ||
|
|
e52a3b5732 | ||
|
|
e63d231fa5 | ||
|
|
24280b68e8 | ||
|
|
888e8a7324 | ||
|
|
c51f2515d6 | ||
|
|
adfe53f969 | ||
|
|
f164b6dd37 | ||
|
|
02760f6257 | ||
|
|
8541317c10 | ||
|
|
3223d8d378 | ||
|
|
bdf88e7425 | ||
|
|
6cdd3f54da | ||
|
|
4337bcc752 | ||
|
|
0d396799c1 | ||
|
|
0b14aeddde | ||
|
|
1b2b32c8b8 | ||
|
|
66e1631e4b | ||
|
|
7ff6b8aa9f | ||
|
|
b64f4f1228 | ||
|
|
5f381b232d | ||
|
|
f95e3683ee | ||
|
|
0d9d0df40d | ||
|
|
20e4d587ca | ||
|
|
3aaf5bc895 | ||
|
|
623a844814 | ||
|
|
c9add13ae6 | ||
|
|
fcd85ef064 | ||
|
|
54dffe95e9 | ||
|
|
82d4fa0dd6 | ||
|
|
eff49b88ce | ||
|
|
04d821edef | ||
|
|
7eb65ad2ae | ||
|
|
f79ec42ad3 | ||
|
|
f6557afd71 | ||
|
|
10489ead98 | ||
|
|
d021ab867b | ||
|
|
90a8b12562 | ||
|
|
6209991d6b | ||
|
|
3caa105cef | ||
|
|
0bff08751b | ||
|
|
ea5e45dfe2 | ||
|
|
1e21dc3a9b | ||
|
|
c73ef6e69b | ||
|
|
57942ad197 | ||
|
|
974410131c | ||
|
|
848837b78b | ||
|
|
dc63e1ebcf | ||
|
|
8b5826b3bf | ||
|
|
f3efcb6227 | ||
|
|
43c01101bf | ||
|
|
d1e3877b4d | ||
|
|
a221da4ae0 | ||
|
|
703b3df3ef | ||
|
|
05e03cad8e | ||
|
|
71027dc8fb | ||
|
|
4ae469a0a4 | ||
|
|
80b56a8a5a | ||
|
|
a2bb08c816 | ||
|
|
619b2b3c8b | ||
|
|
fac97955d1 | ||
|
|
ea66a05adc | ||
|
|
dd31249b5a | ||
|
|
37b4da07f1 | ||
|
|
cb9c40c23d | ||
|
|
cce11ba090 | ||
|
|
6e2f181c18 | ||
|
|
e464430433 | ||
|
|
f5b7ed7bfe | ||
|
|
72a099dae1 | ||
|
|
13d9e7666c | ||
|
|
fea1232fa6 | ||
|
|
2a172f312d | ||
|
|
3c000cf5fb | ||
|
|
915c513abe | ||
|
|
2ed269e000 | ||
|
|
217cd65995 | ||
|
|
bc21a7456b | ||
|
|
94f8c19db4 | ||
|
|
80d30e6bf8 | ||
|
|
566dfe0dcd | ||
|
|
9ad08e1ec6 | ||
|
|
1770d3554e | ||
|
|
13ae3ab2bc | ||
|
|
e300b7f3a2 | ||
|
|
f44a0e089c | ||
|
|
5b3039af0e | ||
|
|
d0ac17fd60 | ||
|
|
156a64730b | ||
|
|
8cc0800876 | ||
|
|
9d6d894153 | ||
|
|
6cabcc0523 | ||
|
|
6a415925fd | ||
|
|
bee75d5f3e | ||
|
|
7dce6de14f | ||
|
|
6bde034147 | ||
|
|
c714ef60a4 | ||
|
|
f97c9f48b2 | ||
|
|
d2dc11ca57 | ||
|
|
d45af6d6e9 | ||
|
|
bf7776206e | ||
|
|
47a2cd7b99 | ||
|
|
9fb8290289 | ||
|
|
e5a5617a7c | ||
|
|
5352f868bb | ||
|
|
d9969b545a | ||
|
|
8a7383a210 | ||
|
|
648f596a99 | ||
|
|
8875d288db | ||
|
|
8cb7df741a | ||
|
|
7404279f66 | ||
|
|
5f09188ca9 | ||
|
|
21a3102db4 | ||
|
|
73025eb9db | ||
|
|
a5e06a7bcf | ||
|
|
eef6ffc75d | ||
|
|
e1f68fca9c | ||
|
|
fa620e473f | ||
|
|
413822a040 | ||
|
|
a7fecd88dd | ||
|
|
c565fa8f88 | ||
|
|
c5da4987c8 | ||
|
|
d64e079092 | ||
|
|
f03cdc7604 | ||
|
|
5afeb430ee | ||
|
|
b4c953f36a | ||
|
|
9dea6f2495 | ||
|
|
544fc3b97b | ||
|
|
73660f9c98 | ||
|
|
da95d6e8b7 | ||
|
|
ff6f2a1db6 | ||
|
|
5e6bac5bcc | ||
|
|
09304a6184 | ||
|
|
004e7d3327 | ||
|
|
fe145502a6 | ||
|
|
904c408575 | ||
|
|
98047626d7 | ||
|
|
e6b6616575 | ||
|
|
c7e852e33c | ||
|
|
8c272e0ff8 | ||
|
|
17bad4cf74 | ||
|
|
3b3840b7b2 | ||
|
|
0900548d8b | ||
|
|
2bb21d769c | ||
|
|
2630f5f4dc | ||
|
|
15dbc445d8 | ||
|
|
9098b6c823 | ||
|
|
ed403113a2 | ||
|
|
f6fe93b2a8 | ||
|
|
e5ce077bf3 | ||
|
|
fe7983319a | ||
|
|
ca8059ef61 | ||
|
|
15570e0794 | ||
|
|
a247bfaa68 | ||
|
|
682503ce78 | ||
|
|
709c1f05ce | ||
|
|
0113ad8330 | ||
|
|
9ba3525779 | ||
|
|
9980d8ac3a | ||
|
|
a0f617cd8a | ||
|
|
9747212a14 | ||
|
|
825bfb8fbf | ||
|
|
0863941638 | ||
|
|
5469018dbc | ||
|
|
dacd44383d | ||
|
|
e80d8c7d22 | ||
|
|
72538543aa | ||
|
|
980b3ab699 | ||
|
|
e09ea0e515 | ||
|
|
0b1e147394 | ||
|
|
9117655893 | ||
|
|
ca505c0fde | ||
|
|
bb96c73f7b | ||
|
|
fa25b2ecc4 | ||
|
|
0e7b9fc3c8 | ||
|
|
37842b678d | ||
|
|
dd54b153c0 | ||
|
|
0db9d70659 | ||
|
|
09ddae6514 | ||
|
|
0457003448 | ||
|
|
1b3ce71663 | ||
|
|
777db81e88 | ||
|
|
44a2d152de | ||
|
|
165a40221d | ||
|
|
ab8507608e | ||
|
|
67d17c0442 | ||
|
|
e7215072a0 | ||
|
|
7932c261dd | ||
|
|
85d36c5e83 | ||
|
|
75c064bdf6 | ||
|
|
a1e0db1d09 | ||
|
|
6f40c04998 | ||
|
|
6d492ea3e7 | ||
|
|
a068933451 | ||
|
|
eb923e7d2b | ||
|
|
5d9f95fca1 | ||
|
|
e52f092b08 | ||
|
|
353586a4c4 | ||
|
|
7ea3653e77 | ||
|
|
0238f0041e | ||
|
|
242ec32883 | ||
|
|
96520fe778 | ||
|
|
8e61a208d5 | ||
|
|
8e47b249fd | ||
|
|
fc4a57f14c | ||
|
|
611adce2b3 | ||
|
|
9eaadb4d3c | ||
|
|
de98134362 | ||
|
|
ce2c6c3521 | ||
|
|
eb60ab3493 | ||
|
|
881f2d2ea3 | ||
|
|
1872771139 | ||
|
|
f307d59c11 | ||
|
|
f1698d631f | ||
|
|
59ba13b5a9 | ||
|
|
d27969a853 | ||
|
|
7b6f04e955 | ||
|
|
bc0a9005f2 | ||
|
|
c4d130878f | ||
|
|
315ca492fd | ||
|
|
a594982712 | ||
|
|
d4ed216bd3 | ||
|
|
8935dd19db | ||
|
|
351b14e512 | ||
|
|
7188209f03 | ||
|
|
95047d3c90 | ||
|
|
359e8e1017 | ||
|
|
e7df0f7341 | ||
|
|
da1ab3dab1 | ||
|
|
abc29e4429 | ||
|
|
b8300ce0ea | ||
|
|
638f31ff41 | ||
|
|
a0d1877d0e | ||
|
|
3eaa5560bf | ||
|
|
d4c4d4f5b1 | ||
|
|
d79fb39d4b | ||
|
|
a2e89bf85e | ||
|
|
e27af27b6e | ||
|
|
72cc7015a2 | ||
|
|
a2bd3c6d95 | ||
|
|
dcd9b72bf9 | ||
|
|
d2aa2277d9 | ||
|
|
da4b58f6e5 | ||
|
|
b994caeab9 | ||
|
|
0b6059fc53 | ||
|
|
4b8e4b372c | ||
|
|
bb3d26efb7 | ||
|
|
74a6a21e56 | ||
|
|
2b3cd16b6f | ||
|
|
79cfab094d | ||
|
|
0e2201a5e1 | ||
|
|
e04106b734 | ||
|
|
b9dbacae60 | ||
|
|
590e5909b3 | ||
|
|
960a6e113c | ||
|
|
01bc6016fb | ||
|
|
5f01092239 | ||
|
|
444596646e | ||
|
|
c98dec4291 | ||
|
|
ca014e6f37 | ||
|
|
f5cc4c0355 | ||
|
|
00520cd631 | ||
|
|
c56d53156e | ||
|
|
05aa0f2a07 | ||
|
|
829ffb5cce | ||
|
|
b635b7db5a | ||
|
|
9f863b35ca | ||
|
|
de09ac796f | ||
|
|
cfa2e604f6 | ||
|
|
a8644a1de8 | ||
|
|
9a170d4d60 | ||
|
|
77687f3a42 | ||
|
|
a64c919e0b | ||
|
|
9eb113dee7 | ||
|
|
d08e1561d9 | ||
|
|
26308b244e | ||
|
|
0e4fe82acb | ||
|
|
fa146ad6bd | ||
|
|
0f8d91101b | ||
|
|
a6d04a7baa | ||
|
|
00ad03daf0 | ||
|
|
2b43158414 | ||
|
|
0e1fd3ee8b | ||
|
|
c65c7a928f | ||
|
|
65a87024d4 | ||
|
|
c599dd60f4 | ||
|
|
c2d5c47b51 | ||
|
|
89d6967afc | ||
|
|
7c29c16575 | ||
|
|
7679d219a0 | ||
|
|
298126af7f | ||
|
|
7f6f08acfc | ||
|
|
c83e4da20d | ||
|
|
b5c2f01c31 | ||
|
|
54dc69af1c | ||
|
|
5f2bf575df | ||
|
|
c9addbe56d | ||
|
|
155b3f5e42 | ||
|
|
32a9d34295 | ||
|
|
a8f4a09de6 | ||
|
|
e824da8453 | ||
|
|
51bf61d04e | ||
|
|
f55a3c5a40 | ||
|
|
546607c8e4 | ||
|
|
4818d8efe8 | ||
|
|
a2a37040c7 | ||
|
|
0fac5e72ec | ||
|
|
d195fd3a59 | ||
|
|
f23af14199 | ||
|
|
1149bafee3 | ||
|
|
aa311f349b | ||
|
|
6f32e35278 | ||
|
|
44a14426dc | ||
|
|
eadf3eb181 | ||
|
|
a982abf876 | ||
|
|
3719965652 | ||
|
|
91c028d276 | ||
|
|
4042763729 | ||
|
|
a6d1f6692e | ||
|
|
4d34203968 | ||
|
|
93c13564b8 | ||
|
|
f9ee9d7f08 | ||
|
|
7332bd6002 | ||
|
|
9645f4638c | ||
|
|
8d128a7c63 | ||
|
|
627993ef07 | ||
|
|
4cfdd5dd83 | ||
|
|
697e995d89 | ||
|
|
16d9f47a4f | ||
|
|
6ac2ff4ec2 | ||
|
|
e099a2a8f7 | ||
|
|
163b317ad6 | ||
|
|
446d062b3c | ||
|
|
6781995724 | ||
|
|
b3bf29ab02 | ||
|
|
7a0a62dc9c | ||
|
|
d50e91aafe | ||
|
|
ae724eff61 | ||
|
|
4bdb436e8e | ||
|
|
2ecd8a0b2a | ||
|
|
f873eccdd2 | ||
|
|
9593ca4fc5 | ||
|
|
2e4a85e36f | ||
|
|
ee614ff3ce | ||
|
|
6b12c36538 | ||
|
|
a4a5cf66aa |
@@ -0,0 +1,3 @@
|
||||
ignore:
|
||||
- "lib/*"
|
||||
- "lib/**/*"
|
||||
@@ -0,0 +1 @@
|
||||
github: nmoinvaz
|
||||
@@ -0,0 +1,315 @@
|
||||
name: CI
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
name: ${{ matrix.name }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
name: [
|
||||
Ubuntu 16 GCC 4.8,
|
||||
Ubuntu 16 GCC,
|
||||
Ubuntu 16 Clang 3.5,
|
||||
Ubuntu 16 Clang,
|
||||
Ubuntu 18 GCC,
|
||||
Ubuntu 18 Clang,
|
||||
Ubuntu 18 Clang No Zlib,
|
||||
Ubuntu 18 Clang No Bzip2,
|
||||
Ubuntu 18 Clang No LZMA,
|
||||
Ubuntu 18 Clang No Pkcrypt,
|
||||
Ubuntu 18 Clang No Winzip AES,
|
||||
Ubuntu 18 Clang No Encryption,
|
||||
Ubuntu 18 Clang Compress Only,
|
||||
Ubuntu 18 Clang Decompress Only,
|
||||
Ubuntu 18 Clang OpenSSL,
|
||||
Windows 2016 MSVC,
|
||||
Windows 2016 GCC,
|
||||
Windows 2019 MSVC,
|
||||
Windows 2019 GCC,
|
||||
macOS Xcode 9.4.1,
|
||||
macOS Xcode,
|
||||
macOS Xcode LibCompression,
|
||||
macOS Xcode OpenSSL
|
||||
]
|
||||
|
||||
include:
|
||||
- name: Ubuntu 16 GCC 4.8
|
||||
os: ubuntu-16.04
|
||||
compiler: gcc
|
||||
cmake-args: -DMZ_CODE_COVERAGE=ON
|
||||
version: "4.8"
|
||||
codecov: ubuntu_16_gcc_48
|
||||
|
||||
- name: Ubuntu 16 GCC
|
||||
os: ubuntu-16.04
|
||||
compiler: gcc
|
||||
cmake-args: -DMZ_CODE_COVERAGE=ON
|
||||
codecov: ubuntu_16_gcc
|
||||
|
||||
- name: Ubuntu 16 Clang 3.5
|
||||
os: ubuntu-16.04
|
||||
compiler: clang
|
||||
cmake-args: -DMZ_CODE_COVERAGE=ON
|
||||
codecov: ubuntu_16_clang_35
|
||||
version: "3.5"
|
||||
packages: llvm-3.5
|
||||
gcov-exec: llvm-cov-3.5 gcov
|
||||
|
||||
# No code coverage on release builds
|
||||
- name: Ubuntu 16 Clang
|
||||
os: ubuntu-16.04
|
||||
compiler: clang
|
||||
deploy: true
|
||||
deploy-name: linux
|
||||
|
||||
- name: Ubuntu 18 GCC
|
||||
os: ubuntu-18.04
|
||||
compiler: gcc
|
||||
cmake-args: -DMZ_CODE_COVERAGE=ON
|
||||
codecov: ubuntu_18_gcc
|
||||
|
||||
- name: Ubuntu 18 Clang
|
||||
os: ubuntu-18.04
|
||||
compiler: clang
|
||||
cmake-args: -DMZ_CODE_COVERAGE=ON
|
||||
codecov: ubuntu_18_clang
|
||||
packages: llvm-6.0
|
||||
gcov-exec: llvm-cov-6.0 gcov
|
||||
|
||||
- name: Ubuntu 18 Clang No Zlib
|
||||
os: ubuntu-18.04
|
||||
compiler: clang
|
||||
cmake-args: -DMZ_CODE_COVERAGE=ON -DMZ_ZLIB=OFF
|
||||
codecov: ubuntu_18_clang_no_zlib
|
||||
packages: llvm-6.0
|
||||
gcov-exec: llvm-cov-6.0 gcov
|
||||
|
||||
- name: Ubuntu 18 Clang No Bzip2
|
||||
os: ubuntu-18.04
|
||||
compiler: clang
|
||||
cmake-args: -DMZ_CODE_COVERAGE=ON -DMZ_BZIP=OFF
|
||||
codecov: ubuntu_18_clang_no_bzip2
|
||||
packages: llvm-6.0
|
||||
gcov-exec: llvm-cov-6.0 gcov
|
||||
|
||||
- name: Ubuntu 18 Clang No LZMA
|
||||
os: ubuntu-18.04
|
||||
compiler: clang
|
||||
cmake-args: -DMZ_CODE_COVERAGE=ON -DMZ_LZMA=OFF
|
||||
codecov: ubuntu_18_clang_no_lzma
|
||||
packages: llvm-6.0
|
||||
gcov-exec: llvm-cov-6.0 gcov
|
||||
|
||||
- name: Ubuntu 18 Clang No Pkcrypt
|
||||
os: ubuntu-18.04
|
||||
compiler: clang
|
||||
cmake-args: -DMZ_CODE_COVERAGE=ON -DMZ_PKCRYPT=OFF
|
||||
codecov: ubuntu_18_clang_no_pkcrypt
|
||||
packages: llvm-6.0
|
||||
gcov-exec: llvm-cov-6.0 gcov
|
||||
|
||||
- name: Ubuntu 18 Clang No Winzip AES
|
||||
os: ubuntu-18.04
|
||||
compiler: clang
|
||||
cmake-args: -DMZ_CODE_COVERAGE=ON -DMZ_WZAES=OFF
|
||||
codecov: ubuntu_18_clang_no_winzip_aes
|
||||
packages: llvm-6.0
|
||||
gcov-exec: llvm-cov-6.0 gcov
|
||||
|
||||
- name: Ubuntu 18 Clang No Encryption
|
||||
os: ubuntu-18.04
|
||||
compiler: clang
|
||||
cmake-args: -DMZ_CODE_COVERAGE=ON -DMZ_PKCRYPT=OFF -DMZ_WZAES=OFF
|
||||
codecov: ubuntu_18_clang_no_encryption
|
||||
packages: llvm-6.0
|
||||
gcov-exec: llvm-cov-6.0 gcov
|
||||
|
||||
- name: Ubuntu 18 Clang Compress Only
|
||||
os: ubuntu-18.04
|
||||
compiler: clang
|
||||
cmake-args: -DMZ_CODE_COVERAGE=ON -DMZ_COMPRESS_ONLY=ON
|
||||
codecov: ubuntu_18_clang_compress_only
|
||||
packages: llvm-6.0
|
||||
gcov-exec: llvm-cov-6.0 gcov
|
||||
|
||||
- name: Ubuntu 18 Clang Decompress Only
|
||||
os: ubuntu-18.04
|
||||
compiler: clang
|
||||
cmake-args: -DMZ_CODE_COVERAGE=ON -DMZ_DECOMPRESS_ONLY=ON
|
||||
codecov: ubuntu_18_clang_decompress_only
|
||||
packages: llvm-6.0
|
||||
gcov-exec: llvm-cov-6.0 gcov
|
||||
|
||||
- name: Ubuntu 18 Clang OpenSSL
|
||||
os: ubuntu-18.04
|
||||
compiler: clang
|
||||
cmake-args: -DMZ_CODE_COVERAGE=ON -DMZ_OPENSSL=ON
|
||||
codecov: ubuntu_18_clang_openssl
|
||||
packages: llvm-6.0
|
||||
gcov-exec: llvm-cov-6.0 gcov
|
||||
|
||||
# No code coverage supported
|
||||
- name: Windows 2016 MSVC
|
||||
os: windows-2016
|
||||
compiler: cl
|
||||
deploy: true
|
||||
deploy-name: windows
|
||||
|
||||
- name: Windows 2016 GCC
|
||||
os: windows-2016
|
||||
compiler: gcc
|
||||
cmake-args: -DMZ_CODE_COVERAGE=ON -G Ninja
|
||||
codecov: windows_2016_gcc
|
||||
|
||||
# No code coverage supported
|
||||
- name: Windows 2019 MSVC
|
||||
os: windows-2019
|
||||
compiler: cl
|
||||
|
||||
- name: Windows 2019 GCC
|
||||
os: windows-2019
|
||||
compiler: gcc
|
||||
cmake-args: -DMZ_CODE_COVERAGE=ON -G Ninja
|
||||
codecov: windows_2019_gcc
|
||||
|
||||
# No code coverage on release builds
|
||||
- name: macOS Xcode 9.4.1
|
||||
os: macOS-latest
|
||||
version: "9.4.1"
|
||||
deploy: true
|
||||
deploy-name: macos_xcode_941
|
||||
|
||||
- name: macOS Xcode
|
||||
os: macOS-latest
|
||||
cmake-args: -DMZ_CODE_COVERAGE=ON
|
||||
codecov: macos_xcode
|
||||
|
||||
- name: macOS Xcode LibCompression
|
||||
os: macOS-latest
|
||||
cmake-args: -DMZ_CODE_COVERAGE=ON -DMZ_LIBCOMP=ON
|
||||
codecov: macos_xcode_libcompression
|
||||
|
||||
- name: macOS Xcode OpenSSL
|
||||
os: macOS-latest
|
||||
cmake-args: -DMZ_CODE_COVERAGE=ON -DMZ_OPENSSL=ON -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -DOPENSSL_INCLUDE_DIRS=/usr/local/opt/openssl/include -DOPENSSL_CRYPTO_LIBRARY=/usr/local/opt/openssl/lib/libcrypto.dylib -DOPENSSL_SSL_LIBRARY=/usr/local/opt/openssl/lib/libssl.dylib
|
||||
codecov: macos_xcode_openssl
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
|
||||
- name: Install packages (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
brew install pkgconfig ${{ matrix.packages }}
|
||||
|
||||
- name: Install packages (Ubuntu)
|
||||
if: runner.os == 'Linux' && matrix.packages
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install ${{ matrix.packages }}
|
||||
|
||||
- name: Install packages (Windows)
|
||||
if: runner.os == 'Windows' && matrix.codecov
|
||||
run: |
|
||||
choco install ninja
|
||||
|
||||
- name: Install packages (Windows/GCC)
|
||||
if: runner.os == 'Windows' && matrix.codecov && matrix.compiler == 'gcc'
|
||||
# Use gcov-7 via mingw on windows because gcov-8 throws tons of warnings
|
||||
# https://partner-bugzilla.redhat.com/show_bug.cgi?id=1577508
|
||||
run: |
|
||||
choco install mingw --version=7.3.0 --force --allow-downgrade
|
||||
|
||||
- name: Install codecov.io tools
|
||||
if: matrix.codecov
|
||||
# Need to use special fork of codecov-python for Windows
|
||||
# https://github.com/codecov/codecov-python/pull/169
|
||||
run: |
|
||||
python -u -m pip -v install git+https://github.com/nmoinvaz/codecov-python.git@master
|
||||
|
||||
- name: Generate project files
|
||||
run: |
|
||||
mkdir ${{ matrix.build-dir || '.not-used' }}
|
||||
cd ${{ matrix.build-dir || '.' }}
|
||||
cmake ${{ matrix.build-src-dir || '.' }} -DMZ_BUILD_TEST=ON -DMZ_BUILD_UNIT_TEST=ON -DCMAKE_BUILD_TYPE=Release ${{ matrix.cmake-args }}
|
||||
env:
|
||||
CC: ${{ matrix.compiler }}
|
||||
CFLAGS: ${{ matrix.cflags }}
|
||||
LDFLAGS: ${{ matrix.ldflags }}
|
||||
|
||||
- name: Compile source code
|
||||
run: |
|
||||
cd ${{ matrix.build-src-dir || '.' }}
|
||||
cmake --build . --config ${{ matrix.build-config || 'Release' }}
|
||||
|
||||
- name: Install test certificate (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain test/test.pem || true
|
||||
|
||||
- name: Install test certificate (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
run: |
|
||||
certutil -addstore -enterprise Root test/test.pem
|
||||
|
||||
- name: Run test cases
|
||||
run: |
|
||||
cd ${{ matrix.build-src-dir || '.' }}
|
||||
ctest --output-on-failure -C ${{ matrix.build-config || 'Release' }}
|
||||
# Specify test certificate for OpenSSL tests
|
||||
env:
|
||||
SSL_CERT_FILE: test.pem
|
||||
|
||||
- name: Upload coverage report
|
||||
if: matrix.codecov
|
||||
run: |
|
||||
cd ${{ matrix.build-src-dir || '.' }}
|
||||
python -m codecov -F "${{ matrix.codecov }}" --name "${{ matrix.name }}" --gcov-exec="${{ matrix.gcov-exec || 'gcov' }}"
|
||||
env:
|
||||
# Codecov integration does not yet support GitHub Actions
|
||||
CODECOV_TOKEN: "${{secrets.CODECOV_TOKEN}}"
|
||||
|
||||
- name: Package release (Ubuntu/macOS)
|
||||
if: (runner.os == 'Linux' || runner.os == 'macOS') && matrix.deploy && startsWith(github.ref, 'refs/tags/')
|
||||
run: |
|
||||
cd ${{ matrix.build-dir || '.' }}
|
||||
ls mini*zip_cmd libminizip* | tar -czvf minizip-${{ matrix.deploy-name }}.tar.gz -T -
|
||||
|
||||
- name: Upload release (Ubuntu/macOS)
|
||||
uses: svenstaro/upload-release-action@v1-release
|
||||
if: (runner.os == 'Linux' || runner.os == 'macOS') && matrix.deploy && startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
asset_name: minizip-${{ matrix.deploy-name }}.tar.gz
|
||||
file: ${{ matrix.build-dir || '.' }}/minizip-${{ matrix.deploy-name }}.tar.gz
|
||||
tag: ${{ github.ref }}
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
overwrite: true
|
||||
|
||||
- name: Package release (Windows)
|
||||
if: runner.os == 'Windows' && matrix.deploy && startsWith(github.ref, 'refs/tags/')
|
||||
run: |
|
||||
cd ${{ matrix.build-dir || '.' }}/${{ matrix.build-config || 'Release' }}
|
||||
7z a -tzip minizip-${{ matrix.deploy-name }}.zip *mini*zip*
|
||||
|
||||
- name: Upload release (Windows)
|
||||
uses: svenstaro/upload-release-action@v1-release
|
||||
if: runner.os == 'Windows' && matrix.deploy && startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
asset_name: minizip-${{ matrix.deploy-name }}.zip
|
||||
file: ${{ matrix.build-dir || '.' }}/${{ matrix.build-config || 'Release' }}/minizip-${{ matrix.deploy-name }}.zip
|
||||
tag: ${{ github.ref }}
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
overwrite: true
|
||||
|
||||
- name: Podspec (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
rm CMakeCache.txt
|
||||
cd ${{ matrix.build-dir || '.' }}
|
||||
cmake -G Xcode ${{ matrix.build-src-dir || '.' }}
|
||||
echo "target 'minizip' do pod 'Minizip', :path => '${{ matrix.build-src-dir || '.' }}'; platform :osx; end" > Podfile
|
||||
pod install
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
language: c
|
||||
|
||||
os:
|
||||
- linux
|
||||
|
||||
compiler:
|
||||
- clang
|
||||
- gcc
|
||||
|
||||
python:
|
||||
- "2.7"
|
||||
|
||||
before_install:
|
||||
- sudo apt-get install libbsd-dev
|
||||
- sudo pip install --upgrade pip
|
||||
- sudo pip install numpy
|
||||
|
||||
before_script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake .. -DBUILD_TEST=ON
|
||||
|
||||
script:
|
||||
- make
|
||||
- cd ../test
|
||||
- travis_wait 30 python test.py --exe_dir=../build
|
||||
+729
-190
File diff suppressed because it is too large
Load Diff
@@ -14,4 +14,4 @@ freely, subject to the following restrictions:
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
+38
-7
@@ -1,6 +1,6 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'Minizip'
|
||||
s.version = '2.3.6'
|
||||
s.version = '2.9.2'
|
||||
s.license = 'zlib'
|
||||
s.summary = 'Minizip contrib in zlib with the latest bug fixes and advanced features'
|
||||
s.description = <<-DESC
|
||||
@@ -13,25 +13,56 @@ DESC
|
||||
s.homepage = 'https://github.com/nmoinvaz/minizip'
|
||||
s.authors = 'Nathan Moinvaziri', 'Gilles Vollant'
|
||||
|
||||
s.source = { :git => 'https://github.com/nmoinvaz/minizip.git' }
|
||||
s.libraries = 'z'
|
||||
s.source = { :git => 'https://github.com/nmoinvaz/minizip.git', :tag => "#{s.version}" }
|
||||
s.libraries = 'z', 'iconv'
|
||||
s.default_subspecs = 'Core', 'PKCRYPT', 'WZAES_APPLE', 'BZIP2'
|
||||
|
||||
s.subspec 'Core' do |sp|
|
||||
sp.source_files = '{mz_os,mz_compat,mz_strm,mz_strm_mem,mz_strm_buf,mz_zip,mz_strm_crypt,mz_strm_posix,mz_strm_zlib}.{c,h}'
|
||||
sp.source_files = '{mz,mz_os,mz_os_posix,mz_compat,mz_crypt,mz_strm,mz_strm_mem,mz_strm_os,mz_strm_os_posix,mz_strm_buf,mz_strm_crypt,mz_strm_zlib,mz_zip,mz_zip_rw,mz_strm_split}.{c,h}'
|
||||
sp.pod_target_xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => 'HAVE_INTTYPES_H HAVE_STDINT_H HAVE_ZLIB' }
|
||||
end
|
||||
|
||||
s.subspec 'AES' do |sp|
|
||||
s.subspec 'PKCRYPT' do |sp|
|
||||
# Enables PKWARE traditional encryption
|
||||
sp.dependency 'Minizip/Core'
|
||||
sp.source_files = 'lib/aes/*.{c,h}', 'mz_strm_aes.{c,h}'
|
||||
sp.source_files = 'mz_strm_pkcrypt.{c,h}'
|
||||
sp.pod_target_xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => 'HAVE_PKCRYPT' }
|
||||
end
|
||||
|
||||
s.subspec 'WZAES_APPLE' do |sp|
|
||||
# Enables Apple's Security framework for AES
|
||||
sp.dependency 'Minizip/Core'
|
||||
sp.source_files = 'mz_strm_wzaes.{c,h}', 'mz_crypt_apple.c'
|
||||
sp.framework = 'Security'
|
||||
sp.pod_target_xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => 'HAVE_WZAES' }
|
||||
end
|
||||
|
||||
s.subspec 'WZAES_BRG' do |sp|
|
||||
# Enables Brian Gladman's encryption library for AES
|
||||
sp.dependency 'Minizip/Core'
|
||||
sp.source_files = 'lib/brg/*.{c,h}', 'mz_strm_wzaes.{c,h}', 'mz_crypt_brg.c'
|
||||
sp.pod_target_xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => 'HAVE_ARC4RANDOM_BUF HAVE_WZAES' }
|
||||
end
|
||||
|
||||
s.subspec 'BZIP2' do |sp|
|
||||
# Enables BZIP2 compression
|
||||
sp.dependency 'Minizip/Core'
|
||||
sp.source_files = 'lib/bzip2/*.{c,h}', 'mz_strm_bzip.{c,h}'
|
||||
sp.pod_target_xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => 'HAVE_BZIP2' }
|
||||
end
|
||||
|
||||
s.subspec 'BZIP2_SYSTEM' do |sp|
|
||||
# Enables system library BZIP2 compression
|
||||
sp.dependency 'Minizip/Core'
|
||||
sp.source_files = 'mz_strm_bzip.{c,h}'
|
||||
sp.libraries = 'bz2'
|
||||
sp.pod_target_xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => 'HAVE_BZIP2' }
|
||||
end
|
||||
|
||||
s.subspec 'LZMA' do |sp|
|
||||
# Enables LZMA compression
|
||||
sp.dependency 'Minizip/Core'
|
||||
sp.source_files = 'lib/liblzma/*.{c,h}', 'mz_strm_lzma.{c,h}'
|
||||
sp.source_files = 'lib/liblzma/**/*.{c,h}', 'mz_strm_lzma.{c,h}'
|
||||
sp.pod_target_xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => 'HAVE_LZMA' }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,204 +1,129 @@
|
||||
# Minizip 2.3.6
|
||||
|
||||
This library is a refactoring of the minizip contribution found in the zlib distribution and is supported on Windows, macOS, and Linux. The motivation for this work has been the inclusion of advanced features, improvements in code maintainability and readability, and the reduction of duplicate code. It is based on the original work of [Gilles Vollant](http://www.winimage.com/zLibDll/minizip.html) that has been contributed to by many people over the years.
|
||||
|
||||
Dev: 
|
||||
Master: 
|
||||
|
||||
For my older fork of this library checkout the [1.2](https://github.com/nmoinvaz/minizip/tree/1.2) branch.
|
||||
For the original work maintained by Mark Adler checkout the zlib minizip [contrib](https://github.com/madler/zlib/tree/master/contrib/minizip).
|
||||
|
||||
## Build
|
||||
|
||||
To generate project files for your platform:
|
||||
|
||||
1. [Download and install](https://cmake.org/install/) cmake.
|
||||
2. [Download](https://zlib.net/) and install zlib if it is not installed on your system.
|
||||
3. Run cmake in the minizip directory.
|
||||
|
||||
```
|
||||
cmake . -DBUILD_TEST=ON
|
||||
cmake --build .
|
||||
```
|
||||
|
||||
## Build Options
|
||||
|
||||
| Name | Description | Default Value |
|
||||
|:- |:-|:-:|
|
||||
| USE_ZLIB | Enables ZLIB compression | ON |
|
||||
| USE_BZIP2 | Enables BZIP2 compression | ON |
|
||||
| USE_LZMA | Enables LZMA compression | ON |
|
||||
| USE_PKCRYPT | Enables PKWARE traditional encryption | ON |
|
||||
| COMPRESS_ONLY | Only support compression | OFF |
|
||||
| DECOMPRESS_ONLY | Only support decompression | OFF |
|
||||
| BUILD_TEST | Builds minizip test executable | OFF |
|
||||
|
||||
## Zlib Installation (Windows)
|
||||
|
||||
Option 1. Install the zlib package to the Program Files directory with an Administrator command prompt.
|
||||
|
||||
```
|
||||
cmake . -DCMAKE_INSTALL_PREFIX=%PROGRAMFILES%\zlib
|
||||
cmake --build . --config Release --target INSTALL
|
||||
```
|
||||
|
||||
Option 2. Compile zlib in minizip's lib directory.
|
||||
|
||||
```
|
||||
cmake .
|
||||
cmake --build . --config Release
|
||||
```
|
||||
|
||||
Navigate back to the minizip directory and before building run:
|
||||
|
||||
```
|
||||
cmake . -DZLIB_LIBRARY=lib\zlib\release\zlibstatic.lib -DZLIB_INCLUDE_DIR=lib\zlib\
|
||||
```
|
||||
|
||||
## Contents
|
||||
|
||||
| File(s) | Description | Required |
|
||||
|:- |:-|:-:|
|
||||
| minizip.c | Sample application | No |
|
||||
| mz_compat.\* | Minizip 1.0 compatibility layer | No |
|
||||
| mz.h | Error codes and flags | Yes |
|
||||
| mz_os\* | OS specific helper functions | Encryption, Disk Splitting |
|
||||
| mz_strm.\* | Stream interface | Yes |
|
||||
| mz_strm_aes.\* | WinZIP AES stream | No |
|
||||
| mz_strm_buf.\* | Buffered stream | No |
|
||||
| mz_strm_bzip.\* | BZIP2 stream using libbzip2 | No |
|
||||
| mz_strm_crc32.\* | CRC32 stream | Yes |
|
||||
| mz_strm_lzma.\* | LZMA stream using liblzma | zlib or liblzma |
|
||||
| mz_strm_mem.\* | Memory stream | Yes |
|
||||
| mz_strm_split.\* | Disk splitting stream | No |
|
||||
| mz_strm_pkcrypt.\* | PKWARE traditional encryption stream | No |
|
||||
| mz_strm_posix.\* | File stream using Posix functions | Non-windows systems |
|
||||
| mz_strm_win32.\* | File stream using Win32 API functions | Windows systems |
|
||||
| mz_strm_zlib.\* | Deflate stream using zlib | zlib or liblzma |
|
||||
| mz_zip.\* | Zip functionality | Yes |
|
||||
|
||||
## Features
|
||||
|
||||
### Compression Methods
|
||||
|
||||
#### BZIP2
|
||||
|
||||
+ Requires ``cmake . -DUSE_BZIP2=ON`` or ``#define HAVE_BZIP2``
|
||||
+ Requires [BZIP2](http://www.bzip.org/) library
|
||||
|
||||
#### LZMA
|
||||
|
||||
+ Requires ``cmake . -DUSE_LZMA=ON`` or ``#define HAVE_LZMA``
|
||||
+ Requires [liblzma](https://tukaani.org/xz/) library
|
||||
|
||||
### Encryption
|
||||
|
||||
#### [WinZIP AES Encryption](https://www.winzip.com/aes_info.htm)
|
||||
|
||||
+ Requires ``cmake . -DUSE_AES=ON`` or ``#define HAVE_AES``
|
||||
+ Requires Brian Gladman's [AES](https://github.com/BrianGladman/aes) and [SHA](https://github.com/BrianGladman/sha) libraries
|
||||
|
||||
When zipping with a password it will always use AES 256-bit encryption.
|
||||
When unzipping it will use AES decryption only if necessary.
|
||||
|
||||
#### Disabling All Encryption
|
||||
|
||||
To disable encryption use the following cmake commands:
|
||||
|
||||
```
|
||||
cmake . -DUSE_AES=OFF
|
||||
cmake . -DUSE_PKCRYPT=OFF
|
||||
```
|
||||
|
||||
### NTFS Timestamps
|
||||
|
||||
Support has been added for UTC last modified, last accessed, and creation dates.
|
||||
|
||||
### Streams
|
||||
|
||||
This library has been refactored around streams.
|
||||
|
||||
#### Memory Streaming
|
||||
|
||||
To unzip from a zip file in memory pass the memory stream to the open function.
|
||||
```
|
||||
uint8_t *zip_buffer = NULL;
|
||||
int32_t zip_buffer_size = 0;
|
||||
void *mem_stream = NULL;
|
||||
|
||||
// fill zip_buffer with zip contents
|
||||
mz_stream_mem_create(&mem_stream);
|
||||
mz_stream_mem_set_buffer(mem_stream, zip_buffer, zip_buffer_size);
|
||||
mz_stream_open(mem_stream, NULL, MZ_OPEN_MODE_READ);
|
||||
|
||||
void *zip_handle = mz_zip_open(mem_stream, MZ_OPEN_MODE_READ);
|
||||
// do unzip operations
|
||||
|
||||
mz_stream_mem_delete(&mem_stream);
|
||||
```
|
||||
|
||||
To create a zip file in memory first create a growable memory stream and pass it to the open function.
|
||||
|
||||
```
|
||||
void *mem_stream = NULL;
|
||||
|
||||
mz_stream_mem_create(&mem_stream);
|
||||
mz_stream_mem_set_grow_size(mem_stream, (128 * 1024));
|
||||
mz_stream_open(mem_stream, NULL, MZ_OPEN_MODE_CREATE);
|
||||
|
||||
void *zip_handle = mz_zip_open(mem_stream, MZ_OPEN_MODE_WRITE);
|
||||
// do unzip operations
|
||||
|
||||
mz_stream_mem_delete(&mem_stream);
|
||||
```
|
||||
|
||||
For a complete example, see test_zip_mem() in [test.c](https://github.com/nmoinvaz/minizip/blob/master/test/test.c).
|
||||
|
||||
#### Buffered Streaming
|
||||
|
||||
By default the library will read bytes typically one at a time. The buffered stream allows for buffered read and write operations to improve I/O performance.
|
||||
|
||||
```
|
||||
void *stream = NULL;
|
||||
void *buf_stream = NULL;
|
||||
|
||||
mz_stream_os_create(&stream)
|
||||
// do open os stream
|
||||
|
||||
mz_stream_buffered_create(&buf_stream);
|
||||
mz_stream_buffered_open(buf_stream, NULL, MZ_OPEN_MODE_READ);
|
||||
mz_stream_buffered_set_base(buf_stream, stream);
|
||||
|
||||
void *zip_handle = mz_zip_open(buf_stream, MZ_OPEN_MODE_READ);
|
||||
```
|
||||
|
||||
#### Disk Splitting Stream
|
||||
|
||||
To create an archive with multiple disks use the disk splitting stream and supply a disk size value in bytes.
|
||||
|
||||
```
|
||||
void *stream = NULL;
|
||||
void *split_stream = NULL;
|
||||
|
||||
mz_stream_os_create(&stream);
|
||||
|
||||
mz_stream_split_create(&split_stream);
|
||||
mz_stream_split_set_prop_int64(split_stream, MZ_STREAM_PROP_DISK_SIZE, 64 * 1024);
|
||||
|
||||
mz_stream_set_base(split_stream, stream);
|
||||
|
||||
mz_stream_open(split_stream, path..
|
||||
|
||||
void *zip_handle = mz_zip_open(split_stream, MZ_OPEN_MODE_WRITE);
|
||||
```
|
||||
|
||||
### Windows RT
|
||||
|
||||
+ Requires ``#define MZ_WINRT_API``
|
||||
|
||||
## Limitations
|
||||
|
||||
+ Archives are required to have a central directory.
|
||||
+ Central directory header values should be correct and it is necessary for the compressed size to be accurate for AES encryption.
|
||||
+ Central directory encryption is not supported due to licensing restrictions mentioned by PKWARE in their zip appnote.
|
||||
+ Central directory is the only data stored on the last disk of a split-disk archive and doesn't follow disk size restrictions.
|
||||
# minizip 2.9.2
|
||||
|
||||
minizip is a zip manipulation library written in C that is supported on Windows, macOS, and Linux.
|
||||
|
||||
[](https://github.com/nmoinvaz/minizip/actions)
|
||||
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:minizip)
|
||||
[](https://www.codefactor.io/repository/github/nmoinvaz/minizip)
|
||||
[](https://github.com/nmoinvaz/minizip/blob/master/LICENSE)
|
||||
[](https://codecov.io/github/nmoinvaz/minizip/)
|
||||
|
||||
Developed and maintained by Nathan Moinvaziri.
|
||||
|
||||
## Branches
|
||||
|
||||
| Name | Description |
|
||||
|:- |:-|
|
||||
|[master](https://github.com/nmoinvaz/minizip/tree/master)|Modern rewrite that includes more advanced features, improvements in code maintainability and readability, and the reduction of duplicate code. Compatibility layer provided for older versions.|
|
||||
|[dev](https://github.com/nmoinvaz/minizip/tree/dev)|Latest development code|
|
||||
|[1.2](https://github.com/nmoinvaz/minizip/tree/1.2)|Drop-in replacement for zlib's minizip that includes WinZip AES encryption, disk splitting, I/O buffering and some additional fixes.|
|
||||
|[1.1](https://github.com/nmoinvaz/minizip/tree/1.1)|Original minizip as of zlib 1.2.11.|
|
||||
|
||||
## History
|
||||
|
||||
Minizip was originally developed by [Gilles Vollant](https://www.winimage.com/zLibDll/minizip.html) in 1998. It was first included in the zlib distribution as an additional code contribution starting in zlib 1.1.2. Since that time, it has been continually improved upon and contributed to by many people. The original [project](https://github.com/madler/zlib/tree/master/contrib/minizip) can still be found in the zlib distribution that is maintained by Mark Adler.
|
||||
|
||||
My work with the minizip library started in 2006 when I fixed a few bugs I found and submitted them to
|
||||
Gilles Vollant. In 2010, I implemented WinZip AES encryption, disk splitting, and
|
||||
I/O buffering that were necessary for another project I was working on. Shortly after, I created this public repository
|
||||
so I could share my improvements with the community. In early 2017, I began the work to refactor and rewrite
|
||||
the library as version 2 because it had become difficult to maintain and code readability suffered over the years.
|
||||
|
||||
## Features
|
||||
|
||||
+ Creating and extracting zip archives.
|
||||
+ Adding and removing entries from zip archives.
|
||||
+ Read and write raw zip entry data.
|
||||
+ Reading and writing zip archives from memory.
|
||||
+ Zlib, BZIP2, and LZMA compression methods.
|
||||
+ Password protection through Traditional PKWARE and [WinZIP AES](https://www.winzip.com/aes_info.htm) encryption.
|
||||
+ Buffered streaming for improved I/O performance.
|
||||
+ NTFS timestamp support for UTC last modified, last accessed, and creation dates.
|
||||
+ Disk split support for splitting zip archives into multiple files.
|
||||
+ Preservation of file attributes across file systems.
|
||||
+ Follow and store symbolic links.
|
||||
+ Unicode filename support through UTF-8 encoding.
|
||||
+ Legacy character encoding support CP437, CP932, CP936, CP950.
|
||||
+ Turn off compilation of compression, decompression, or encryption.
|
||||
+ Windows (Win32 & WinRT), macOS and Linux platform support.
|
||||
+ Streaming interface for easy implementation of additional platforms.
|
||||
+ Support for Apple's compression library ZLIB implementation.
|
||||
+ Zero out local file header information.
|
||||
+ Zip/unzip of central directory to reduce size.
|
||||
+ Ability to generate and verify CMS signature for each entry.
|
||||
+ Recover the central directory if it is corrupt or missing.
|
||||
+ Example minizip command line tool.
|
||||
|
||||
## Build
|
||||
|
||||
To generate project files for your platform:
|
||||
|
||||
1. [Download and install](https://cmake.org/install/) cmake (version 3.11 or later recommended).
|
||||
2. Run cmake in the minizip directory.
|
||||
|
||||
```
|
||||
cmake . -DMZ_BUILD_TEST=ON
|
||||
cmake --build .
|
||||
```
|
||||
|
||||
## Build Options
|
||||
|
||||
| Name | Description | Default Value |
|
||||
|:- |:-|:-:|
|
||||
| MZ_COMPAT | Enables compatibility layer | ON |
|
||||
| MZ_ZLIB | Enables ZLIB compression | ON |
|
||||
| MZ_BZIP2 | Enables BZIP2 compression | ON |
|
||||
| MZ_LZMA | Enables LZMA compression | ON |
|
||||
| MZ_PKCRYPT | Enables PKWARE traditional encryption | ON |
|
||||
| MZ_WZAES | Enables WinZIP AES encryption | ON |
|
||||
| MZ_LIBCOMP | Enables Apple compression | OFF |
|
||||
| MZ_OPENSSL | Enables OpenSSL encryption | OFF |
|
||||
| MZ_BRG | Enables Brian Gladman's library | OFF |
|
||||
| MZ_SIGNING | Enables zip signing support | ON |
|
||||
| MZ_COMPRESS_ONLY | Only support compression | OFF |
|
||||
| MZ_DECOMPRESS_ONLY | Only support decompression | OFF |
|
||||
| MZ_BUILD_TEST | Builds minizip test executable | OFF |
|
||||
| MZ_BUILD_UNIT_TEST | Builds minizip unit test project | OFF |
|
||||
| MZ_BUILD_FUZZ_TEST | Builds minizip fuzz executables | OFF |
|
||||
| MZ_CODE_COVERAGE | Build with code coverage flags | OFF |
|
||||
|
||||
## Contents
|
||||
|
||||
| File(s) | Description |
|
||||
|:- |:-|
|
||||
| minizip.c | Sample application |
|
||||
| mz_compat.\* | Minizip 1.x compatibility layer |
|
||||
| mz.h | Error codes and flags |
|
||||
| mz_os\* | Platform specific file/utility functions |
|
||||
| mz_crypt\* | Configuration specific crypto/hashing functions |
|
||||
| mz_strm.\* | Stream interface |
|
||||
| mz_strm_buf.\* | Buffered stream |
|
||||
| mz_strm_bzip.\* | BZIP2 stream using libbzip2 |
|
||||
| mz_strm_libcomp.\* | Apple compression stream |
|
||||
| mz_strm_lzma.\* | LZMA stream using liblzma |
|
||||
| mz_strm_mem.\* | Memory stream |
|
||||
| mz_strm_split.\* | Disk splitting stream |
|
||||
| mz_strm_pkcrypt.\* | PKWARE traditional encryption stream |
|
||||
| mz_strm_os\* | Platform specific file stream |
|
||||
| mz_strm_wzaes.\* | WinZIP AES stream |
|
||||
| mz_strm_zlib.\* | Deflate stream using zlib |
|
||||
| mz_zip.\* | Zip format |
|
||||
| mz_zip_rw.\* | Zip reader/writer |
|
||||
|
||||
## Third-Party Libraries
|
||||
|
||||
+ [zlib](https://zlib.net/) written by Mark Adler and Jean-loup Gailly.
|
||||
+ Not included in this repository
|
||||
+ Or alternatively, [zlib-ng](https://github.com/Dead2/zlib-ng) by Hans Kristian Rosbach
|
||||
+ [BZIP2](https://www.sourceware.org/bzip2/) written by Julian Seward.
|
||||
+ [liblzma](https://tukaani.org/xz/) written by Lasse Collin.
|
||||
+ Modifications were made to support the ZIP file format specification
|
||||
+ [AES](https://github.com/BrianGladman/aes) and [SHA](https://github.com/BrianGladman/sha) libraries of Brian Gladman.
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
Thanks go out to all the people who have taken the time to contribute code reviews, testing and/or patches. This project would not have been as good without you.
|
||||
|
||||
Thanks to [Gilles Vollant](https://www.winimage.com/zLibDll/minizip.html) on which this work is originally based on.
|
||||
|
||||
The [ZIP format](https://github.com/nmoinvaz/minizip/blob/master/doc/appnote.txt) was defined by Phil Katz of PKWARE.
|
||||
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
# Minizip Documentation <!-- omit in toc -->
|
||||
|
||||
- [API](#api)
|
||||
- [Limitations](#limitations)
|
||||
- [Zlib Configuration](#zlib-configuration)
|
||||
- [Upgrading from 1.x](#upgrading-from-1x)
|
||||
- [Security Considerations](#security-considerations)
|
||||
|
||||
## API
|
||||
|
||||
### Constants <!-- omit in toc -->
|
||||
|
||||
|Prefix|Description|
|
||||
|-|-|
|
||||
|[MZ_COMPRESS_LEVEL](mz_compress_level.md)|Compression level enumeration|
|
||||
|[MZ_ENCODING](mz_encoding.md)|Character encoding enumeration|
|
||||
|[MZ_ERROR](mz_error.md)|Error constants|
|
||||
|[MZ_HASH](mz_hash.md)|Hash algorithms and digest sizes
|
||||
|[MZ_HOST_SYSTEM](mz_host_system.md)|System identifiers|
|
||||
|[MZ_OPEN_MODE](mz_open_mode.md)|Stream open modes|
|
||||
|[MZ_SEEK](mz_seek.md)|Stream seek origins|
|
||||
|[MZ_ZIP64](mz_zip64.md)|Zip64 extrafield options|
|
||||
|
||||
### Interfaces <!-- omit in toc -->
|
||||
|
||||
|Name|Description|
|
||||
|-|-|
|
||||
|MZ_COMPAT|Old minizip 1.x compatibility layer|
|
||||
|[MZ_OS](mz_os.md)|Operating system level file system operations|
|
||||
|[MZ_ZIP](mz_zip.md)|Zip archive and entry interface |
|
||||
|[MZ_ZIP_RW](mz_zip_rw.md)|Easy zip file extraction and creation|
|
||||
|
||||
### Extrafield Proposals <!-- omit in toc -->
|
||||
|
||||
The zip reader and writer interface provides support for extended hash algorithms for zip entries, compression of the central directory, and the adding and verifying of CMS signatures for each entry. In order to add support for these features, extrafields were added and are described in the [minizip extrafield documentation](mz_extrafield.md).
|
||||
|
||||
## Limitations
|
||||
|
||||
+ Archives are required to have a central directory unless recovery mode is enabled.
|
||||
+ Central directory header values should be correct and it is necessary for the compressed size to be accurate for encryption.
|
||||
+ Central directory is the only data stored on the last disk of a split-disk archive and doesn't follow disk size restrictions.
|
||||
|
||||
### Third-Party Limitations <!-- omit in toc -->
|
||||
|
||||
* Windows Explorer zip extraction utility does not support disk splitting. [1](https://stackoverflow.com/questions/31286707/the-same-volume-can-not-be-used-as-both-the-source-and-destination)
|
||||
* macOS archive utility does not properly support ZIP files over 4GB. [1](http://web.archive.org/web/20140331005235/http://www.springyarchiver.com/blog/topic/topic/203) [2](https://bitinn.net/10716/)
|
||||
|
||||
## Zlib Configuration
|
||||
|
||||
By default, if zlib is not found, it will be pulled as an external project and installed. This requires [Git](https://git-scm.com/) to be installed and available to your command interpreter.
|
||||
|
||||
* To specify your own zlib repository use `ZLIB_REPOSITORY` and/or `ZLIB_TAG`.
|
||||
* To specify your own zlib installation use `ZLIB_LIBRARY` and `ZLIB_INCLUDE_DIR`.
|
||||
|
||||
**Compiling with Zlib-ng**
|
||||
|
||||
To compile using zlib-ng use the following cmake args:
|
||||
|
||||
```
|
||||
-DZLIB_REPOSITORY=https://github.com/Dead2/zlib-ng -DZLIB_TAG=develop
|
||||
```
|
||||
**Compiling and Installing Zlib (Windows)**
|
||||
|
||||
To compile and install zlib to the Program Files directory with an Administrator command prompt:
|
||||
|
||||
```
|
||||
cmake -DCMAKE_INSTALL_PREFIX="C:\Program Files (x86)\zlib" .
|
||||
cmake --build . --config Release --target INSTALL
|
||||
```
|
||||
**Configure Existing Zlib Installation (Windows)**
|
||||
|
||||
To configure cmake with an existing zlib installation point cmake to your install directories:
|
||||
|
||||
```
|
||||
cmake -DZLIB_LIBRARY:FILEPATH="C:\Program Files (x86)\zlib\lib\zlibstaticd.lib" .
|
||||
cmake -DZLIB_INCLUDE_DIR:PATH="C:\Program Files (x86)\zlib\include" .
|
||||
```
|
||||
|
||||
## Upgrading from 1.x
|
||||
|
||||
If you are using CMAKE it will automatically include all the files and define all the #defines
|
||||
required based on your configuration and it will also build the project files necessary for your platform.
|
||||
|
||||
However, for some projects it may be necessary to drop in the new files into an existing project. In that
|
||||
instance, some #defines will have to be set as they have changed.
|
||||
|
||||
|1.x|2.x|Description|
|
||||
|-|-|:-|
|
||||
||HAVE_ZLIB|Compile with ZLIB library. Older verisons of Minizip required ZLIB. It is now possible to alternatively compile only using liblzma library.|
|
||||
||HAVE_LZMA|Compile with LZMA support.|
|
||||
|HAVE_BZIP2|HAVE_BZIP2|Compile with BZIP2 library support.|
|
||||
|HAVE_APPLE_COMPRESSION|HAVE_LIBCOMP|Compile using Apple Compression library.|
|
||||
|HAVE_AES|HAVE_WZAES|Compile using AES encryption support.|
|
||||
||HAVE_PKCRYPT|Compile using PKWARE traditional encryption support. Previously this was automatically assumed.|
|
||||
|NOUNCRYPT|Nearest to MZ_ZIP_NO_ENCRYPTION|Previously turn off all decryption support.|
|
||||
|NOCRYPT|Nearest to MZ_ZIP_NO_ENCRYPTION|Previously turned off all encryption support.|
|
||||
||MZ_ZIP_NO_ENCRYPTION|Turns off all encryption/decryption support.|
|
||||
|NO_ADDFILEINEXISTINGZIP||Not currently supported.|
|
||||
|IOWIN32_USING_WINRT_API|MZ_WINRT_API|Enable WinRT API support in Win32 file I/O stream.|
|
||||
||MZ_ZIP_NO_COMPRESSION|Intended to reduce compilation size if not using zipping functionality.|
|
||||
||MZ_ZIP_NO_COMPRESSION|Intended to reduce compilation size if not using zipping functionality.|
|
||||
|
||||
At a minimum HAVE_ZLIB and HAVE_PKCRYPT will be necessary to be defined for drop-in replacement. To determine which files to drop in, see the Contents section of the [README](https://github.com/nmoinvaz/minizip/blob/master/README.md).
|
||||
|
||||
The compatibility layer for 1.x does not currently provide support for the `ioapi` interface; it has been replaced with a new streaming interface. It is possible to create a stream interface in a similar way that you would have created an ioapi interface.
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### WinZip AES <!-- omit in toc -->
|
||||
|
||||
When compressing an archive with WinZIP AES enabled, by default it uses 256 bit encryption. During decompression minizip will use whatever bit encryption was specified when the entry was added to the archive.
|
||||
|
||||
WinZip AES encryption uses CTR on top of ECB which prevents identical ciphertext blocks that might occur when using ECB by itself. More details about the WinZIP AES format can be found in the [winzip documentation](zip/winzip_aes.md).
|
||||
|
||||
### How to Create a Secure Zip <!-- omit in toc -->
|
||||
|
||||
In order to create a secure zip file you must:
|
||||
|
||||
* Use WinZIP AES encryption
|
||||
* Zip the central directory
|
||||
* Sign the zip file using a certificate
|
||||
|
||||
The combination of using AES encryption and zipping the central directory prevents data leakage through filename exposure.
|
||||
@@ -0,0 +1,10 @@
|
||||
# MZ_COMPRESS_LEVEL
|
||||
|
||||
Minizip compression level enumeration.
|
||||
|
||||
|Name|Code|Description|
|
||||
|-|-|-|
|
||||
|MZ_COMPRESS_LEVEL_DEFAULT|-1|Default compression level (6)|
|
||||
|MZ_COMPRESS_LEVEL_FAST|2|Fast compression level|
|
||||
|MZ_COMPRESS_LEVEL_NORMAL|6|Mid compression level|
|
||||
|MZ_COMPRESS_LEVEL_BEST|9|Slow compression level|
|
||||
@@ -0,0 +1,12 @@
|
||||
# MZ_COMPRESS_METHOD
|
||||
|
||||
Minizip compression method enumeration.
|
||||
|
||||
|Name|Code|Description|
|
||||
|-|-|-|
|
||||
|MZ_COMPRESS_METHOD_STORE|0|No compression|
|
||||
|MZ_COMPRESS_METHOD_DEFLATE|8|Deflate compression|
|
||||
|MZ_COMPRESS_METHOD_BZIP2|12|Bzip2 compression|
|
||||
|MZ_COMPRESS_METHOD_LZMA|14|LZMA1 compression|
|
||||
|
||||
_MZ_COMPRESS_METHOD_AES_ is only for internal use.
|
||||
@@ -0,0 +1,11 @@
|
||||
# MZ_ENCODING
|
||||
|
||||
Minizip character encoding enumeration. Older zip files may store the filename in a different character encoding.
|
||||
|
||||
|Name|Code|Description|
|
||||
|-|-|-|
|
||||
|MZ_ENCODING_CODEPAGE_437|437|[Code page 437](https://en.wikipedia.org/wiki/Code_page_437)|
|
||||
|MZ_ENCODING_CODEPAGE_932|932|[Code page 932](https://en.wikipedia.org/wiki/Code_page_932)|
|
||||
|MZ_ENCODING_CODEPAGE_936|936|[Code page 936](https://en.wikipedia.org/wiki/Code_page_936)|
|
||||
|MZ_ENCODING_CODEPAGE_950|950|[Code page 950](https://en.wikipedia.org/wiki/Code_page_950)|
|
||||
|MZ_ENCODING_CODEPAGE_UTF8|65001|[UTF-8](https://en.wikipedia.org/wiki/UTF-8)|
|
||||
@@ -0,0 +1,31 @@
|
||||
# MZ_ERROR
|
||||
|
||||
Minizip error enumeration. These errors codes are compatible with and extend zlib error codes.
|
||||
|
||||
|Name|Code|Description|
|
||||
|-|-|-|
|
||||
|MZ_OK|0|OK error (zlib)|
|
||||
|MZ_STREAM_ERROR|-1|Stream error (zlib)|
|
||||
|MZ_DATA_ERROR|-3|Data error (zlib)|
|
||||
|MZ_MEM_ERROR|-4|Memory allocation error (zlib)|
|
||||
|MZ_BUF_ERROR|-5|Buffer error (zlib)|
|
||||
|MZ_VERSION_ERROR|-6|Version error (zlib)|
|
||||
|MZ_END_OF_LIST|-100|End of list error|
|
||||
|MZ_END_OF_STREAM|-101|End of stream error|
|
||||
|MZ_PARAM_ERROR|-102|Invalid parameter error|
|
||||
|MZ_FORMAT_ERROR|-103|File format error|
|
||||
|MZ_INTERNAL_ERROR|-104|Library internal error|
|
||||
|MZ_CRC_ERROR|-105|CRC error|
|
||||
|MZ_CRYPT_ERROR|-106|Cryptography error|
|
||||
|MZ_EXIST_ERROR|-107|Does not exist error|
|
||||
|MZ_PASSWORD_ERROR|-108|Invalid password error|
|
||||
|MZ_SUPPORT_ERROR|-109|Library support error|
|
||||
|MZ_HASH_ERROR|-110|Hash error|
|
||||
|MZ_OPEN_ERROR|-111|Stream open error|
|
||||
|MZ_CLOSE_ERROR|-112|Stream close error|
|
||||
|MZ_SEEK_ERROR|-113|Stream seek error|
|
||||
|MZ_TELL_ERROR|-114|Stream tell error|
|
||||
|MZ_READ_ERROR|-115|Stream read error|
|
||||
|MZ_WRITE_ERROR|-116|Stream write error|
|
||||
|MZ_SIGN_ERROR|-117|Signing error|
|
||||
|MZ_SYMLINK_ERROR|-118|Symbolic link error|
|
||||
@@ -0,0 +1,12 @@
|
||||
# MZ_HASH
|
||||
|
||||
Minizip hash algorithm enumeration. The _mz_zip_reader_ and _mz_zip_writer_ instances support storing more secure hash algorithms for each zip entry.
|
||||
|
||||
|Name|Code|Description|
|
||||
|-|-|-|
|
||||
|MZ_HASH_MD5|10|MD5 algorithm identifier|
|
||||
|MZ_HASH_MD5_SIZE|16|MD5 digest size|
|
||||
|MZ_HASH_SHA1|20|SHA1 algorithm identifier|
|
||||
|MZ_HASH_SHA1_SIZE|20|SHA1 digest size|
|
||||
|MZ_HASH_SHA256|23|SHA256 algorithm identifer|
|
||||
|MZ_HASH_SHA256_SIZE|32|SHA256 digest size|
|
||||
@@ -0,0 +1,24 @@
|
||||
# MZ_HOST_SYSTEM
|
||||
|
||||
Minizip host system enumeration. These values correspond to section 4.4.2.2 of the [PKWARE zip app note](zip/appnote.txt).
|
||||
|
||||
|Name|Code|Description|
|
||||
|-|-|-|
|
||||
|MZ_HOST_SYSTEM_MSDOS|0|MS-DOS|
|
||||
|MZ_HOST_SYSTEM_UNIX|3|UNIX|
|
||||
|MZ_HOST_SYSTEM_WINDOWS_NTFS|10|Windows NTFS|
|
||||
|MZ_HOST_SYSTEM_RISCOS|13|RISC OS|
|
||||
|MZ_HOST_SYSTEM_OSX_DARWIN|19|Darwin|
|
||||
|
||||
The host system information is available in the _version_madeby_ field in _mz_zip_file_.
|
||||
|
||||
**Example**
|
||||
```
|
||||
mz_zip_file *file_info = NULL;
|
||||
mz_zip_entry_get_info(zip_handle, &file_info);
|
||||
int32_t host_sys = MZ_HOST_SYSTEM(file_info->version_madeby);
|
||||
printf("Host system value: %d\n", host_sys);
|
||||
if (host_sys == MZ_HOST_SYSTEM_MSDOS) {
|
||||
printf("Zip entry attributes are MS-DOS compatible\n");
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,12 @@
|
||||
# MZ_OPEN
|
||||
|
||||
Minizip stream open flag enumeration.
|
||||
|
||||
|Name|Code|Description|
|
||||
|-|-|-|
|
||||
|MZ_OPEN_MODE_READ|0x01|Open for reading|
|
||||
|MZ_OPEN_MODE_WRITE|0x02|Open for writing|
|
||||
|MZ_OPEN_MODE_READWRITE|0x03|Open for reading and writing|
|
||||
|MZ_OPEN_MODE_APPEND|0x04|Open for appending|
|
||||
|MZ_OPEN_MODE_CREATE|0x08|Open for creating|
|
||||
|MZ_OPEN_MODE_EXISTING|0x10|Open existing|
|
||||
+859
@@ -0,0 +1,859 @@
|
||||
# MZ_OS <!-- omit in toc -->
|
||||
|
||||
These functions provide support for handling common file system operations.
|
||||
|
||||
- [Path](#path)
|
||||
- [mz_path_combine](#mzpathcombine)
|
||||
- [mz_path_append_slash](#mzpathappendslash)
|
||||
- [mz_path_remove_slash](#mzpathremoveslash)
|
||||
- [mz_path_has_slash](#mzpathhasslash)
|
||||
- [mz_path_convert_slashes](#mzpathconvertslashes)
|
||||
- [mz_path_compare_wc](#mzpathcomparewc)
|
||||
- [mz_path_resolve](#mzpathresolve)
|
||||
- [mz_path_remove_filename](#mzpathremovefilename)
|
||||
- [mz_path_remove_extension](#mzpathremoveextension)
|
||||
- [mz_path_get_filename](#mzpathgetfilename)
|
||||
- [Directory](#directory)
|
||||
- [mz_dir_make](#mzdirmake)
|
||||
- [File](#file)
|
||||
- [mz_file_get_crc](#mzfilegetcrc)
|
||||
- [Operating System](#operating-system)
|
||||
- [mz_os_unicode_string_create](#mzosunicodestringcreate)
|
||||
- [mz_os_unicode_string_delete](#mzosunicodestringdelete)
|
||||
- [mz_os_utf8_string_create](#mzosutf8stringcreate)
|
||||
- [mz_os_utf8_string_delete](#mzosutf8stringdelete)
|
||||
- [mz_os_rand](#mzosrand)
|
||||
- [mz_os_rename](#mzosrename)
|
||||
- [mz_os_unlink](#mzosunlink)
|
||||
- [mz_os_file_exists](#mzosfileexists)
|
||||
- [mz_os_get_file_size](#mzosgetfilesize)
|
||||
- [mz_os_get_file_date](#mzosgetfiledate)
|
||||
- [mz_os_set_file_date](#mzossetfiledate)
|
||||
- [mz_os_get_file_attribs](#mzosgetfileattribs)
|
||||
- [mz_os_set_file_attribs](#mzossetfileattribs)
|
||||
- [mz_os_make_dir](#mzosmakedir)
|
||||
- [mz_os_open_dir](#mzosopendir)
|
||||
- [mz_os_read_dir](#mzosreaddir)
|
||||
- [mz_os_close_dir](#mzosclosedir)
|
||||
- [mz_os_is_dir](#mzosisdir)
|
||||
- [mz_os_is_symlink](#mzosissymlink)
|
||||
- [mz_os_make_symlink](#mzosmakesymlink)
|
||||
- [mz_os_read_symlink](#mzosreadsymlink)
|
||||
- [mz_os_ms_time](#mzosmstime)
|
||||
|
||||
## Path
|
||||
|
||||
The _mz_path_ family of functions are helper functions used when constructing file system paths.
|
||||
|
||||
### mz_path_combine
|
||||
|
||||
Combines two paths.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|char *|path|Base path|
|
||||
|const char *|join|Path to append|
|
||||
|int32_t|max_path|Maximum path buffer size|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|int32_t|[MZ_ERROR](mz_error.md) code, MZ_OK if successful|
|
||||
|
||||
**Example**
|
||||
```
|
||||
char path[120];
|
||||
strncat(path, "c:\\windows\\", sizeof(path));
|
||||
mz_path_combine(path, "temp", sizeof(path));
|
||||
printf("Combined path: %s\n", path);
|
||||
```
|
||||
|
||||
### mz_path_append_slash
|
||||
|
||||
Appends a path slash on to the end of the path. To get the path slash character for the compiler platform use _MZ_PATH_SLASH_PLATFORM_ preprocessor define.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|char *|path|Path|
|
||||
|int32_t|max_path|Maximum bytes to store path|
|
||||
|char|slash|Path slash character|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|int32_t|[MZ_ERROR](mz_error.md) code, MZ_OK if successful|
|
||||
|
||||
**Example**
|
||||
```
|
||||
char path[120];
|
||||
strncat(path, "c:\\windows", sizeof(path));
|
||||
mz_path_append_slash(path, sizeof(path), MZ_PATH_SLASH_PLATFORM);
|
||||
printf("Path with end slash: %s\n", path);
|
||||
```
|
||||
|
||||
### mz_path_remove_slash
|
||||
|
||||
Removes a path slash from the end of the path.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|char *|path|Path|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|int32_t|[MZ_ERROR](mz_error.md) code, MZ_OK if successful|
|
||||
|
||||
**Example**
|
||||
```
|
||||
char path[120];
|
||||
strncat(path, "c:\\windows\\", sizeof(path));
|
||||
mz_path_remove_slash(path);
|
||||
printf("Path with no slash: %s\n", path);
|
||||
```
|
||||
|
||||
### mz_path_has_slash
|
||||
|
||||
Returns whether or not the path ends with slash.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|const char *|path|Path|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|int32_t|[MZ_ERROR](mz_error.md) code, MZ_OK if has slash.|
|
||||
|
||||
**Example**
|
||||
```
|
||||
const char *path = "c:\\windows\\";
|
||||
if (mz_path_has_slash(path) == MZ_OK)
|
||||
printf("Path ends with a slash\n");
|
||||
else
|
||||
printf("Path does not end with a slash\n");
|
||||
```
|
||||
|
||||
### mz_path_convert_slashes
|
||||
|
||||
Converts the slashes in a path. This can be used to convert all unix path slashes to windows path slashes or conver all windows path slashes to unix path slashes. If there are mixed slashes in the path, it can unify them to all one format.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|char *|path|Path|
|
||||
|char|slash|Path slash character|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|int32_t|[MZ_ERROR](mz_error.md) code, MZ_OK if has slash.|
|
||||
|
||||
**Example**
|
||||
```
|
||||
char path[120];
|
||||
strncat(path, "c:\\windows\\", sizeof(path));
|
||||
if (mz_path_convert_slashes(path, MZ_PATH_SLASH_UNIX) == MZ_OK)
|
||||
printf("Path converted to unix slashes: %s\n", path);
|
||||
```
|
||||
|
||||
### mz_path_compare_wc
|
||||
|
||||
Compares two paths with a wildcard.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|const char *|path|Path|
|
||||
|const char *|wildcard|Wildcard pattern|
|
||||
|uint8_t|ignore_case|Ignore case during comparison if 1.|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|int32_t|[MZ_ERROR](mz_error.md) code, MZ_OK if matched, MZ_EXIST_ERROR if not matched.|
|
||||
|
||||
**Example**
|
||||
```
|
||||
const char *path = "test.txt";
|
||||
if (mz_path_compare_wc(path, "*.txt", 0) == MZ_OK)
|
||||
printf("%s is a text file\n", path);
|
||||
else
|
||||
printf("%s is not a text file\n", path);
|
||||
```
|
||||
|
||||
### mz_path_resolve
|
||||
|
||||
Resolves a path. Path parts that only contain dots will be resolved. If a path part contains a single dot, it will be remoed. If a path part contains two dots, it will remove the last path part. This function can be used to prevent the _zipslip_ vulnerability and ensure that files are not written outside of their intended target.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|const char *|path|Path|
|
||||
|char *|target|Resolved path character array|
|
||||
|int32_t|max_target|Maximum size of resolved path array|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|int32_t|[MZ_ERROR](mz_error.md) code, MZ_OK if successful|
|
||||
|
||||
**Example**
|
||||
```
|
||||
const char *path = "c:\\windows\\..\\";
|
||||
char target[120];
|
||||
mz_path_resolve(path, target, sizeof(target));
|
||||
printf("Resolved path: %s\n", target);
|
||||
```
|
||||
|
||||
### mz_path_remove_filename
|
||||
|
||||
Removes the filename from a path.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|char *|path|Path|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|int32_t|[MZ_ERROR](mz_error.md) code, MZ_OK if successful|
|
||||
|
||||
**Example**
|
||||
```
|
||||
char path[120];
|
||||
strncpy(path, "c:\\windows\\test.txt", sizeof(path));
|
||||
printf("Path: %s\n", path);
|
||||
mz_path_remove_filename(path);
|
||||
printf("Path with no filename: %s\n", path);
|
||||
```
|
||||
|
||||
### mz_path_remove_extension
|
||||
|
||||
Remove the extension from a path.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|char *|path|Path|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|int32_t|[MZ_ERROR](mz_error.md) code, MZ_OK if successful|
|
||||
|
||||
**Example**
|
||||
```
|
||||
char path[120];
|
||||
strncpy(path, "c:\\windows\\test.txt", sizeof(path));
|
||||
printf("Path: %s\n", path);
|
||||
mz_path_remove_extension(path);
|
||||
printf("Path with no file extension: %s\n", path);
|
||||
```
|
||||
|
||||
### mz_path_get_filename
|
||||
|
||||
Get the filename from a path.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|const char *|path|Path|
|
||||
|const char **|filename|Pointer to filename string|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|int32_t|[MZ_ERROR](mz_error.md) code, MZ_OK if successful|
|
||||
|
||||
**Example**
|
||||
```
|
||||
const char *path = "c:\\windows\\test.txt";
|
||||
const char *filename = NULL;
|
||||
printf("Path: %s\n", path);
|
||||
if (mz_path_get_filename(path, &filename) == MZ_OK)
|
||||
printf("Filename: %s\n", filename);
|
||||
else
|
||||
printf("Path has no filename\n");
|
||||
```
|
||||
|
||||
## Directory
|
||||
|
||||
### mz_dir_make
|
||||
|
||||
Creates a directory recursively.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|const char *|path|Path|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|int32_t|[MZ_ERROR](mz_error.md) code, MZ_OK if successful|
|
||||
|
||||
**Example**
|
||||
```
|
||||
const char *path = "c:\\temp\\x\\y\\z\\";
|
||||
if (mz_dir_make(path) == MZ_OK)
|
||||
printf("Dir was created: %s\n", path);
|
||||
else
|
||||
printf("Dir was not created: %s\n", path);
|
||||
```
|
||||
|
||||
## File
|
||||
|
||||
### mz_file_get_crc
|
||||
|
||||
Gets the crc32 hash of a file. This function helps provide functional backwards compatibility.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|const char *|path|Path to calculate CRC value for|
|
||||
|uint32_t *|result_crc|Pointer to store the calculated CRC value|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|int32_t|[MZ_ERROR](mz_error.md) code, MZ_OK if successful|
|
||||
|
||||
**Example**
|
||||
```
|
||||
const char *path = "c:\\temp\\test.txt";
|
||||
uint32_t crc = 0;
|
||||
if (mz_file_get_crc(path, &crc) == MZ_OK)
|
||||
printf("File %s CRC: %08x\n", path, crc);
|
||||
else
|
||||
printf("Failed to calculate CRC: %s\n", path);
|
||||
```
|
||||
|
||||
## Operating System
|
||||
|
||||
The _mz_os_ family of functions wrap all platform specific code necessary to zip and unzip files.
|
||||
|
||||
### mz_os_unicode_string_create
|
||||
|
||||
Create unicode string from a string with another encoding.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|const char *|string|String to convert|
|
||||
|int32_t|encoding|String encoding (See [MZ_ENCODING](mz_encoding.md))|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|wchar_t *|Returns pointer to unicode string if successful, otherwise NULL.|
|
||||
|
||||
**Example**
|
||||
```
|
||||
char *test = "test";
|
||||
wchar_t *test_unicode = mz_os_unicode_string_create(test, MZ_ENCODING_UTF8);
|
||||
if (test_unicode != NULL) {
|
||||
printf("Unicode test string created\n");
|
||||
mz_os_unicode_string_delete(&test_unicode);
|
||||
}
|
||||
```
|
||||
|
||||
### mz_os_unicode_string_delete
|
||||
|
||||
Delete a unicode string that was created with _mz_os_unicode_string_create_.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|wchar_t **|string|Pointer to unicode string|
|
||||
|
||||
**Example**
|
||||
```
|
||||
char *test = "test";
|
||||
wchar_t *test_unicode = mz_os_unicode_string_create(test, MZ_ENCODING_UTF8);
|
||||
if (test_unicode != NULL) {
|
||||
printf("Unicode test string created\n");
|
||||
mz_os_unicode_string_delete(&test_unicode);
|
||||
}
|
||||
```
|
||||
|
||||
### mz_os_utf8_string_create
|
||||
|
||||
Create a utf8 string from a string with another encoding.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|const char *|string|String to convert|
|
||||
|int32_t|encoding|String encoding (See [MZ_ENCODING](mz_encoding.md))|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|uint8_t *|Returns pointer to UTF-8 encoded string if successful, otherwise NULL.|
|
||||
|
||||
**Example**
|
||||
```
|
||||
char *test = "test";
|
||||
wchar_t *test_utf8 = mz_os_utf8_string_create(test, MZ_ENCODING_CODEPAGE_437);
|
||||
if (test_utf8 != NULL) {
|
||||
printf("UTF-8 test string created\n");
|
||||
mz_os_utf8_string_create(&test_utf8);
|
||||
}
|
||||
```
|
||||
|
||||
### mz_os_utf8_string_delete
|
||||
|
||||
Delete a utf8 string that was created with _mz_os_utf8_string_create_.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|uint8_t **|string|Pointer to utf8 encoded string|
|
||||
|
||||
**Example**
|
||||
```
|
||||
char *test = "test";
|
||||
wchar_t *test_utf8 = mz_os_utf8_string_create(test, MZ_ENCODING_CODEPAGE_437);
|
||||
if (test_utf8 != NULL) {
|
||||
printf("UTF-8 test string created\n");
|
||||
mz_os_utf8_string_create(&test_utf8);
|
||||
}
|
||||
```
|
||||
|
||||
### mz_os_rand
|
||||
|
||||
Random number generator (not cryptographically secure). For a cryptographically secure random number generator use _mz_crypt_rand_.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|uint8_t *|buf|Buffer to fill with random data|
|
||||
|int32_t|size|Maximum size of buffer array|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|int32_t|[MZ_ERROR](mz_error.md) code, MZ_OK if successful|
|
||||
|
||||
**Example**
|
||||
```
|
||||
uint8_t buf[120];
|
||||
if (mz_os_rand(buf, sizeof(buf)) == MZ_OK)
|
||||
printf("%d bytes of random data generated\n", sizeof(buf));
|
||||
```
|
||||
|
||||
### mz_os_rename
|
||||
|
||||
Rename a file.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|const char *|source_path|Original path|
|
||||
|const char *|target_path|New path|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|int32_t|[MZ_ERROR](mz_error.md) code, MZ_OK if successful|
|
||||
|
||||
**Example**
|
||||
```
|
||||
if (mz_os_rename("c:\\test1.txt", "c:\\test2.txt") == MZ_OK)
|
||||
printf("File was renamed successfully\n");
|
||||
```
|
||||
|
||||
### mz_os_unlink
|
||||
|
||||
Delete an existing file.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|const char *|path|File path|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|int32_t|[MZ_ERROR](mz_error.md) code, MZ_OK if successful|
|
||||
|
||||
**Example**
|
||||
```
|
||||
if (mz_os_unlink("c:\\test2.txt") == MZ_OK)
|
||||
printf("File was deleted successfully\n");
|
||||
```
|
||||
|
||||
### mz_os_file_exists
|
||||
|
||||
Check to see if a file exists.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|const char *|path|File path|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|int32_t|[MZ_ERROR](mz_error.md) code, MZ_OK if successful|
|
||||
|
||||
**Example**
|
||||
```
|
||||
const char *path = "c:\\test2.txt";
|
||||
if (mz_os_file_exists(path) == MZ_OK)
|
||||
printf("File %s exists\n", path);
|
||||
else
|
||||
printf("File %s does not exist\n", path);
|
||||
```
|
||||
|
||||
### mz_os_get_file_size
|
||||
|
||||
Gets the length of a file.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|const char *|path|File path|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|int64_t|Size of file, does not check for existence of file.|
|
||||
|
||||
**Example**
|
||||
```
|
||||
const char *path = "c:\\test3.txt";
|
||||
if (mz_os_file_exists(path) == MZ_OK) {
|
||||
int64_t file_size = mz_os_get_file_size(path);
|
||||
printf("File %s size %lld\n", path, file_size);
|
||||
} else {
|
||||
printf("File %s does not exist\n", path);
|
||||
}
|
||||
```
|
||||
|
||||
### mz_os_get_file_date
|
||||
|
||||
Gets a file's modified, access, and creation dates if supported. Creation date is not supported on Linux based systems and zero is returned for _creation_date_ on those systems.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|const char *|path|File path|
|
||||
|time_t *|modified_date|Pointer to store file's modified unix timestamp|
|
||||
|time_t *|accessed_date|Pointer to store file's accessed unix timestamp|
|
||||
|time_t *|creation_date|Pointer to store file's creation unix timestamp|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|int32_t|[MZ_ERROR](mz_error.md) code, MZ_OK if successful|
|
||||
|
||||
**Example**
|
||||
```
|
||||
const char *path = "c:\\test4.txt";
|
||||
time_t modified_date, accessed_date, creation_date;
|
||||
if (mz_os_get_file_date(path, &modified_date, &accessed_date, &creation_date) == MZ_OK)
|
||||
printf("File %s modified %lld accessed %lld creation %lld\n", path, modified_date, accessed_date, creation_date);
|
||||
```
|
||||
|
||||
### mz_os_set_file_date
|
||||
|
||||
Sets a file's modified, access, and creation dates if supported. Creation date is not supported on Linux based systems.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|const char *|path|File path|
|
||||
|time_t|modified_date|File's modified unix timestamp|
|
||||
|time_t|accessed_date|File's accessed unix timestamp|
|
||||
|time_t|creation_date|File's creation unix timestamp|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|int32_t|[MZ_ERROR](mz_error.md) code, MZ_OK if successful|
|
||||
|
||||
**Example**
|
||||
```
|
||||
const char *src_path = "c:\\test4.txt";
|
||||
const char *target_path = "c:\\test5.txt";
|
||||
time_t modified_date, accessed_date, creation_date;
|
||||
if (mz_os_get_file_date(src_path, &modified_date, &accessed_date, &creation_date) == MZ_OK) {
|
||||
printf("Source file %s modified %lld accessed %lld creation %lld\n", path, modified_date, accessed_date, creation_date);
|
||||
if (mz_os_set_file_date(target_path, modified_date, accessed_date, creation_date) == MZ_OK) {
|
||||
printf("Target file dates changed successfully\n");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### mz_os_get_file_attribs
|
||||
|
||||
Gets a file's attributes.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|const char *|path|File path|
|
||||
|uint32_t *|attributes|Pointer to store file attributes value|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|int32_t|[MZ_ERROR](mz_error.md) code, MZ_OK if successful|
|
||||
|
||||
**Example**
|
||||
```
|
||||
const char *path = "c:\\test6.txt";
|
||||
uint32_t attributes = 0;
|
||||
if (mz_os_get_file_attribs(path, &attributes) == MZ_OK)
|
||||
printf("File %s attributes %08x\n", attributes);
|
||||
```
|
||||
|
||||
### mz_os_set_file_attribs
|
||||
|
||||
Sets a file's attributes.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|const char *|path|File path|
|
||||
|uint32_t|attributes|File attributes value|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|int32_t|[MZ_ERROR](mz_error.md) code, MZ_OK if successful|
|
||||
|
||||
**Example**
|
||||
```
|
||||
const char *path = "c:\\test6.txt";
|
||||
uint32_t attributes = 0;
|
||||
if (mz_os_get_file_attribs(path, &attributes) == MZ_OK) {
|
||||
printf("File %s attributes %08x\n", attributes);
|
||||
attributes |= FILE_ATTRIBUTE_READONLY;
|
||||
if (mz_os_set_file_attribs(path, attributes) == MZ_OK) {
|
||||
printf("File changed to readonly\n");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### mz_os_make_dir
|
||||
|
||||
Creates a directory. To recursively create a directory use _mz_dir_make_.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|const char *|path|Directory path|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|int32_t|[MZ_ERROR](mz_error.md) code, MZ_OK if successful|
|
||||
|
||||
**Example**
|
||||
```
|
||||
if (mz_os_make_dir("c:\\testdir\\") == MZ_OK)
|
||||
printf("Test directory created\n");
|
||||
```
|
||||
|
||||
### mz_os_open_dir
|
||||
|
||||
Opens a directory for listing.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|const char *|path|Directory path|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|DIR *|Directory enumeration handle, returns NULL if error.|
|
||||
|
||||
**Example**
|
||||
```
|
||||
const char *search_dir = "c:\\test1\\";
|
||||
DIR *dir = mz_open_dir(search_dir);
|
||||
if (dir != NULL) {
|
||||
printf("Dir %s was opened\n", search_dir);
|
||||
mz_os_close_dir(dir);
|
||||
}
|
||||
```
|
||||
|
||||
### mz_os_read_dir
|
||||
|
||||
Reads a directory listing entry.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|DIR *|dir|Directory enumeration handle|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|struct dirent *|Pointer to directory entry information structure. To get the name of the directory use the _d_name_ structure field.|
|
||||
|
||||
**Example**
|
||||
```
|
||||
const char *search_dir = "c:\\test2\\";
|
||||
DIR *dir = mz_open_dir(search_dir);
|
||||
if (dir != NULL) {
|
||||
struct dirent *entry = NULL;
|
||||
printf("Dir %s was opened\n", search_dir);
|
||||
while ((entry = mz_os_read_dir(dir)) != NULL) {
|
||||
printf("Dir entry: %s was opened\n", entry->d_name);
|
||||
}
|
||||
mz_os_close_dir(dir);
|
||||
}
|
||||
```
|
||||
|
||||
### mz_os_close_dir
|
||||
|
||||
Closes a directory that has been opened for listing.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|DIR *|dir|Directory enumeration handle|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|int32_t|[MZ_ERROR](mz_error.md) code, MZ_OK if successful|
|
||||
|
||||
**Example**
|
||||
```
|
||||
const char *search_dir = "c:\\test3\\";
|
||||
DIR *dir = mz_open_dir(search_dir);
|
||||
if (dir != NULL) {
|
||||
struct dirent *entry = NULL;
|
||||
printf("Dir %s was opened\n", search_dir);
|
||||
while ((entry = mz_os_read_dir(dir)) != NULL) {
|
||||
printf("Dir entry: %s was opened\n", entry->d_name);
|
||||
}
|
||||
mz_os_close_dir(dir);
|
||||
}
|
||||
```
|
||||
|
||||
### mz_os_is_dir
|
||||
|
||||
Checks to see if path is a directory.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|const char *|path|File system path|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|int32_t|[MZ_ERROR](mz_error.md) code, MZ_OK if it is a directory.|
|
||||
|
||||
**Example**
|
||||
```
|
||||
const char *path = "c:\\test7.txt";
|
||||
if (mz_os_is_dir(path) == MZ_OK)
|
||||
printf("Path %s is a directory\n", path);
|
||||
else
|
||||
printf("Path %s is not a directory\n", path);
|
||||
```
|
||||
|
||||
### mz_os_is_symlink
|
||||
|
||||
Checks to see if path is a symbolic link.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|const char *|path|File system path|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|int32_t|[MZ_ERROR](mz_error.md) code, MZ_OK if it is a symbolic link.|
|
||||
|
||||
**Example**
|
||||
```
|
||||
const char *path = "c:\\test7.txt";
|
||||
if (mz_os_is_symlink(path) == MZ_OK)
|
||||
printf("Path %s is a symbolic link\n", path);
|
||||
else
|
||||
printf("Path %s is not a symbolic link\n", path);
|
||||
```
|
||||
|
||||
### mz_os_make_symlink
|
||||
|
||||
Creates a symbolic link pointing to a target.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|const char *|path|Link path|
|
||||
|const char *|target_path|Actual path|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|int32_t|[MZ_ERROR](mz_error.md) code, MZ_OK if successful|
|
||||
|
||||
**Example**
|
||||
```
|
||||
const char *path = "c:\\test7.txt";
|
||||
const char *target_path = "c:\\test8.txt";
|
||||
if (mz_os_make_symlink(path, target_path) == MZ_OK)
|
||||
printf("Symbolic link created at %s pointing to %s\n", path, target_path);
|
||||
```
|
||||
|
||||
### mz_os_read_symlink
|
||||
|
||||
Gets the target path for a symbolic link.
|
||||
|
||||
**Arguments**
|
||||
|Type|Name|Description|
|
||||
|-|-|-|
|
||||
|const char *|path|Link path|
|
||||
|char *|target_path|Actual path|
|
||||
|int32_t|max_path|Maximum bytes to store actual path|
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|int32_t|[MZ_ERROR](mz_error.md) code, MZ_OK if successful|
|
||||
|
||||
**Example**
|
||||
```
|
||||
const char *path = "c:\\test7.txt";
|
||||
const char *target_path = "c:\\test8.txt";
|
||||
if (mz_os_make_symlink(path, target_path) == MZ_OK) {
|
||||
char actual_path[120];
|
||||
printf("Symbolic link created at %s pointing to %s\n", path, target_path);
|
||||
if (mz_os_read_symlink(path, actual_path, sizeof(actual_path)) == MZ_OK) {
|
||||
if (strcmp(target_path, actual_path) == 0) {
|
||||
printf("Confirmed symbolic link created\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### mz_os_ms_time
|
||||
|
||||
Gets the time in milliseconds.
|
||||
|
||||
**Return**
|
||||
|Type|Description|
|
||||
|-|-|
|
||||
|uint64_t|Current time in milliseconds|
|
||||
|
||||
**Example**
|
||||
```
|
||||
uint64_t current_time = mz_os_ms_time();
|
||||
printf("Current time in %lldms\n", current_time);
|
||||
```
|
||||
@@ -0,0 +1,9 @@
|
||||
# MZ_SEEK
|
||||
|
||||
Minizip stream seek origin enumeration.
|
||||
|
||||
|Name|Code|Description|
|
||||
|-|-|-|
|
||||
|MZ_SEEK_SET|0|Seek from beginning|
|
||||
|MZ_SEEK_CUR|1|Seek from current position|
|
||||
|MZ_SEEK_END|2|Seek from end|
|
||||
+1520
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,9 @@
|
||||
# MZ_ZIP64
|
||||
|
||||
Minizip zip64 mode enumeration. The zip64 extension is documented in [PKWARE zip app note](zip/appnote.txt) section 4.5.3 and provides support for zip files and entries greater than 4GB. These modes are only supported while writing a zip entry.
|
||||
|
||||
|Name|Code|Description|
|
||||
|-|-|-|
|
||||
|MZ_ZIP64_AUTO|0|Only store and use zip64 extrafield if compressed size, uncompressed size, or disk offset is greater than -UINT32_MAX_.|
|
||||
|MZ_ZIP64_FORCE|1|Always use and store zip64 extrafield even if it is not necessary.|
|
||||
|MZ_ZIP64_DISABLE|2|Never use or store zip64 extrafield. If zip64 is required to write the entry it will result in MZ_PARAM_ERROR.|
|
||||
@@ -0,0 +1,29 @@
|
||||
# MZ_ZIP_FILE
|
||||
|
||||
Minizip zip entry information structure. The _mz_zip_file_ structure can be populated and used for writing zip entry information. When retrieving information about a zip entry, it will be populated with the zip entry's information.
|
||||
|
||||
|Type|Name|Description|[PKWARE zip app note](zip/appnote.txt) section|
|
||||
|-|-|-|-|
|
||||
|uint16_t|version_madeby|Version made by field|4.4.2|
|
||||
|uint16_t|version_needed|Version needed to extract|4.4.3|
|
||||
|uint16_t|flag|General purpose bit flag|4.4.4|
|
||||
|uint16_t|compression_method|Compression method|4.4.5|
|
||||
|time_t|modified_date|Last modified unix timestamp|4.4.6, 4.5.5, 4.5.7|
|
||||
|time_t|accessed_date|Last accessed unix timestamp|4.5.5, 4.5.7|
|
||||
|time_t|creation_date|Creation date unix timestamp|4.5.5|
|
||||
|uint32_t|crc|CRC-32 hash|4.4.7|
|
||||
|int64_t|compressed_size|Compressed size|4.4.8|
|
||||
|int64_t|uncompressed_size|Uncompressed size|4.4.9|
|
||||
|uint16_t|filename_size|Filename length|4.4.10|
|
||||
|uint16_t|extrafield_size|Extrafield length|4.4.11|
|
||||
|uint16_t|comment_size|Comment size|4.4.12|
|
||||
|uint32_t|disk_number|Starting disk number|4.4.13|
|
||||
|int64_t|disk_offset|Starting disk offset|4.4.16|
|
||||
|uint16_t|internal_fa|Internal file attributes|4.4.14|
|
||||
|uint16_t|external_fa|External file attributes|4.4.15|
|
||||
|const char *|filename|Filename UTF-8 null-terminated string|4.4.17|
|
||||
|const uint8_t *|extrafield|Extrafield buffer array|4.4.28|
|
||||
|const char *|comment|Comment UTF-8 null-terminated string|4.4.18|
|
||||
|uint16_t|zip64|Zip64 extension mode|[MZ_ZIP64](mz_zip64)|
|
||||
|uint16_t|aes_version|WinZip AES version|[WinZip AES App Note](zip/winzip_aes.md)|
|
||||
|uint16_t|aes_encryption_mode|WinZip AES encryption mode|[WinZip AES App Note](zip/winzip_aes.md)|
|
||||
+2053
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+3497
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,261 @@
|
||||
|
||||
# AES Encryption Information:
|
||||
Encryption Specification AE-1 and AE-2
|
||||
|
||||
**Document version: 1.04
|
||||
Last modified: January 30, 2009**
|
||||
|
||||
**NOTE: WinZip® users do not need to read or understand the information contained on this page. It is intended for developers of Zip file utilities.**
|
||||
|
||||
Changes since the original version of this document are summarized in the [Change History](https://www.winzip.com/aes_info.htm#changes) section below.
|
||||
|
||||
This document describes the file format that WinZip uses to create [AES-encrypted Zip files](https://www.winzip.com/learn/aes-encryption.html). The AE-1 encryption specification was introduced in WinZip 9.0 Beta 1, released in May 2003. The AE-2 encryption specification, a minor variant of the original AE-1 specification differing only in how the CRC is handled, was introduced in WinZip 9.0 Beta 3, released in January, 2004. Note that as of WinZip 11, WinZip itself encrypts most files using the AE-1 format and encrypts others using the AE-2 format.
|
||||
|
||||
From time to time we may update the information provided here, for example to document any changes to the file formats, or to add additional notes or implementation tips. If you would like to receive e-mail announcements of any substantive changes we make to this document, you can [sign up below](https://www.winzip.com/aes_info.htm#mailing-list)for our Developer Information mailing list.
|
||||
|
||||
Without compromising the basic Zip file format, WinZip Computing has extended the format specification to support AES encryption, and this document fully describes the format extension. Additionally, we are providing information about a no-cost third-party source for the actual AES encryption code--the same code that is used by WinZip. We believe that use of the free encryption code and of this specification will make it easy for all developers to add compatible advanced encryption to their Zip file utilities.
|
||||
|
||||
This document is not a tutorial on encryption or Zip file structure. While we have attempted to provide the necessary details of the current WinZip AES encryption format, developers and other interested third parties will need to have or obtain an understanding of basic encryption concepts, Zip file format, etc.
|
||||
|
||||
Developers should also review [AES Coding Tips](https://www.winzip.com/aes_tips.html) page.
|
||||
|
||||
WinZip Computing makes no warranties regarding the information provided in this document. In particular, WinZip Computing does not represent or warrant that the information provided here is free from errors or is suitable for any particular use, or that the file formats described here will be supported in future versions of WinZip. You should test and validate all code and techniques in accordance with good programming practice.
|
||||
|
||||
----------
|
||||
|
||||
**I. Encryption services**
|
||||
|
||||
To perform AES encryption and decryption, WinZip uses AES functions written by Dr. Brian Gladman. The source code for these functions is available in C/C++ and Pentium family assembler for anyone to use under an open source BSD or GPL license from [the AES project page](https://www.winzip.com/gladman.cgi) on Dr. Gladman's web site. The [AES Coding Tips](https://www.winzip.com/aes_tips.html) page also has some information on the use of these functions. WinZip Computing thanks Dr. Gladman for making his AES functions available to anyone under liberal license terms.
|
||||
|
||||
Dr. Gladman's encryption functions are portable to a number of operating systems and can be static linked into your applications, so there are no operating system version or library dependencies. In particular, the functions do not require Microsoft's Cryptography API.
|
||||
|
||||
General information on the AES standard and the encryption algorithm (also known as _Rijndael_) is readily available on the Internet. A good place to start is [https://web.archive.org/web/20100407101917/www.nist.gov/public_affairs/releases/g00-176.htm](https://web.archive.org/web/20100407101917/www.nist.gov/public_affairs/releases/g00-176.htm).
|
||||
|
||||
**II. Zip file format**
|
||||
|
||||
1. Base format reference
|
||||
|
||||
AES-encrypted files are stored within the guidelines of the standard Zip file format using only a new "extra data" field, a new compression method code, and a value in the CRC field dependant on the encryption version, AE-1 or AE-2. The basic Zip file format is otherwise unchanged.
|
||||
|
||||
WinZip sets the version needed to extract and version made by fields in the local and central headers to the same values it would use if the file were not encrypted.
|
||||
|
||||
The basic Zip file format specification used by WinZip is available via FTP from the Info-ZIP group at [https://infozip.sourceforge.io/doc/appnote-iz-latest.zip](https://infozip.sourceforge.io/doc/appnote-iz-latest.zip).
|
||||
|
||||
2. Compression method and encryption flag
|
||||
|
||||
As for any encrypted file, bit 0 of the "general purpose bit flags" field must be set to 1 in each AES-encrypted file's local header and central directory entry.
|
||||
|
||||
Additionally, the presence of an AES-encrypted file in a Zip file is indicated by a new compression method code (decimal 99) in the file's local header and central directory entry, used along with the AES extra data field described below. There is no change in either the _version made by_ or _version needed to extract_ codes.
|
||||
|
||||
The code for the actual compression method is stored in the AES extra data field (see below).
|
||||
|
||||
3. CRC value
|
||||
|
||||
For files encrypted using the AE-2 method, the standard Zip CRC value is _not_ used, and a 0 must be stored in this field. Corruption of encrypted data within a Zip file is instead detected via the [authentication code](https://www.winzip.com/aes_info.htm#authentication-code) field.
|
||||
|
||||
Files encrypted using the AE-1 method _do_ include the standard Zip CRC value. This, along with the fact that the vendor version stored in the AES extra data field is 0x0001 for AE-1 and 0x0002 for AE-2, is the only difference between the AE-1 and AE-2 formats.
|
||||
|
||||
**NOTE:** Zip utilities that support the AE-2 format are required to be able to read files that were created in the AE-1 format, and during decryption/extraction of files in AE-1 format should verify that the file's CRC matches the value stored in the CRC field.
|
||||
|
||||
4. AES extra data field
|
||||
1. A file encrypted with AES encryption will have a special "extra data" field associated with it. This extra data field is stored in both the local header and central directory entry for the file.
|
||||
|
||||
Note: see the Zip file format document referenced above for general information on the format and use of extra data fields.
|
||||
|
||||
2. The extra data header ID for AES encryption is 0x9901. The fields are all stored in Intel low-byte/high-byte order. The extra data field currently has a length of 11: seven data bytes plus two bytes for the header ID and two bytes for the data size. Therefore, the extra data overhead for each file in the archive is 22 bytes (11 bytes in the central header plus 11 bytes in the local header).
|
||||
3. The format of the data in the AES extra data field is as follows. See the notes below for additional information.
|
||||
|
||||
|**Offset**|**Size(bytes)**|**Content**|
|
||||
|:-|:-|:-|
|
||||
|0|2|Extra field header ID (0x9901)|
|
||||
|2|2|Data size (currently 7, but subject to possible increase in the future)|
|
||||
|4|2|Integer version number specific to the zip vendor|
|
||||
|6|2|2-character vendor ID|
|
||||
|8|1|Integer mode value indicating AES encryption strength|
|
||||
|9|2|The actual compression method used to compress the file|
|
||||
|
||||
4. Notes
|
||||
- **Data size**: this value is currently 7, but because it is possible that this specification will be modified in the future to store additional data in this extra field, vendors should not assume that it will always remain 7.
|
||||
- **Vendor ID**: the vendor ID field should always be set to the two ASCII characters "AE".
|
||||
- **Vendor version**: the vendor version for AE-1 is 0x0001. The vendor version for AE-2 is 0x0002.
|
||||
|
||||
Zip utilities that support AE-2 must also be able to process files that are encrypted in AE-1 format. The handling of the [CRC value](https://www.winzip.com/aes_info.htm#CRC) is the only difference between the AE-1 and AE-2 formats.
|
||||
|
||||
- **Encryption strength**: the mode values (encryption strength) for AE-1 and AE-2 are:
|
||||
|
||||
|**Value**|**Strength**|
|
||||
|-|-|
|
||||
|0x01|128-bit encryption key|
|
||||
|0x02|192-bit encryption key|
|
||||
|0x03|256-bit encryption key|
|
||||
|
||||
The encryption specification supports _only_ 128-, 192-, and 256-bit encryption keys. No other key lengths are permitted.
|
||||
|
||||
(Note: the current version of WinZip does not support encrypting files using 192-bit keys. This specification, however, does provide for the use of 192-bit keys, and WinZip is able to decrypt such files.)
|
||||
|
||||
- **Compression method**: the compression method is the one that would otherwise have been stored in the local and central headers for the file. For example, if the file is imploded, this field will contain the compression code 6. This is needed because a compression method of 99 is used to indicate the presence of an AES-encrypted file (see [above](https://www.winzip.com/aes_info.htm#comp-method)).
|
||||
|
||||
**III. Encrypted file storage format**
|
||||
|
||||
1. File format
|
||||
|
||||
Additional overhead data required for decryption is stored with the encrypted file itself (i.e., not in the headers). The actual format of the stored file is as follows; additional information about these fields is below. All fields are byte-aligned.
|
||||
|
||||
|**Size (bytes)**|**Content**|
|
||||
|:-|:-|
|
||||
|Variable|Salt value|
|
||||
|2|Password verification value|
|
||||
|Variable|Encrypted file data|
|
||||
|10|Authentication code|
|
||||
|
||||
Note that the value in the "compressed size" fields of the local file header and the central directory entry is the total size of all the items listed above. In other words, it is the total size of the salt value, password verification value, encrypted data, and authentication code.
|
||||
|
||||
2. Salt value
|
||||
|
||||
The "salt" or "salt value" is a random or pseudo-random sequence of bytes that is combined with the encryption password to create encryption and authentication keys. The salt is generated by the encrypting application and is stored unencrypted with the file data. The addition of salt values to passwords provides a number of security benefits and makes dictionary attacks based on precomputed keys much more difficult.
|
||||
|
||||
Good cryptographic practice requires that a different salt value be used for each of multiple files encrypted with the same password. If two files are encrypted with the same password and salt, they can leak information about each other. For example, it is possible to determine whether two files encrypted with the same password and salt are identical, and an attacker who somehow already knows the contents of one of two files encrypted with the same password and salt can determine some or all of the contents of the other file. Therefore, you should make every effort to use a unique salt value for each file.
|
||||
|
||||
The size of the salt value depends on the length of the encryption key, as follows:
|
||||
|
||||
|**Key size**|**Salt size**|
|
||||
|:-|:-|
|
||||
|128 bits|8 bytes|
|
||||
|192 bits|12 bytes|
|
||||
|256 bits|16 bytes|
|
||||
|
||||
3. Password verification value
|
||||
|
||||
This two-byte value is produced as part of the process that derives the encryption and decryption keys from the password. When encrypting, a verification value is derived from the encryption password and stored with the encrypted file. Before decrypting, a verification value can be derived from the decryption password and compared to the value stored with the file, serving as a quick check that will detect _most_, but not all, incorrect passwords. There is a 1 in 65,536 chance that an incorrect password will yield a matching verification value; therefore, a matching verification value cannot be absolutely relied on to indicate a correct password.
|
||||
|
||||
Information on how to obtain the password verification value from Dr. Gladman's encryption library can be found on the [coding tips](https://www.winzip.com/aes_tips.html) page.
|
||||
|
||||
This value is stored unencrypted.
|
||||
|
||||
4. Encrypted file data
|
||||
|
||||
Encryption is applied only to the content of files. It is performed after compression, and not to any other associated data. The file data is encrypted byte-for-byte using the AES encryption algorithm operating in "CTR" mode, which means that the lengths of the compressed data and the compressed, encrypted data are the same.
|
||||
|
||||
It is important for implementors to note that, although the data is encrypted byte-for-byte, it is presented to the encryption and decryption functions in blocks. The block size used for encryption and decryption must be the same. To be compatible with the encryption specification, this block size must be 16 bytes (although the last block may be smaller).
|
||||
|
||||
5. Authentication code
|
||||
|
||||
Authentication provides a high quality check that the contents of an encrypted file have not been inadvertently changed or deliberately tampered with since they were first encrypted. In effect, this is a super-CRC check on the data in the file _after_ compression and encryption. (Additionally, authentication is essential when using CTR mode encryption because this mode is vulnerable to several trivial attacks in its absence.)
|
||||
|
||||
The authentication code is derived from the output of the encryption process. [Dr. Gladman's AES code](https://www.winzip.com/aes_info.htm#encryption) provides this service, and information about how to obtain it is in the [coding tips](https://www.winzip.com/aes_tips.html).
|
||||
|
||||
The authentication code is stored unencrypted. It is byte-aligned and immediately follows the last byte of encrypted data.
|
||||
|
||||
For more discussion about authentication, see the [authentication code FAQ](https://www.winzip.com/aes_info.htm#auth-faq) below.
|
||||
|
||||
|
||||
**IV. Changes in WinZip 11**
|
||||
|
||||
Beginning with WinZip 11, WinZip makes a change in its use of the AE-1 and AE-2 file formats. The file formats themselves have not changed, and AES-encrypted files created by WinZip 11 are completely compatible with version 1.02 the WinZip AES encryption specification, which was published in January 2004.
|
||||
|
||||
[WinZip 9.0](https://www.winzip.com/win/en/winzip-9.html) and [WinZip 10.0](https://www.winzip.com/win/en/winzip-10.html) stored all AES-encrypted files using the AE-2 file format, which does not store the encrypted file's CRC. WinZip 11 instead uses the AE-1 file format, which does store the CRC, for most files. This provides an extra integrity check against the possibility of hardware or software errors that occur during the actual process of [file compression/encryption](https://www.winzip.com/win/en/features/data-protection.html) or decryption/decompression. For more information on this point, see the discussion of the [CRC](https://www.winzip.com/aes_info.htm#crc-faq) below.
|
||||
|
||||
Because for some very small files the CRC can be used to determine the exact contents of a file, regardless of the encryption method used, WinZip 11 continues to use the AE-2 file format, with no CRC stored, for files with an uncompressed size of less than 20 bytes. WinZip 11 also uses the AE-2 file format for files compressed in BZIP2 format, because the BZIP2 format contains its own integrity checks equivalent to those provided by the Zip format's CRC.
|
||||
|
||||
Other vendors who support WinZip's AES encryption specification may want to consider making a similar change to their own implementations of the specification, to get the benefit of the extra integrity check that it provides.
|
||||
|
||||
Note that the January 2004 version of the WinZip AE-2 specification, version 1.0.2, already required that all utilities that implemented the AE-2 format also be able to process files in AE-1 format, and should check on decryption/extraction of those files that the CRC was correct.
|
||||
|
||||
**V. Notes**
|
||||
|
||||
1. Non-files and zero-length files
|
||||
|
||||
To reduce Zip file size, it is recommended that non-file entries such as folder/directory entries not be encrypted. This, however, is only a recommendation; it is permissible to encrypt or not encrypt these entries, as you prefer.
|
||||
|
||||
On the other hand, it is recommended that you _do_ encrypt zero-length files. The presence of both encrypted and unencrypted files in a Zip file may trigger user warnings in some Zip file utilities, so the user experience may be improved if all files (including zero-length files) are encrypted.
|
||||
|
||||
If zero-length files are encrypted, the encrypted data portion of the file storage (see [above](https://www.winzip.com/aes_info.htm#encrypted-data)) will be empty, but the remainder of the encryption overhead data must be present, both in the file storage area and in the local and central headers.
|
||||
|
||||
2. "Mixed" Zip files
|
||||
|
||||
There is no requirement that all files in a Zip file be encrypted or that all files that _are_ encrypted use the same encryption method or the same password.
|
||||
|
||||
A Zip file can contain any combination of unencrypted files and files encrypted with any of the four currently defined encryption methods (Zip 2.0, AES-128, AES-192, AES-256). Encrypted files may use the same password or different passwords.
|
||||
|
||||
3. Key Generation
|
||||
|
||||
Key derivation, as used by AE-1 and AE-2 and as implemented in Dr. Gladman's library, is done according to the PBKDF2 algorithm, which is described in the [RFC2898](https://www.ietf.org/rfc/rfc2898.txt) guidelines. An iteration count of 1000 is used. An appropriate number of bits from the resulting hash value are used to compose three output values: an encryption key, an authentication key, and a password verification value. The first _n_ bits become the encryption key, the next _m_ bits become the authentication key, and the last 16 bits (two bytes) become the password verification value.
|
||||
|
||||
As part of the process outlined in RFC 2898 a pseudo-random function must be called; AE-2 uses the HMAC-SHA1 function, since it is a well-respected algorithm that has been in wide use for this purpose for several years.
|
||||
|
||||
Note that, when used in connection with 192- or 256-bit AES encryption, the fact that HMAC-SHA1 produces a 160-bit result means that, regardless of the password that you specify, the search space for the encryption key is unlikely to reach the theoretical 192- or 256-bit maximum, and cannot be guaranteed to exceed 160 bits. This is discussed in section B.1.1 of the [RFC2898 specification](https://www.ietf.org/rfc/rfc2898.txt).
|
||||
|
||||
|
||||
**VI. FAQs**
|
||||
|
||||
- **Why is the compression method field used to indicate AES encryption?**
|
||||
|
||||
As opposed to using new _version made by_ and _version needed to extract_ values to signal AES encryption for a file, the new compression method is more likely to be handled gracefully by older versions of existing Zip file utilities. Zip file utilities typically do not attempt to extract files compressed with unknown methods, presumably notifying the user with an appropriate message.
|
||||
|
||||
- **How can I guarantee that the salt value is unique?**
|
||||
|
||||
In principle, the value of the salt should be different whenever the same password is used more than once, for the reasons described [above](https://www.winzip.com/aes_info.htm#salt), but this is difficult to guarantee.
|
||||
|
||||
In practice, the number of bytes in the salt (as specified by AE-1 and AE-2) is such that using a pseudo-random value will ensure that the probability of duplicated salt values is very low and can be safely ignored.
|
||||
|
||||
There is one exception to this: With the 8-byte salt values used with WinZip's 128-bit encryption it is likely that, if approximately 4 billion files are encrypted with the same password, two of the files will have the same salt, so it is advisable to stay well below this limit. Because of this, when using the same password to encrypt very large numbers of files in WinZip's AES encryption format (that is, files totalling in the millions, for example 2000 Zip files, each containing 1000 encrypted files), we recommend the use of 192-bit or 256-bit AES keys, with their 12- and 16-byte salt values, rather than 128-bit AES keys, with their 8-byte salt values.
|
||||
|
||||
Although salt values do not need to be truly random, it is important that they be generated in a way that the probability of duplicated salt values is not significantly higher than that which would be expected if truly random values were being used.
|
||||
|
||||
One technique for generating salt values is presented in the [coding tips](https://www.winzip.com/aes_tips.html#prng) page.
|
||||
|
||||
- **Why is there an authentication code?**
|
||||
|
||||
The purpose of the authentication code is to insure that, once a file's data has been compressed and encrypted, any accidental corruption of the encrypted data, and any deliberate attempts to modify the encrypted data by an attacker who does not know the password, can be detected.
|
||||
|
||||
The current consensus in the cryptographic community is that associating a message authentication code (or MAC) with encrypted data has strong security value because it makes a number of attacks more difficult to engineer. For AES CTR mode encryption in particular, a MAC is especially important because a number of trivial attacks are possible in its absence. The MAC used with WinZip's AES encryption is based on[HMAC-SHA1-80](https://www.ietf.org/rfc/rfc2104.txt), a mature and widely respected authentication algorithm.
|
||||
|
||||
The MAC is calculated after the file data has been compressed and encrypted. This order of calculation is referred to as Encrypt-then-MAC, and is preferred by many cryptographers to the alternative order of MAC-then-Encrypt because Encrypt-then-MAC is immune to some known attacks on MAC-then-Encrypt.
|
||||
|
||||
- **What is the role of the CRC in WinZip 11?**
|
||||
|
||||
Within the Zip format, the primary use of the CRC value is to detect accidental corruption of data that has been stored in the Zip file. With files encrypted according to the Zip 2.0 encryption specification, it also functions to some extent as a method of detecting deliberate attempts to modify the encrypted data, but not one that can be considered cryptographically strong. The CRC is not needed for these purposes with the WinZip AES encryption specification, where the HMAC-SHA1-based authentication code instead serves these roles.
|
||||
|
||||
The CRC has a drawback in that for very small files, such as files with four or fewer bytes, the CRC can be used, independent of the encryption algorithm, to determine the unencrypted contents of the file. And, in general, it is preferable to store as little information as possible about the encrypted file in the unencrypted Zip headers.
|
||||
|
||||
The CRC does serve one purpose that the authentication code does not. The CRC is computed based on the original uncompressed, unencrypted contents of the file, and it is checked after the file has been decrypted and decompressed. In contrast, the authentication code used with WinZip AES encryption is computed after compression/encryption and it is checked before decryption/decompression. In the very rare event of a hardware or software error that corrupts data during compression and encryption, or during decryption and decompression, the CRC will catch the error, but the authentication code will not.
|
||||
|
||||
WinZip 9.0 and WinZip 10.0 used AE-2 for all files that they created, and did not store the CRC. As of WinZip 11, WinZip instead uses AE-1 for most files, storing the CRC as an additional integrity check against hardware or software errors occurring during the actual compression/encryption or decryption/decompression processes. WinZip 11 will continue to use AE-2, with no CRC, for very small files of less than 20 bytes. It will also use AE-2 for files compressed in BZIP2 format, because this format has internal integrity checks equivalent to a CRC check built in.
|
||||
|
||||
Note that the AES-encrypted files created by WinZip 11 are fully compatible with January 2004's version 1.0.2 of the WinZip AES encryption specification, in which both the AE-1 and AE-2 variants of the file format were already defined.
|
||||
|
||||
|
||||
**VII. Change history**
|
||||
|
||||
**Changes made in document version 1.04, January, 2009:** Minor clarification regarding the algorithm used to generate the authentication code.
|
||||
|
||||
**Changes made in document version 1.03, November, 2006:** Minor editorial and clarifying changes have been made throughout the document. The following substantive technical changes have been made:
|
||||
|
||||
1. WinZip 11 Usage of AE-1 and AE-2
|
||||
|
||||
WinZip's AES encryption specification defines two formats, known as AE-1 and AE-2, which differ in whether the CRC of the encrypted file is stored in the Zip headers. While the file formats themselves remain unchanged, WinZip's usage of them is changing. Beginning with [WinZip 11](https://www.winzip.com/aes_info.htm#winzip11), WinZip uses the AE-1 format, which includes the CRC of the encrypted file, for many encrypted files, in order to provide an additional integrity check against hardware or software errors occurring during the compression/encryption or decryption/decompression processes. Note that AES-encrypted files created by WinZip 11 are completely compatible with the previous version of the WinZip encryption specification, January 2004's version 1.0.2.
|
||||
|
||||
2. The discussion of [salt values](https://www.winzip.com/aes_info.htm#salt) mentions a limitation that applies to the uniqueness of salt values when very large numbers of files are encrypted with 128-bit encryption.
|
||||
3. Older versions of this specification suggested that other vendors might want to use their own vendor IDs to create their own unique encryption formats. We no longer suggest that vendor-specific alternative encryption methods be created in this way.
|
||||
|
||||
**Changes made in document version 1.02, January, 2004:** The introductory text at the start of the document has been rewritten, and minor editorial and clarifying changes have been made throughout the document. Two substantive technical changes have been made:
|
||||
|
||||
1. AE-2 Specification
|
||||
|
||||
Standard Zip files store the CRC of each file's unencrypted data. This value is used to help detect damage or other alterations to Zip files. However, storing the CRC value has a drawback in that, for a very small file, such as a file of four or fewer bytes, the CRC value can be used, independent of the encryption algorithm, to help determine the unencrypted contents of the file.
|
||||
|
||||
Because of this, files encrypted with the new AE-2 method store a 0 in the CRC field of the Zip header, and use the [authentication code](https://www.winzip.com/aes_info.htm#authentication-code) instead of the CRC value to verify that encrypted data within the Zip file has not been corrupted.
|
||||
|
||||
The only differences between the AE-1 and AE-2 methods are the storage in AE-2 of 0 instead of the CRC in the Zip file header,and the use in the AES extra data field of 0x0002 for AE-2 instead of 0x0001 for AE-1 as the vendor version.
|
||||
|
||||
Zip utilities that support the AE-2 format are required to be able to read files that were created in the AE-1 format, and during decryption/extraction of files in AE-1 format should verify that the file's CRC matches the value stored in the CRC field.
|
||||
|
||||
2. Key Generation and HMAC-SHA1
|
||||
|
||||
The description of the [key generation](https://www.winzip.com/aes_info.htm#key-generation) mechanism has been updated to point out a limitation arising from its use of HMAC-SHA1 as the pseudo-random function: When used in connection with 192- or 256-bit AES encryption, the fact that HMAC-SHA1 produces a 160-bit result means that, regardless of the password that you specify, the search space for the encryption key is unlikely to reach the theoretical 192- or 256-bit maximum, and cannot be guaranteed to exceed 160 bits. This is discussed in section B.1.1 of the [RFC2898 specification](https://www.ietf.org/rfc/rfc2898.txt).
|
||||
|
||||
Document version: 1.04
|
||||
Last modified: January 30, 2009
|
||||
|
||||
Copyright© 2003-2018 Corel Corporation.
|
||||
All Rights Reserved
|
||||
@@ -0,0 +1 @@
|
||||
The third-party libraries in these directories have their own licenses.
|
||||
@@ -1,182 +0,0 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
|
||||
This is an implementation of RFC2898, which specifies key derivation from
|
||||
a password and a salt value.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "hmac.h"
|
||||
#include "pwd2key.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void derive_key(const unsigned char pwd[], /* the PASSWORD */
|
||||
unsigned int pwd_len, /* and its length */
|
||||
const unsigned char salt[], /* the SALT and its */
|
||||
unsigned int salt_len, /* length */
|
||||
unsigned int iter, /* the number of iterations */
|
||||
unsigned char key[], /* space for the output key */
|
||||
unsigned int key_len)/* and its required length */
|
||||
{
|
||||
unsigned int i, j, k, n_blk, h_size;
|
||||
unsigned char uu[HMAC_MAX_OUTPUT_SIZE], ux[HMAC_MAX_OUTPUT_SIZE];
|
||||
hmac_ctx c1[1], c2[1], c3[1];
|
||||
|
||||
/* set HMAC context (c1) for password */
|
||||
h_size = hmac_sha_begin(HMAC_SHA1, c1);
|
||||
hmac_sha_key(pwd, pwd_len, c1);
|
||||
|
||||
/* set HMAC context (c2) for password and salt */
|
||||
memcpy(c2, c1, sizeof(hmac_ctx));
|
||||
hmac_sha_data(salt, salt_len, c2);
|
||||
|
||||
/* find the number of SHA blocks in the key */
|
||||
n_blk = 1 + (key_len - 1) / h_size;
|
||||
|
||||
for(i = 0; i < n_blk; ++i) /* for each block in key */
|
||||
{
|
||||
/* ux[] holds the running xor value */
|
||||
memset(ux, 0, h_size);
|
||||
|
||||
/* set HMAC context (c3) for password and salt */
|
||||
memcpy(c3, c2, sizeof(hmac_ctx));
|
||||
|
||||
/* enter additional data for 1st block into uu */
|
||||
uu[0] = (unsigned char)((i + 1) >> 24);
|
||||
uu[1] = (unsigned char)((i + 1) >> 16);
|
||||
uu[2] = (unsigned char)((i + 1) >> 8);
|
||||
uu[3] = (unsigned char)(i + 1);
|
||||
|
||||
/* this is the key mixing iteration */
|
||||
for(j = 0, k = 4; j < iter; ++j)
|
||||
{
|
||||
/* add previous round data to HMAC */
|
||||
hmac_sha_data(uu, k, c3);
|
||||
|
||||
/* obtain HMAC for uu[] */
|
||||
hmac_sha_end(uu, h_size, c3);
|
||||
|
||||
/* xor into the running xor block */
|
||||
for(k = 0; k < h_size; ++k)
|
||||
ux[k] ^= uu[k];
|
||||
|
||||
/* set HMAC context (c3) for password */
|
||||
memcpy(c3, c1, sizeof(hmac_ctx));
|
||||
}
|
||||
|
||||
/* compile key blocks into the key output */
|
||||
j = 0; k = i * h_size;
|
||||
while(j < h_size && k < key_len)
|
||||
key[k++] = ux[j++];
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
struct
|
||||
{ unsigned int pwd_len;
|
||||
unsigned int salt_len;
|
||||
unsigned int it_count;
|
||||
unsigned char *pwd;
|
||||
unsigned char salt[32];
|
||||
unsigned char key[32];
|
||||
} tests[] =
|
||||
{
|
||||
{ 8, 4, 5, (unsigned char*)"password",
|
||||
{
|
||||
0x12, 0x34, 0x56, 0x78
|
||||
},
|
||||
{
|
||||
0x5c, 0x75, 0xce, 0xf0, 0x1a, 0x96, 0x0d, 0xf7,
|
||||
0x4c, 0xb6, 0xb4, 0x9b, 0x9e, 0x38, 0xe6, 0xb5
|
||||
}
|
||||
},
|
||||
{ 8, 8, 5, (unsigned char*)"password",
|
||||
{
|
||||
0x12, 0x34, 0x56, 0x78, 0x78, 0x56, 0x34, 0x12
|
||||
},
|
||||
{
|
||||
0xd1, 0xda, 0xa7, 0x86, 0x15, 0xf2, 0x87, 0xe6,
|
||||
0xa1, 0xc8, 0xb1, 0x20, 0xd7, 0x06, 0x2a, 0x49
|
||||
}
|
||||
},
|
||||
{ 8, 21, 1, (unsigned char*)"password",
|
||||
{
|
||||
"ATHENA.MIT.EDUraeburn"
|
||||
},
|
||||
{
|
||||
0xcd, 0xed, 0xb5, 0x28, 0x1b, 0xb2, 0xf8, 0x01,
|
||||
0x56, 0x5a, 0x11, 0x22, 0xb2, 0x56, 0x35, 0x15
|
||||
}
|
||||
},
|
||||
{ 8, 21, 2, (unsigned char*)"password",
|
||||
{
|
||||
"ATHENA.MIT.EDUraeburn"
|
||||
},
|
||||
{
|
||||
0x01, 0xdb, 0xee, 0x7f, 0x4a, 0x9e, 0x24, 0x3e,
|
||||
0x98, 0x8b, 0x62, 0xc7, 0x3c, 0xda, 0x93, 0x5d
|
||||
}
|
||||
},
|
||||
{ 8, 21, 1200, (unsigned char*)"password",
|
||||
{
|
||||
"ATHENA.MIT.EDUraeburn"
|
||||
},
|
||||
{
|
||||
0x5c, 0x08, 0xeb, 0x61, 0xfd, 0xf7, 0x1e, 0x4e,
|
||||
0x4e, 0xc3, 0xcf, 0x6b, 0xa1, 0xf5, 0x51, 0x2b
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{ unsigned int i, j, key_len = 256;
|
||||
unsigned char key[256];
|
||||
|
||||
printf("\nTest of RFC2898 Password Based Key Derivation");
|
||||
for(i = 0; i < 5; ++i)
|
||||
{
|
||||
derive_key(tests[i].pwd, tests[i].pwd_len, tests[i].salt,
|
||||
tests[i].salt_len, tests[i].it_count, key, key_len);
|
||||
|
||||
printf("\ntest %i: ", i + 1);
|
||||
printf("key %s", memcmp(tests[i].key, key, 16) ? "is bad" : "is good");
|
||||
for(j = 0; j < key_len && j < 64; j += 4)
|
||||
{
|
||||
if(j % 16 == 0)
|
||||
printf("\n");
|
||||
printf("0x%02x%02x%02x%02x ", key[j], key[j + 1], key[j + 2], key[j + 3]);
|
||||
}
|
||||
printf(j < key_len ? " ... \n" : "\n");
|
||||
}
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
|
||||
This is an implementation of RFC2898, which specifies key derivation from
|
||||
a password and a salt value.
|
||||
*/
|
||||
|
||||
#ifndef PWD2KEY_H
|
||||
#define PWD2KEY_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void derive_key(
|
||||
const unsigned char pwd[], /* the PASSWORD, and */
|
||||
unsigned int pwd_len, /* its length */
|
||||
const unsigned char salt[], /* the SALT and its */
|
||||
unsigned int salt_len, /* length */
|
||||
unsigned int iter, /* the number of iterations */
|
||||
unsigned char key[], /* space for the output key */
|
||||
unsigned int key_len); /* and its required length */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -51,7 +51,7 @@ extern "C"
|
||||
#if ( FUNCS_IN_C & ENCRYPTION_IN_C )
|
||||
|
||||
/* Visual C++ .Net v7.1 provides the fastest encryption code when using
|
||||
Pentium optimiation with small code but this is poor for decryption
|
||||
Pentium optimisation with small code but this is poor for decryption
|
||||
so we need to control this with the following VC++ pragmas
|
||||
*/
|
||||
|
||||
@@ -168,7 +168,7 @@ AES_RETURN aes_xi(encrypt)(const unsigned char *in, unsigned char *out, const ae
|
||||
#if ( FUNCS_IN_C & DECRYPTION_IN_C)
|
||||
|
||||
/* Visual C++ .Net v7.1 provides the fastest encryption code when using
|
||||
Pentium optimiation with small code but this is poor for decryption
|
||||
Pentium optimisation with small code but this is poor for decryption
|
||||
so we need to control this with the following VC++ pragmas
|
||||
*/
|
||||
|
||||
@@ -212,7 +212,7 @@ AES_RETURN aes_xi(encrypt)(const unsigned char *in, unsigned char *out, const ae
|
||||
#endif
|
||||
|
||||
/* This code can work with the decryption key schedule in the */
|
||||
/* order that is used for encrytpion (where the 1st decryption */
|
||||
/* order that is used for encryption (where the 1st decryption */
|
||||
/* round key is at the high end ot the schedule) or with a key */
|
||||
/* schedule that has been reversed to put the 1st decryption */
|
||||
/* round key at the low end of the schedule in memory (when */
|
||||
@@ -393,8 +393,10 @@ AES_RETURN aes_xi(decrypt_key192)(const unsigned char *key, aes_decrypt_ctx cx[1
|
||||
cx->ks[v(48,(3))] = ss[3] = word_in(key, 3);
|
||||
|
||||
#ifdef DEC_KS_UNROLL
|
||||
cx->ks[v(48,(4))] = ff(ss[4] = word_in(key, 4));
|
||||
cx->ks[v(48,(5))] = ff(ss[5] = word_in(key, 5));
|
||||
ss[4] = word_in(key, 4);
|
||||
cx->ks[v(48,(4))] = ff(ss[4]);
|
||||
ss[5] = word_in(key, 5);
|
||||
cx->ks[v(48,(5))] = ff(ss[5]);
|
||||
kdf6(cx->ks, 0); kd6(cx->ks, 1);
|
||||
kd6(cx->ks, 2); kd6(cx->ks, 3);
|
||||
kd6(cx->ks, 4); kd6(cx->ks, 5);
|
||||
@@ -485,10 +487,14 @@ AES_RETURN aes_xi(decrypt_key256)(const unsigned char *key, aes_decrypt_ctx cx[1
|
||||
cx->ks[v(56,(3))] = ss[3] = word_in(key, 3);
|
||||
|
||||
#ifdef DEC_KS_UNROLL
|
||||
cx->ks[v(56,(4))] = ff(ss[4] = word_in(key, 4));
|
||||
cx->ks[v(56,(5))] = ff(ss[5] = word_in(key, 5));
|
||||
cx->ks[v(56,(6))] = ff(ss[6] = word_in(key, 6));
|
||||
cx->ks[v(56,(7))] = ff(ss[7] = word_in(key, 7));
|
||||
ss[4] = word_in(key, 4);
|
||||
cx->ks[v(56,(4))] = ff(ss[4]);
|
||||
ss[5] = word_in(key, 5);
|
||||
cx->ks[v(56,(5))] = ff(ss[5]);
|
||||
ss[6] = word_in(key, 6);
|
||||
cx->ks[v(56,(6))] = ff(ss[6]);
|
||||
ss[7] = word_in(key, 7);
|
||||
cx->ks[v(56,(7))] = ff(ss[7]);
|
||||
kdf8(cx->ks, 0); kd8(cx->ks, 1);
|
||||
kd8(cx->ks, 2); kd8(cx->ks, 3);
|
||||
kd8(cx->ks, 4); kd8(cx->ks, 5);
|
||||
@@ -64,7 +64,7 @@ Issue Date: 20/12/2007
|
||||
|
||||
Class AESencrypt for encryption
|
||||
|
||||
Construtors:
|
||||
Constructors:
|
||||
AESencrypt(void)
|
||||
AESencrypt(const unsigned char *key) - 128 bit key
|
||||
Members:
|
||||
@@ -74,7 +74,7 @@ Issue Date: 20/12/2007
|
||||
AES_RETURN encrypt(const unsigned char *in, unsigned char *out) const
|
||||
|
||||
Class AESdecrypt for encryption
|
||||
Construtors:
|
||||
Constructors:
|
||||
AESdecrypt(void)
|
||||
AESdecrypt(const unsigned char *key) - 128 bit key
|
||||
Members:
|
||||
@@ -180,9 +180,9 @@ Issue Date: 20/12/2007
|
||||
if it is detected (both present and enabled).
|
||||
|
||||
AESNI uses a decryption key schedule with the first decryption
|
||||
round key at the high end of the key scedule with the following
|
||||
round key at the high end of the key schedule with the following
|
||||
round keys at lower positions in memory. So AES_REV_DKS must NOT
|
||||
be defined when AESNI will be used. ALthough it is unlikely that
|
||||
be defined when AESNI will be used. Although it is unlikely that
|
||||
assembler code will be used with an AESNI build, if it is then
|
||||
AES_REV_DKS must NOT be defined when the assembler files are
|
||||
built
|
||||
@@ -279,7 +279,7 @@ Issue Date: 20/12/2007
|
||||
|
||||
/* 5. LOOP UNROLLING
|
||||
|
||||
The code for encryption and decrytpion cycles through a number of rounds
|
||||
The code for encryption and decryption cycles through a number of rounds
|
||||
that can be implemented either in a loop or by expanding the code into a
|
||||
long sequence of instructions, the latter producing a larger program but
|
||||
one that will often be much faster. The latter is called loop unrolling.
|
||||
@@ -324,9 +324,9 @@ Issue Date: 20/12/2007
|
||||
/* 7. INTERNAL STATE VARIABLE FORMAT
|
||||
|
||||
The internal state of Rijndael is stored in a number of local 32-bit
|
||||
word varaibles which can be defined either as an array or as individual
|
||||
word variables which can be defined either as an array or as individual
|
||||
names variables. Include this section if you want to store these local
|
||||
varaibles in arrays. Otherwise individual local variables will be used.
|
||||
variables in arrays. Otherwise individual local variables will be used.
|
||||
*/
|
||||
#if 1
|
||||
# define ARRAYS
|
||||
@@ -355,10 +355,10 @@ Issue Date: 20/12/2007
|
||||
|
||||
/* 10. TABLE ALIGNMENT
|
||||
|
||||
On some sytsems speed will be improved by aligning the AES large lookup
|
||||
On some systems speed will be improved by aligning the AES large lookup
|
||||
tables on particular boundaries. This define should be set to a power of
|
||||
two giving the desired alignment. It can be left undefined if alignment
|
||||
is not needed. This option is specific to the Microsft VC++ compiler -
|
||||
is not needed. This option is specific to the Microsoft VC++ compiler -
|
||||
it seems to sometimes cause trouble for the VC++ version 6 compiler.
|
||||
*/
|
||||
|
||||
@@ -383,7 +383,7 @@ Issue Date: 20/12/2007
|
||||
up using tables. The basic tables are each 256 32-bit words, with either
|
||||
one or four tables being required for each round function depending on
|
||||
how much speed is required. The encryption and decryption round functions
|
||||
are different and the last encryption and decrytpion round functions are
|
||||
are different and the last encryption and decryption round functions are
|
||||
different again making four different round functions in all.
|
||||
|
||||
This means that:
|
||||
@@ -482,7 +482,7 @@ Issue Date: 20/12/2007
|
||||
a column number c to the way the state array variable is to be held.
|
||||
The first define below maps the state into an array x[c] whereas the
|
||||
second form maps the state into a number of individual variables x0,
|
||||
x1, etc. Another form could map individual state colums to machine
|
||||
x1, etc. Another form could map individual state columns to machine
|
||||
register names.
|
||||
*/
|
||||
|
||||
@@ -386,7 +386,7 @@ AES_RETURN aes_init(void)
|
||||
/*
|
||||
Automatic code initialisation (suggested by by Henrik S. Gaßmann)
|
||||
based on code provided by Joe Lowe and placed in the public domain at:
|
||||
http://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc
|
||||
https://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@@ -175,7 +175,7 @@ extern "C" {
|
||||
length 'size' bits
|
||||
|
||||
UPTR_CAST(x,size) casts a pointer to a pointer to a
|
||||
varaiable of length 'size' bits
|
||||
variable of length 'size' bits
|
||||
*/
|
||||
|
||||
#define UI_TYPE(size) uint##size##_t
|
||||
@@ -101,7 +101,7 @@ int hmac_sha_begin(enum hmac_hash hash, hmac_ctx cx[1])
|
||||
case HMAC_SHA512_128:
|
||||
cx->f_begin = (hf_begin *)sha512_128_begin;
|
||||
cx->f_hash = (hf_hash *)sha512_128_hash;
|
||||
cx->f_end = (hf_begin *)sha512_128_end;
|
||||
cx->f_end = (hf_end *)sha512_128_end;
|
||||
cx->input_len = SHA512_128_BLOCK_SIZE;
|
||||
cx->output_len = SHA512_128_DIGEST_SIZE;
|
||||
break;
|
||||
@@ -32,6 +32,7 @@ extern "C"
|
||||
#endif
|
||||
|
||||
#include "sha1.h"
|
||||
#include "sha2.h"
|
||||
|
||||
#if defined(SHA_224) || defined(SHA_256) || defined(SHA_384) || defined(SHA_512)
|
||||
#define HMAC_MAX_OUTPUT_SIZE SHA2_MAX_DIGEST_SIZE
|
||||
+949
@@ -0,0 +1,949 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
|
||||
This code implements sha256, sha384 and sha512 but the latter two
|
||||
functions rely on efficient 64-bit integer operations that may not be
|
||||
very efficient on 32-bit machines
|
||||
|
||||
The sha256 functions use a type 'sha256_ctx' to hold details of the
|
||||
current hash state and uses the following three calls:
|
||||
|
||||
void sha256_begin( sha256_ctx ctx[1] )
|
||||
void sha256_hash( const unsigned char data[],
|
||||
unsigned long len, sha256_ctx ctx[1] )
|
||||
void sha_end1( unsigned char hval[], sha256_ctx ctx[1] )
|
||||
|
||||
The first subroutine initialises a hash computation by setting up the
|
||||
context in the sha256_ctx context. The second subroutine hashes 8-bit
|
||||
bytes from array data[] into the hash state withinh sha256_ctx context,
|
||||
the number of bytes to be hashed being given by the the unsigned long
|
||||
integer len. The third subroutine completes the hash calculation and
|
||||
places the resulting digest value in the array of 8-bit bytes hval[].
|
||||
|
||||
The sha384 and sha512 functions are similar and use the interfaces:
|
||||
|
||||
void sha384_begin( sha384_ctx ctx[1] );
|
||||
void sha384_hash( const unsigned char data[],
|
||||
unsigned long len, sha384_ctx ctx[1] );
|
||||
void sha384_end( unsigned char hval[], sha384_ctx ctx[1] );
|
||||
|
||||
void sha512_begin( sha512_ctx ctx[1] );
|
||||
void sha512_hash( const unsigned char data[],
|
||||
unsigned long len, sha512_ctx ctx[1] );
|
||||
void sha512_end( unsigned char hval[], sha512_ctx ctx[1] );
|
||||
|
||||
In addition there is a function sha2 that can be used to call all these
|
||||
functions using a call with a hash length parameter as follows:
|
||||
|
||||
int sha2_begin( unsigned long len, sha2_ctx ctx[1] );
|
||||
void sha2_hash( const unsigned char data[],
|
||||
unsigned long len, sha2_ctx ctx[1] );
|
||||
void sha2_end( unsigned char hval[], sha2_ctx ctx[1] );
|
||||
|
||||
The data block length in any one call to any of these hash functions must
|
||||
be no more than 2^32 - 1 bits or 2^29 - 1 bytes.
|
||||
|
||||
My thanks to Erik Andersen <andersen@codepoet.org> for testing this code
|
||||
on big-endian systems and for his assistance with corrections
|
||||
*/
|
||||
|
||||
#if 1
|
||||
#define UNROLL_SHA2 /* for SHA2 loop unroll */
|
||||
#endif
|
||||
|
||||
#include <string.h> /* for memcpy() etc. */
|
||||
|
||||
#include "sha2.h"
|
||||
#include "brg_endian.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#if defined( _MSC_VER ) && ( _MSC_VER > 800 )
|
||||
#pragma intrinsic(memcpy)
|
||||
#pragma intrinsic(memset)
|
||||
#endif
|
||||
|
||||
#if 0 && defined(_MSC_VER)
|
||||
#define rotl32 _lrotl
|
||||
#define rotr32 _lrotr
|
||||
#else
|
||||
#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n)))
|
||||
#define rotr32(x,n) (((x) >> n) | ((x) << (32 - n)))
|
||||
#endif
|
||||
|
||||
#if !defined(bswap_32)
|
||||
#define bswap_32(x) ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00))
|
||||
#endif
|
||||
|
||||
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
|
||||
#define SWAP_BYTES
|
||||
#else
|
||||
#undef SWAP_BYTES
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
||||
#define ch(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
|
||||
#define maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
|
||||
|
||||
#else /* Thanks to Rich Schroeppel and Colin Plumb for the following */
|
||||
|
||||
#define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
|
||||
#define maj(x,y,z) (((x) & (y)) | ((z) & ((x) ^ (y))))
|
||||
|
||||
#endif
|
||||
|
||||
/* round transforms for SHA256 and SHA512 compression functions */
|
||||
|
||||
#define vf(n,i) v[(n - i) & 7]
|
||||
|
||||
#define hf(i) (p[i & 15] += \
|
||||
g_1(p[(i + 14) & 15]) + p[(i + 9) & 15] + g_0(p[(i + 1) & 15]))
|
||||
|
||||
#define v_cycle(i,j) \
|
||||
vf(7,i) += (j ? hf(i) : p[i]) + k_0[i+j] \
|
||||
+ s_1(vf(4,i)) + ch(vf(4,i),vf(5,i),vf(6,i)); \
|
||||
vf(3,i) += vf(7,i); \
|
||||
vf(7,i) += s_0(vf(0,i))+ maj(vf(0,i),vf(1,i),vf(2,i))
|
||||
|
||||
#if defined(SHA_224) || defined(SHA_256)
|
||||
|
||||
#define SHA256_MASK (SHA256_BLOCK_SIZE - 1)
|
||||
|
||||
#if defined(SWAP_BYTES)
|
||||
#define bsw_32(p,n) \
|
||||
{ int _i = (n); while(_i--) ((uint32_t*)p)[_i] = bswap_32(((uint32_t*)p)[_i]); }
|
||||
#else
|
||||
#define bsw_32(p,n)
|
||||
#endif
|
||||
|
||||
#define s_0(x) (rotr32((x), 2) ^ rotr32((x), 13) ^ rotr32((x), 22))
|
||||
#define s_1(x) (rotr32((x), 6) ^ rotr32((x), 11) ^ rotr32((x), 25))
|
||||
#define g_0(x) (rotr32((x), 7) ^ rotr32((x), 18) ^ ((x) >> 3))
|
||||
#define g_1(x) (rotr32((x), 17) ^ rotr32((x), 19) ^ ((x) >> 10))
|
||||
#define k_0 k256
|
||||
|
||||
/* rotated SHA256 round definition. Rather than swapping variables as in */
|
||||
/* FIPS-180, different variables are 'rotated' on each round, returning */
|
||||
/* to their starting positions every eight rounds */
|
||||
|
||||
#define q(n) v##n
|
||||
|
||||
#define one_cycle(a,b,c,d,e,f,g,h,k,w) \
|
||||
q(h) += s_1(q(e)) + ch(q(e), q(f), q(g)) + k + w; \
|
||||
q(d) += q(h); q(h) += s_0(q(a)) + maj(q(a), q(b), q(c))
|
||||
|
||||
/* SHA256 mixing data */
|
||||
|
||||
const uint32_t k256[64] =
|
||||
{ 0x428a2f98ul, 0x71374491ul, 0xb5c0fbcful, 0xe9b5dba5ul,
|
||||
0x3956c25bul, 0x59f111f1ul, 0x923f82a4ul, 0xab1c5ed5ul,
|
||||
0xd807aa98ul, 0x12835b01ul, 0x243185beul, 0x550c7dc3ul,
|
||||
0x72be5d74ul, 0x80deb1feul, 0x9bdc06a7ul, 0xc19bf174ul,
|
||||
0xe49b69c1ul, 0xefbe4786ul, 0x0fc19dc6ul, 0x240ca1ccul,
|
||||
0x2de92c6ful, 0x4a7484aaul, 0x5cb0a9dcul, 0x76f988daul,
|
||||
0x983e5152ul, 0xa831c66dul, 0xb00327c8ul, 0xbf597fc7ul,
|
||||
0xc6e00bf3ul, 0xd5a79147ul, 0x06ca6351ul, 0x14292967ul,
|
||||
0x27b70a85ul, 0x2e1b2138ul, 0x4d2c6dfcul, 0x53380d13ul,
|
||||
0x650a7354ul, 0x766a0abbul, 0x81c2c92eul, 0x92722c85ul,
|
||||
0xa2bfe8a1ul, 0xa81a664bul, 0xc24b8b70ul, 0xc76c51a3ul,
|
||||
0xd192e819ul, 0xd6990624ul, 0xf40e3585ul, 0x106aa070ul,
|
||||
0x19a4c116ul, 0x1e376c08ul, 0x2748774cul, 0x34b0bcb5ul,
|
||||
0x391c0cb3ul, 0x4ed8aa4aul, 0x5b9cca4ful, 0x682e6ff3ul,
|
||||
0x748f82eeul, 0x78a5636ful, 0x84c87814ul, 0x8cc70208ul,
|
||||
0x90befffaul, 0xa4506cebul, 0xbef9a3f7ul, 0xc67178f2ul,
|
||||
};
|
||||
|
||||
/* Compile 64 bytes of hash data into SHA256 digest value */
|
||||
/* NOTE: this routine assumes that the byte order in the */
|
||||
/* ctx->wbuf[] at this point is such that low address bytes */
|
||||
/* in the ORIGINAL byte stream will go into the high end of */
|
||||
/* words on BOTH big and little endian systems */
|
||||
|
||||
VOID_RETURN sha256_compile(sha256_ctx ctx[1])
|
||||
{
|
||||
#if !defined(UNROLL_SHA2)
|
||||
|
||||
uint32_t j, *p = ctx->wbuf, v[8];
|
||||
|
||||
memcpy(v, ctx->hash, sizeof(ctx->hash));
|
||||
|
||||
for(j = 0; j < 64; j += 16)
|
||||
{
|
||||
v_cycle( 0, j); v_cycle( 1, j);
|
||||
v_cycle( 2, j); v_cycle( 3, j);
|
||||
v_cycle( 4, j); v_cycle( 5, j);
|
||||
v_cycle( 6, j); v_cycle( 7, j);
|
||||
v_cycle( 8, j); v_cycle( 9, j);
|
||||
v_cycle(10, j); v_cycle(11, j);
|
||||
v_cycle(12, j); v_cycle(13, j);
|
||||
v_cycle(14, j); v_cycle(15, j);
|
||||
}
|
||||
|
||||
ctx->hash[0] += v[0]; ctx->hash[1] += v[1];
|
||||
ctx->hash[2] += v[2]; ctx->hash[3] += v[3];
|
||||
ctx->hash[4] += v[4]; ctx->hash[5] += v[5];
|
||||
ctx->hash[6] += v[6]; ctx->hash[7] += v[7];
|
||||
|
||||
#else
|
||||
|
||||
uint32_t *p = ctx->wbuf,v0,v1,v2,v3,v4,v5,v6,v7;
|
||||
|
||||
v0 = ctx->hash[0]; v1 = ctx->hash[1];
|
||||
v2 = ctx->hash[2]; v3 = ctx->hash[3];
|
||||
v4 = ctx->hash[4]; v5 = ctx->hash[5];
|
||||
v6 = ctx->hash[6]; v7 = ctx->hash[7];
|
||||
|
||||
one_cycle(0,1,2,3,4,5,6,7,k256[ 0],p[ 0]);
|
||||
one_cycle(7,0,1,2,3,4,5,6,k256[ 1],p[ 1]);
|
||||
one_cycle(6,7,0,1,2,3,4,5,k256[ 2],p[ 2]);
|
||||
one_cycle(5,6,7,0,1,2,3,4,k256[ 3],p[ 3]);
|
||||
one_cycle(4,5,6,7,0,1,2,3,k256[ 4],p[ 4]);
|
||||
one_cycle(3,4,5,6,7,0,1,2,k256[ 5],p[ 5]);
|
||||
one_cycle(2,3,4,5,6,7,0,1,k256[ 6],p[ 6]);
|
||||
one_cycle(1,2,3,4,5,6,7,0,k256[ 7],p[ 7]);
|
||||
one_cycle(0,1,2,3,4,5,6,7,k256[ 8],p[ 8]);
|
||||
one_cycle(7,0,1,2,3,4,5,6,k256[ 9],p[ 9]);
|
||||
one_cycle(6,7,0,1,2,3,4,5,k256[10],p[10]);
|
||||
one_cycle(5,6,7,0,1,2,3,4,k256[11],p[11]);
|
||||
one_cycle(4,5,6,7,0,1,2,3,k256[12],p[12]);
|
||||
one_cycle(3,4,5,6,7,0,1,2,k256[13],p[13]);
|
||||
one_cycle(2,3,4,5,6,7,0,1,k256[14],p[14]);
|
||||
one_cycle(1,2,3,4,5,6,7,0,k256[15],p[15]);
|
||||
|
||||
one_cycle(0,1,2,3,4,5,6,7,k256[16],hf( 0));
|
||||
one_cycle(7,0,1,2,3,4,5,6,k256[17],hf( 1));
|
||||
one_cycle(6,7,0,1,2,3,4,5,k256[18],hf( 2));
|
||||
one_cycle(5,6,7,0,1,2,3,4,k256[19],hf( 3));
|
||||
one_cycle(4,5,6,7,0,1,2,3,k256[20],hf( 4));
|
||||
one_cycle(3,4,5,6,7,0,1,2,k256[21],hf( 5));
|
||||
one_cycle(2,3,4,5,6,7,0,1,k256[22],hf( 6));
|
||||
one_cycle(1,2,3,4,5,6,7,0,k256[23],hf( 7));
|
||||
one_cycle(0,1,2,3,4,5,6,7,k256[24],hf( 8));
|
||||
one_cycle(7,0,1,2,3,4,5,6,k256[25],hf( 9));
|
||||
one_cycle(6,7,0,1,2,3,4,5,k256[26],hf(10));
|
||||
one_cycle(5,6,7,0,1,2,3,4,k256[27],hf(11));
|
||||
one_cycle(4,5,6,7,0,1,2,3,k256[28],hf(12));
|
||||
one_cycle(3,4,5,6,7,0,1,2,k256[29],hf(13));
|
||||
one_cycle(2,3,4,5,6,7,0,1,k256[30],hf(14));
|
||||
one_cycle(1,2,3,4,5,6,7,0,k256[31],hf(15));
|
||||
|
||||
one_cycle(0,1,2,3,4,5,6,7,k256[32],hf( 0));
|
||||
one_cycle(7,0,1,2,3,4,5,6,k256[33],hf( 1));
|
||||
one_cycle(6,7,0,1,2,3,4,5,k256[34],hf( 2));
|
||||
one_cycle(5,6,7,0,1,2,3,4,k256[35],hf( 3));
|
||||
one_cycle(4,5,6,7,0,1,2,3,k256[36],hf( 4));
|
||||
one_cycle(3,4,5,6,7,0,1,2,k256[37],hf( 5));
|
||||
one_cycle(2,3,4,5,6,7,0,1,k256[38],hf( 6));
|
||||
one_cycle(1,2,3,4,5,6,7,0,k256[39],hf( 7));
|
||||
one_cycle(0,1,2,3,4,5,6,7,k256[40],hf( 8));
|
||||
one_cycle(7,0,1,2,3,4,5,6,k256[41],hf( 9));
|
||||
one_cycle(6,7,0,1,2,3,4,5,k256[42],hf(10));
|
||||
one_cycle(5,6,7,0,1,2,3,4,k256[43],hf(11));
|
||||
one_cycle(4,5,6,7,0,1,2,3,k256[44],hf(12));
|
||||
one_cycle(3,4,5,6,7,0,1,2,k256[45],hf(13));
|
||||
one_cycle(2,3,4,5,6,7,0,1,k256[46],hf(14));
|
||||
one_cycle(1,2,3,4,5,6,7,0,k256[47],hf(15));
|
||||
|
||||
one_cycle(0,1,2,3,4,5,6,7,k256[48],hf( 0));
|
||||
one_cycle(7,0,1,2,3,4,5,6,k256[49],hf( 1));
|
||||
one_cycle(6,7,0,1,2,3,4,5,k256[50],hf( 2));
|
||||
one_cycle(5,6,7,0,1,2,3,4,k256[51],hf( 3));
|
||||
one_cycle(4,5,6,7,0,1,2,3,k256[52],hf( 4));
|
||||
one_cycle(3,4,5,6,7,0,1,2,k256[53],hf( 5));
|
||||
one_cycle(2,3,4,5,6,7,0,1,k256[54],hf( 6));
|
||||
one_cycle(1,2,3,4,5,6,7,0,k256[55],hf( 7));
|
||||
one_cycle(0,1,2,3,4,5,6,7,k256[56],hf( 8));
|
||||
one_cycle(7,0,1,2,3,4,5,6,k256[57],hf( 9));
|
||||
one_cycle(6,7,0,1,2,3,4,5,k256[58],hf(10));
|
||||
one_cycle(5,6,7,0,1,2,3,4,k256[59],hf(11));
|
||||
one_cycle(4,5,6,7,0,1,2,3,k256[60],hf(12));
|
||||
one_cycle(3,4,5,6,7,0,1,2,k256[61],hf(13));
|
||||
one_cycle(2,3,4,5,6,7,0,1,k256[62],hf(14));
|
||||
one_cycle(1,2,3,4,5,6,7,0,k256[63],hf(15));
|
||||
|
||||
ctx->hash[0] += v0; ctx->hash[1] += v1;
|
||||
ctx->hash[2] += v2; ctx->hash[3] += v3;
|
||||
ctx->hash[4] += v4; ctx->hash[5] += v5;
|
||||
ctx->hash[6] += v6; ctx->hash[7] += v7;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* SHA256 hash data in an array of bytes into hash buffer */
|
||||
/* and call the hash_compile function as required. */
|
||||
|
||||
VOID_RETURN sha256_hash(const unsigned char data[], unsigned long len, sha256_ctx ctx[1])
|
||||
{ uint32_t pos = (uint32_t)((ctx->count[0] >> 3) & SHA256_MASK);
|
||||
const unsigned char *sp = data;
|
||||
unsigned char *w = (unsigned char*)ctx->wbuf;
|
||||
#if SHA2_BITS == 1
|
||||
uint32_t ofs = (ctx->count[0] & 7);
|
||||
#else
|
||||
len <<= 3;
|
||||
#endif
|
||||
if((ctx->count[0] += len) < len)
|
||||
++(ctx->count[1]);
|
||||
|
||||
#if SHA2_BITS == 1
|
||||
if(ofs) /* if not on a byte boundary */
|
||||
{
|
||||
if(ofs + len < 8) /* if no added bytes are needed */
|
||||
{
|
||||
w[pos] |= (*sp >> ofs);
|
||||
}
|
||||
else /* otherwise and add bytes */
|
||||
{ unsigned char part = w[pos];
|
||||
|
||||
while((int)(ofs + (len -= 8)) >= 0)
|
||||
{
|
||||
w[pos++] = part | (*sp >> ofs);
|
||||
part = *sp++ << (8 - ofs);
|
||||
if(pos == SHA256_BLOCK_SIZE)
|
||||
{
|
||||
bsw_32(w, SHA256_BLOCK_SIZE >> 2);
|
||||
sha256_compile(ctx); pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
w[pos] = part;
|
||||
}
|
||||
}
|
||||
else /* data is byte aligned */
|
||||
#endif
|
||||
{ uint32_t space = SHA256_BLOCK_SIZE - pos;
|
||||
|
||||
while(len >= (space << 3))
|
||||
{
|
||||
memcpy(w + pos, sp, space);
|
||||
bsw_32(w, SHA256_BLOCK_SIZE >> 2);
|
||||
sha256_compile(ctx);
|
||||
sp += space; len -= (space << 3);
|
||||
space = SHA256_BLOCK_SIZE; pos = 0;
|
||||
}
|
||||
memcpy(w + pos, sp, (len + 7 * SHA2_BITS) >> 3);
|
||||
}
|
||||
}
|
||||
|
||||
/* SHA256 Final padding and digest calculation */
|
||||
|
||||
static void sha_end1(unsigned char hval[], sha256_ctx ctx[1], const unsigned int hlen)
|
||||
{ uint32_t i = (uint32_t)((ctx->count[0] >> 3) & SHA256_MASK), m1;
|
||||
|
||||
/* put bytes in the buffer in an order in which references to */
|
||||
/* 32-bit words will put bytes with lower addresses into the */
|
||||
/* top of 32 bit words on BOTH big and little endian machines */
|
||||
bsw_32(ctx->wbuf, (i + 3 + SHA2_BITS) >> 2)
|
||||
|
||||
/* we now need to mask valid bytes and add the padding which is */
|
||||
/* a single 1 bit and as many zero bits as necessary. Note that */
|
||||
/* we can always add the first padding byte here because the */
|
||||
/* buffer always has at least one empty slot */
|
||||
m1 = (unsigned char)0x80 >> (ctx->count[0] & 7);
|
||||
ctx->wbuf[i >> 2] &= ((0xffffff00 | (~m1 + 1)) << 8 * (~i & 3));
|
||||
ctx->wbuf[i >> 2] |= (m1 << 8 * (~i & 3));
|
||||
|
||||
/* we need 9 or more empty positions, one for the padding byte */
|
||||
/* (above) and eight for the length count. If there is not */
|
||||
/* enough space pad and empty the buffer */
|
||||
if(i > SHA256_BLOCK_SIZE - 9)
|
||||
{
|
||||
if(i < 60) ctx->wbuf[15] = 0;
|
||||
sha256_compile(ctx);
|
||||
i = 0;
|
||||
}
|
||||
else /* compute a word index for the empty buffer positions */
|
||||
i = (i >> 2) + 1;
|
||||
|
||||
while(i < 14) /* and zero pad all but last two positions */
|
||||
ctx->wbuf[i++] = 0;
|
||||
|
||||
/* the following 32-bit length fields are assembled in the */
|
||||
/* wrong byte order on little endian machines but this is */
|
||||
/* corrected later since they are only ever used as 32-bit */
|
||||
/* word values. */
|
||||
ctx->wbuf[14] = ctx->count[1];
|
||||
ctx->wbuf[15] = ctx->count[0];
|
||||
sha256_compile(ctx);
|
||||
|
||||
/* extract the hash value as bytes in case the hash buffer is */
|
||||
/* misaligned for 32-bit words */
|
||||
for(i = 0; i < hlen; ++i)
|
||||
hval[i] = ((ctx->hash[i >> 2] >> (8 * (~i & 3))) & 0xff);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(SHA_224)
|
||||
|
||||
const uint32_t i224[8] =
|
||||
{
|
||||
0xc1059ed8ul, 0x367cd507ul, 0x3070dd17ul, 0xf70e5939ul,
|
||||
0xffc00b31ul, 0x68581511ul, 0x64f98fa7ul, 0xbefa4fa4ul
|
||||
};
|
||||
|
||||
VOID_RETURN sha224_begin(sha224_ctx ctx[1])
|
||||
{
|
||||
memset(ctx, 0, sizeof(sha224_ctx));
|
||||
memcpy(ctx->hash, i224, sizeof(ctx->hash));
|
||||
}
|
||||
|
||||
VOID_RETURN sha224_end(unsigned char hval[], sha224_ctx ctx[1])
|
||||
{
|
||||
sha_end1(hval, ctx, SHA224_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
VOID_RETURN sha224(unsigned char hval[], const unsigned char data[], unsigned long len)
|
||||
{ sha224_ctx cx[1];
|
||||
|
||||
sha224_begin(cx);
|
||||
sha224_hash(data, len, cx);
|
||||
sha_end1(hval, cx, SHA224_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(SHA_256)
|
||||
|
||||
const uint32_t i256[8] =
|
||||
{
|
||||
0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul,
|
||||
0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul
|
||||
};
|
||||
|
||||
VOID_RETURN sha256_begin(sha256_ctx ctx[1])
|
||||
{
|
||||
memset(ctx, 0, sizeof(sha256_ctx));
|
||||
memcpy(ctx->hash, i256, sizeof(ctx->hash));
|
||||
}
|
||||
|
||||
VOID_RETURN sha256_end(unsigned char hval[], sha256_ctx ctx[1])
|
||||
{
|
||||
sha_end1(hval, ctx, SHA256_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
VOID_RETURN sha256(unsigned char hval[], const unsigned char data[], unsigned long len)
|
||||
{ sha256_ctx cx[1];
|
||||
|
||||
sha256_begin(cx);
|
||||
sha256_hash(data, len, cx);
|
||||
sha_end1(hval, cx, SHA256_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(SHA_384) || defined(SHA_512)
|
||||
|
||||
#define SHA512_MASK (SHA512_BLOCK_SIZE - 1)
|
||||
|
||||
#define rotr64(x,n) (((x) >> n) | ((x) << (64 - n)))
|
||||
|
||||
#if !defined(bswap_64)
|
||||
#define bswap_64(x) (((uint64_t)(bswap_32((uint32_t)(x)))) << 32 | bswap_32((uint32_t)((x) >> 32)))
|
||||
#endif
|
||||
|
||||
#if defined(SWAP_BYTES)
|
||||
#define bsw_64(p,n) \
|
||||
{ int _i = (n); while(_i--) ((uint64_t*)p)[_i] = bswap_64(((uint64_t*)p)[_i]); }
|
||||
#else
|
||||
#define bsw_64(p,n)
|
||||
#endif
|
||||
|
||||
/* SHA512 mixing function definitions */
|
||||
|
||||
#ifdef s_0
|
||||
# undef s_0
|
||||
# undef s_1
|
||||
# undef g_0
|
||||
# undef g_1
|
||||
# undef k_0
|
||||
#endif
|
||||
|
||||
#define s_0(x) (rotr64((x), 28) ^ rotr64((x), 34) ^ rotr64((x), 39))
|
||||
#define s_1(x) (rotr64((x), 14) ^ rotr64((x), 18) ^ rotr64((x), 41))
|
||||
#define g_0(x) (rotr64((x), 1) ^ rotr64((x), 8) ^ ((x) >> 7))
|
||||
#define g_1(x) (rotr64((x), 19) ^ rotr64((x), 61) ^ ((x) >> 6))
|
||||
#define k_0 k512
|
||||
|
||||
/* SHA384/SHA512 mixing data */
|
||||
|
||||
const uint64_t k512[80] =
|
||||
{
|
||||
li_64(428a2f98d728ae22), li_64(7137449123ef65cd),
|
||||
li_64(b5c0fbcfec4d3b2f), li_64(e9b5dba58189dbbc),
|
||||
li_64(3956c25bf348b538), li_64(59f111f1b605d019),
|
||||
li_64(923f82a4af194f9b), li_64(ab1c5ed5da6d8118),
|
||||
li_64(d807aa98a3030242), li_64(12835b0145706fbe),
|
||||
li_64(243185be4ee4b28c), li_64(550c7dc3d5ffb4e2),
|
||||
li_64(72be5d74f27b896f), li_64(80deb1fe3b1696b1),
|
||||
li_64(9bdc06a725c71235), li_64(c19bf174cf692694),
|
||||
li_64(e49b69c19ef14ad2), li_64(efbe4786384f25e3),
|
||||
li_64(0fc19dc68b8cd5b5), li_64(240ca1cc77ac9c65),
|
||||
li_64(2de92c6f592b0275), li_64(4a7484aa6ea6e483),
|
||||
li_64(5cb0a9dcbd41fbd4), li_64(76f988da831153b5),
|
||||
li_64(983e5152ee66dfab), li_64(a831c66d2db43210),
|
||||
li_64(b00327c898fb213f), li_64(bf597fc7beef0ee4),
|
||||
li_64(c6e00bf33da88fc2), li_64(d5a79147930aa725),
|
||||
li_64(06ca6351e003826f), li_64(142929670a0e6e70),
|
||||
li_64(27b70a8546d22ffc), li_64(2e1b21385c26c926),
|
||||
li_64(4d2c6dfc5ac42aed), li_64(53380d139d95b3df),
|
||||
li_64(650a73548baf63de), li_64(766a0abb3c77b2a8),
|
||||
li_64(81c2c92e47edaee6), li_64(92722c851482353b),
|
||||
li_64(a2bfe8a14cf10364), li_64(a81a664bbc423001),
|
||||
li_64(c24b8b70d0f89791), li_64(c76c51a30654be30),
|
||||
li_64(d192e819d6ef5218), li_64(d69906245565a910),
|
||||
li_64(f40e35855771202a), li_64(106aa07032bbd1b8),
|
||||
li_64(19a4c116b8d2d0c8), li_64(1e376c085141ab53),
|
||||
li_64(2748774cdf8eeb99), li_64(34b0bcb5e19b48a8),
|
||||
li_64(391c0cb3c5c95a63), li_64(4ed8aa4ae3418acb),
|
||||
li_64(5b9cca4f7763e373), li_64(682e6ff3d6b2b8a3),
|
||||
li_64(748f82ee5defb2fc), li_64(78a5636f43172f60),
|
||||
li_64(84c87814a1f0ab72), li_64(8cc702081a6439ec),
|
||||
li_64(90befffa23631e28), li_64(a4506cebde82bde9),
|
||||
li_64(bef9a3f7b2c67915), li_64(c67178f2e372532b),
|
||||
li_64(ca273eceea26619c), li_64(d186b8c721c0c207),
|
||||
li_64(eada7dd6cde0eb1e), li_64(f57d4f7fee6ed178),
|
||||
li_64(06f067aa72176fba), li_64(0a637dc5a2c898a6),
|
||||
li_64(113f9804bef90dae), li_64(1b710b35131c471b),
|
||||
li_64(28db77f523047d84), li_64(32caab7b40c72493),
|
||||
li_64(3c9ebe0a15c9bebc), li_64(431d67c49c100d4c),
|
||||
li_64(4cc5d4becb3e42b6), li_64(597f299cfc657e2a),
|
||||
li_64(5fcb6fab3ad6faec), li_64(6c44198c4a475817)
|
||||
};
|
||||
|
||||
/* Compile 128 bytes of hash data into SHA384/512 digest */
|
||||
/* NOTE: this routine assumes that the byte order in the */
|
||||
/* ctx->wbuf[] at this point is such that low address bytes */
|
||||
/* in the ORIGINAL byte stream will go into the high end of */
|
||||
/* words on BOTH big and little endian systems */
|
||||
|
||||
VOID_RETURN sha512_compile(sha512_ctx ctx[1])
|
||||
{ uint64_t v[8], *p = ctx->wbuf;
|
||||
uint32_t j;
|
||||
|
||||
memcpy(v, ctx->hash, sizeof(ctx->hash));
|
||||
|
||||
for(j = 0; j < 80; j += 16)
|
||||
{
|
||||
v_cycle( 0, j); v_cycle( 1, j);
|
||||
v_cycle( 2, j); v_cycle( 3, j);
|
||||
v_cycle( 4, j); v_cycle( 5, j);
|
||||
v_cycle( 6, j); v_cycle( 7, j);
|
||||
v_cycle( 8, j); v_cycle( 9, j);
|
||||
v_cycle(10, j); v_cycle(11, j);
|
||||
v_cycle(12, j); v_cycle(13, j);
|
||||
v_cycle(14, j); v_cycle(15, j);
|
||||
}
|
||||
|
||||
ctx->hash[0] += v[0]; ctx->hash[1] += v[1];
|
||||
ctx->hash[2] += v[2]; ctx->hash[3] += v[3];
|
||||
ctx->hash[4] += v[4]; ctx->hash[5] += v[5];
|
||||
ctx->hash[6] += v[6]; ctx->hash[7] += v[7];
|
||||
}
|
||||
|
||||
/* Compile 128 bytes of hash data into SHA256 digest value */
|
||||
/* NOTE: this routine assumes that the byte order in the */
|
||||
/* ctx->wbuf[] at this point is in such an order that low */
|
||||
/* address bytes in the ORIGINAL byte stream placed in this */
|
||||
/* buffer will now go to the high end of words on BOTH big */
|
||||
/* and little endian systems */
|
||||
|
||||
VOID_RETURN sha512_hash(const unsigned char data[], unsigned long len, sha512_ctx ctx[1])
|
||||
{ uint32_t pos = (uint32_t)(ctx->count[0] >> 3) & SHA512_MASK;
|
||||
const unsigned char *sp = data;
|
||||
unsigned char *w = (unsigned char*)ctx->wbuf;
|
||||
#if SHA2_BITS == 1
|
||||
uint32_t ofs = (ctx->count[0] & 7);
|
||||
#else
|
||||
len <<= 3;
|
||||
#endif
|
||||
|
||||
if((ctx->count[0] += len) < len)
|
||||
++(ctx->count[1]);
|
||||
|
||||
#if SHA2_BITS == 1
|
||||
if(ofs) /* if not on a byte boundary */
|
||||
{
|
||||
if(ofs + len < 8) /* if no added bytes are needed */
|
||||
{
|
||||
w[pos] |= (*sp >> ofs);
|
||||
}
|
||||
else /* otherwise and add bytes */
|
||||
{ unsigned char part = w[pos];
|
||||
|
||||
while((int)(ofs + (len -= 8)) >= 0)
|
||||
{
|
||||
w[pos++] = part | (*sp >> ofs);
|
||||
part = *sp++ << (8 - ofs);
|
||||
if(pos == SHA512_BLOCK_SIZE)
|
||||
{
|
||||
bsw_64(w, SHA512_BLOCK_SIZE >> 3);
|
||||
sha512_compile(ctx); pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
w[pos] = part;
|
||||
}
|
||||
}
|
||||
else /* data is byte aligned */
|
||||
#endif
|
||||
{ uint32_t space = SHA512_BLOCK_SIZE - pos;
|
||||
|
||||
while(len >= (space << 3))
|
||||
{
|
||||
memcpy(w + pos, sp, space);
|
||||
bsw_64(w, SHA512_BLOCK_SIZE >> 3);
|
||||
sha512_compile(ctx);
|
||||
sp += space; len -= (space << 3);
|
||||
space = SHA512_BLOCK_SIZE; pos = 0;
|
||||
}
|
||||
memcpy(w + pos, sp, (len + 7 * SHA2_BITS) >> 3);
|
||||
}
|
||||
}
|
||||
|
||||
/* SHA384/512 Final padding and digest calculation */
|
||||
|
||||
static void sha_end2(unsigned char hval[], sha512_ctx ctx[1], const unsigned int hlen)
|
||||
{ uint32_t i = (uint32_t)((ctx->count[0] >> 3) & SHA512_MASK);
|
||||
uint64_t m1;
|
||||
|
||||
/* put bytes in the buffer in an order in which references to */
|
||||
/* 32-bit words will put bytes with lower addresses into the */
|
||||
/* top of 32 bit words on BOTH big and little endian machines */
|
||||
bsw_64(ctx->wbuf, (i + 7 + SHA2_BITS) >> 3);
|
||||
|
||||
/* we now need to mask valid bytes and add the padding which is */
|
||||
/* a single 1 bit and as many zero bits as necessary. Note that */
|
||||
/* we can always add the first padding byte here because the */
|
||||
/* buffer always has at least one empty slot */
|
||||
m1 = (unsigned char)0x80 >> (ctx->count[0] & 7);
|
||||
ctx->wbuf[i >> 3] &= ((li_64(ffffffffffffff00) | (~m1 + 1)) << 8 * (~i & 7));
|
||||
ctx->wbuf[i >> 3] |= (m1 << 8 * (~i & 7));
|
||||
|
||||
/* we need 17 or more empty byte positions, one for the padding */
|
||||
/* byte (above) and sixteen for the length count. If there is */
|
||||
/* not enough space pad and empty the buffer */
|
||||
if(i > SHA512_BLOCK_SIZE - 17)
|
||||
{
|
||||
if(i < 120) ctx->wbuf[15] = 0;
|
||||
sha512_compile(ctx);
|
||||
i = 0;
|
||||
}
|
||||
else
|
||||
i = (i >> 3) + 1;
|
||||
|
||||
while(i < 14)
|
||||
ctx->wbuf[i++] = 0;
|
||||
|
||||
/* the following 64-bit length fields are assembled in the */
|
||||
/* wrong byte order on little endian machines but this is */
|
||||
/* corrected later since they are only ever used as 64-bit */
|
||||
/* word values. */
|
||||
ctx->wbuf[14] = ctx->count[1];
|
||||
ctx->wbuf[15] = ctx->count[0];
|
||||
sha512_compile(ctx);
|
||||
|
||||
/* extract the hash value as bytes in case the hash buffer is */
|
||||
/* misaligned for 32-bit words */
|
||||
for(i = 0; i < hlen; ++i)
|
||||
hval[i] = ((ctx->hash[i >> 3] >> (8 * (~i & 7))) & 0xff);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(SHA_384)
|
||||
|
||||
/* SHA384 initialisation data */
|
||||
|
||||
const uint64_t i384[80] =
|
||||
{
|
||||
li_64(cbbb9d5dc1059ed8), li_64(629a292a367cd507),
|
||||
li_64(9159015a3070dd17), li_64(152fecd8f70e5939),
|
||||
li_64(67332667ffc00b31), li_64(8eb44a8768581511),
|
||||
li_64(db0c2e0d64f98fa7), li_64(47b5481dbefa4fa4)
|
||||
};
|
||||
|
||||
VOID_RETURN sha384_begin(sha384_ctx ctx[1])
|
||||
{
|
||||
memset(ctx, 0, sizeof(sha384_ctx));
|
||||
memcpy(ctx->hash, i384, sizeof(ctx->hash));
|
||||
}
|
||||
|
||||
VOID_RETURN sha384_end(unsigned char hval[], sha384_ctx ctx[1])
|
||||
{
|
||||
sha_end2(hval, ctx, SHA384_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
VOID_RETURN sha384(unsigned char hval[], const unsigned char data[], unsigned long len)
|
||||
{ sha384_ctx cx[1];
|
||||
|
||||
sha384_begin(cx);
|
||||
sha384_hash(data, len, cx);
|
||||
sha_end2(hval, cx, SHA384_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(SHA_512)
|
||||
|
||||
/* SHA512 initialisation data */
|
||||
|
||||
static const uint64_t i512[SHA512_DIGEST_SIZE >> 3] =
|
||||
{
|
||||
li_64(6a09e667f3bcc908), li_64(bb67ae8584caa73b),
|
||||
li_64(3c6ef372fe94f82b), li_64(a54ff53a5f1d36f1),
|
||||
li_64(510e527fade682d1), li_64(9b05688c2b3e6c1f),
|
||||
li_64(1f83d9abfb41bd6b), li_64(5be0cd19137e2179)
|
||||
};
|
||||
|
||||
/* FIPS PUB 180-4: SHA-512/256 */
|
||||
|
||||
static const uint64_t i512_256[SHA512_DIGEST_SIZE >> 3] =
|
||||
{
|
||||
li_64(22312194fc2bf72c), li_64(9f555fa3c84c64c2),
|
||||
li_64(2393b86b6f53b151), li_64(963877195940eabd),
|
||||
li_64(96283ee2a88effe3), li_64(be5e1e2553863992),
|
||||
li_64(2b0199fc2c85b8aa), li_64(0eb72ddc81c52ca2),
|
||||
};
|
||||
|
||||
/* FIPS PUB 180-4: SHA-512/224 */
|
||||
|
||||
static const uint64_t i512_224[SHA512_DIGEST_SIZE >> 3] =
|
||||
{
|
||||
li_64(8c3d37c819544da2), li_64(73e1996689dcd4d6),
|
||||
li_64(1dfab7ae32ff9c82), li_64(679dd514582f9fcf),
|
||||
li_64(0f6d2b697bd44da8), li_64(77e36f7304c48942),
|
||||
li_64(3f9d85a86a1d36c8), li_64(1112e6ad91d692a1),
|
||||
};
|
||||
|
||||
/* FIPS PUB 180-4: SHA-512/192 (unsanctioned; facilitates using AES-192) */
|
||||
|
||||
static const uint64_t i512_192[SHA512_DIGEST_SIZE >> 3] =
|
||||
{
|
||||
li_64(010176140648b233), li_64(db92aeb1eebadd6f),
|
||||
li_64(83a9e27aa1d5ea62), li_64(ec95f77eb609b4e1),
|
||||
li_64(71a99185c75caefa), li_64(006e8f08baf32e3c),
|
||||
li_64(6a2b21abd2db2aec), li_64(24926cdbd918a27f),
|
||||
};
|
||||
|
||||
/* FIPS PUB 180-4: SHA-512/128 (unsanctioned; facilitates using AES-128) */
|
||||
|
||||
static const uint64_t i512_128[SHA512_DIGEST_SIZE >> 3] =
|
||||
{
|
||||
li_64(c953a21464c3e8cc), li_64(06cc9cfd166a34b5),
|
||||
li_64(647e88dabf8b24ab), li_64(8513e4dc05a078ac),
|
||||
li_64(7266fcfb7cba0534), li_64(854a78e2ecd19b93),
|
||||
li_64(8618061711cec2dd), li_64(b20d8506efb929b1),
|
||||
};
|
||||
|
||||
VOID_RETURN sha512_begin(sha512_ctx ctx[1])
|
||||
{
|
||||
memset(ctx, 0, sizeof(sha512_ctx));
|
||||
memcpy(ctx->hash, i512, sizeof(ctx->hash));
|
||||
}
|
||||
|
||||
VOID_RETURN sha512_256_begin(sha512_ctx ctx[1])
|
||||
{
|
||||
memset(ctx, 0, sizeof(sha512_ctx));
|
||||
memcpy(ctx->hash, i512_256, sizeof(ctx->hash));
|
||||
}
|
||||
|
||||
VOID_RETURN sha512_224_begin(sha512_ctx ctx[1])
|
||||
{
|
||||
memset(ctx, 0, sizeof(sha512_ctx));
|
||||
memcpy(ctx->hash, i512_224, sizeof(ctx->hash));
|
||||
}
|
||||
|
||||
VOID_RETURN sha512_192_begin(sha512_ctx ctx[1])
|
||||
{
|
||||
memset(ctx, 0, sizeof(sha512_ctx));
|
||||
memcpy(ctx->hash, i512_192, sizeof(ctx->hash));
|
||||
}
|
||||
|
||||
VOID_RETURN sha512_128_begin(sha512_ctx ctx[1])
|
||||
{
|
||||
memset(ctx, 0, sizeof(sha512_ctx));
|
||||
memcpy(ctx->hash, i512_128, sizeof(ctx->hash));
|
||||
}
|
||||
|
||||
VOID_RETURN sha512_end(unsigned char hval[], sha512_ctx ctx[1])
|
||||
{
|
||||
sha_end2(hval, ctx, SHA512_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
VOID_RETURN sha512_256_end(unsigned char hval[], sha512_ctx ctx[1])
|
||||
{
|
||||
sha_end2(hval, ctx, SHA512_256_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
VOID_RETURN sha512_224_end(unsigned char hval[], sha512_ctx ctx[1])
|
||||
{
|
||||
sha_end2(hval, ctx, SHA512_224_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
VOID_RETURN sha512_192_end(unsigned char hval[], sha512_ctx ctx[1])
|
||||
{
|
||||
sha_end2(hval, ctx, SHA512_192_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
VOID_RETURN sha512_128_end(unsigned char hval[], sha512_ctx ctx[1])
|
||||
{
|
||||
sha_end2(hval, ctx, SHA512_128_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
VOID_RETURN sha512(unsigned char hval[], const unsigned char data[], unsigned long len)
|
||||
{ sha512_ctx cx[1];
|
||||
|
||||
sha512_begin(cx);
|
||||
sha512_hash(data, len, cx);
|
||||
sha512_end(hval, cx);
|
||||
}
|
||||
|
||||
VOID_RETURN sha512_256(unsigned char hval[], const unsigned char data[], unsigned long len)
|
||||
{ sha512_ctx cx[1];
|
||||
|
||||
sha512_256_begin(cx);
|
||||
sha512_256_hash(data, len, cx);
|
||||
sha512_256_end(hval, cx);
|
||||
}
|
||||
|
||||
VOID_RETURN sha512_224(unsigned char hval[], const unsigned char data[], unsigned long len)
|
||||
{ sha512_ctx cx[1];
|
||||
|
||||
sha512_224_begin(cx);
|
||||
sha512_224_hash(data, len, cx);
|
||||
sha512_224_end(hval, cx);
|
||||
}
|
||||
|
||||
VOID_RETURN sha512_192(unsigned char hval[], const unsigned char data[], unsigned long len)
|
||||
{ sha512_ctx cx[1];
|
||||
|
||||
sha512_192_begin(cx);
|
||||
sha512_192_hash(data, len, cx);
|
||||
sha512_192_end(hval, cx);
|
||||
}
|
||||
|
||||
VOID_RETURN sha512_128(unsigned char hval[], const unsigned char data[], unsigned long len)
|
||||
{ sha512_ctx cx[1];
|
||||
|
||||
sha512_128_begin(cx);
|
||||
sha512_128_hash(data, len, cx);
|
||||
sha512_128_end(hval, cx);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(SHA_2)
|
||||
|
||||
#define CTX_224(x) ((x)->uu->ctx256)
|
||||
#define CTX_256(x) ((x)->uu->ctx256)
|
||||
#define CTX_384(x) ((x)->uu->ctx512)
|
||||
#define CTX_512(x) ((x)->uu->ctx512)
|
||||
|
||||
/* SHA2 initialisation */
|
||||
|
||||
INT_RETURN sha2_begin(unsigned long len, sha2_ctx ctx[1])
|
||||
{
|
||||
switch(len)
|
||||
{
|
||||
#if defined(SHA_224)
|
||||
case 224:
|
||||
case 28: CTX_256(ctx)->count[0] = CTX_256(ctx)->count[1] = 0;
|
||||
memcpy(CTX_256(ctx)->hash, i224, 32);
|
||||
ctx->sha2_len = 28; return EXIT_SUCCESS;
|
||||
#endif
|
||||
#if defined(SHA_256)
|
||||
case 256:
|
||||
case 32: CTX_256(ctx)->count[0] = CTX_256(ctx)->count[1] = 0;
|
||||
memcpy(CTX_256(ctx)->hash, i256, 32);
|
||||
ctx->sha2_len = 32; return EXIT_SUCCESS;
|
||||
#endif
|
||||
#if defined(SHA_384)
|
||||
case 384:
|
||||
case 48: CTX_384(ctx)->count[0] = CTX_384(ctx)->count[1] = 0;
|
||||
memcpy(CTX_384(ctx)->hash, i384, 64);
|
||||
ctx->sha2_len = 48; return EXIT_SUCCESS;
|
||||
#endif
|
||||
#if defined(SHA_512)
|
||||
case 512:
|
||||
case 64: CTX_512(ctx)->count[0] = CTX_512(ctx)->count[1] = 0;
|
||||
memcpy(CTX_512(ctx)->hash, i512, 64);
|
||||
ctx->sha2_len = 64; return EXIT_SUCCESS;
|
||||
#endif
|
||||
default: return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
VOID_RETURN sha2_hash(const unsigned char data[], unsigned long len, sha2_ctx ctx[1])
|
||||
{
|
||||
switch(ctx->sha2_len)
|
||||
{
|
||||
#if defined(SHA_224)
|
||||
case 28: sha224_hash(data, len, CTX_224(ctx)); return;
|
||||
#endif
|
||||
#if defined(SHA_256)
|
||||
case 32: sha256_hash(data, len, CTX_256(ctx)); return;
|
||||
#endif
|
||||
#if defined(SHA_384)
|
||||
case 48: sha384_hash(data, len, CTX_384(ctx)); return;
|
||||
#endif
|
||||
#if defined(SHA_512)
|
||||
case 64: sha512_hash(data, len, CTX_512(ctx)); return;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
VOID_RETURN sha2_end(unsigned char hval[], sha2_ctx ctx[1])
|
||||
{
|
||||
switch(ctx->sha2_len)
|
||||
{
|
||||
#if defined(SHA_224)
|
||||
case 28: sha_end1(hval, CTX_224(ctx), SHA224_DIGEST_SIZE); return;
|
||||
#endif
|
||||
#if defined(SHA_256)
|
||||
case 32: sha_end1(hval, CTX_256(ctx), SHA256_DIGEST_SIZE); return;
|
||||
#endif
|
||||
#if defined(SHA_384)
|
||||
case 48: sha_end2(hval, CTX_384(ctx), SHA384_DIGEST_SIZE); return;
|
||||
#endif
|
||||
#if defined(SHA_512)
|
||||
case 64: sha_end2(hval, CTX_512(ctx), SHA512_DIGEST_SIZE); return;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
INT_RETURN sha2(unsigned char hval[], unsigned long size,
|
||||
const unsigned char data[], unsigned long len)
|
||||
{ sha2_ctx cx[1];
|
||||
|
||||
if(sha2_begin(size, cx) == EXIT_SUCCESS)
|
||||
{
|
||||
sha2_hash(data, len, cx); sha2_end(hval, cx); return EXIT_SUCCESS;
|
||||
}
|
||||
else
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
+183
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
*/
|
||||
|
||||
#ifndef _SHA2_H
|
||||
#define _SHA2_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* define for bit or byte oriented SHA */
|
||||
#if 1
|
||||
# define SHA2_BITS 0 /* byte oriented */
|
||||
#else
|
||||
# define SHA2_BITS 1 /* bit oriented */
|
||||
#endif
|
||||
|
||||
/* define the hash functions that you need */
|
||||
/* define for 64-bit SHA384 and SHA512 */
|
||||
#define SHA_64BIT
|
||||
#define SHA_2 /* for dynamic hash length */
|
||||
#define SHA_224
|
||||
#define SHA_256
|
||||
#ifdef SHA_64BIT
|
||||
# define SHA_384
|
||||
# define SHA_512
|
||||
# define NEED_uint64_t
|
||||
#endif
|
||||
|
||||
#define SHA2_MAX_DIGEST_SIZE 64
|
||||
#define SHA2_MAX_BLOCK_SIZE 128
|
||||
|
||||
#include "brg_types.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* Note that the following function prototypes are the same */
|
||||
/* for both the bit and byte oriented implementations. But */
|
||||
/* the length fields are in bytes or bits as is appropriate */
|
||||
/* for the version used. Bit sequences are arrays of bytes */
|
||||
/* in which bit sequence indexes increase from the most to */
|
||||
/* the least significant end of each byte. The value 'len' */
|
||||
/* in sha<nnn>_hash for the byte oriented versions of SHA2 */
|
||||
/* is limited to 2^29 bytes, but multiple calls will handle */
|
||||
/* longer data blocks. */
|
||||
|
||||
#define SHA224_DIGEST_SIZE 28
|
||||
#define SHA224_BLOCK_SIZE 64
|
||||
|
||||
#define SHA256_DIGEST_SIZE 32
|
||||
#define SHA256_BLOCK_SIZE 64
|
||||
|
||||
/* type to hold the SHA256 (and SHA224) context */
|
||||
|
||||
typedef struct
|
||||
{ uint32_t count[2];
|
||||
uint32_t hash[SHA256_DIGEST_SIZE >> 2];
|
||||
uint32_t wbuf[SHA256_BLOCK_SIZE >> 2];
|
||||
} sha256_ctx;
|
||||
|
||||
typedef sha256_ctx sha224_ctx;
|
||||
|
||||
VOID_RETURN sha256_compile(sha256_ctx ctx[1]);
|
||||
|
||||
VOID_RETURN sha224_begin(sha224_ctx ctx[1]);
|
||||
#define sha224_hash sha256_hash
|
||||
VOID_RETURN sha224_end(unsigned char hval[], sha224_ctx ctx[1]);
|
||||
VOID_RETURN sha224(unsigned char hval[], const unsigned char data[], unsigned long len);
|
||||
|
||||
VOID_RETURN sha256_begin(sha256_ctx ctx[1]);
|
||||
VOID_RETURN sha256_hash(const unsigned char data[], unsigned long len, sha256_ctx ctx[1]);
|
||||
VOID_RETURN sha256_end(unsigned char hval[], sha256_ctx ctx[1]);
|
||||
VOID_RETURN sha256(unsigned char hval[], const unsigned char data[], unsigned long len);
|
||||
|
||||
#ifndef SHA_64BIT
|
||||
|
||||
typedef struct
|
||||
{ union
|
||||
{ sha256_ctx ctx256[1];
|
||||
} uu[1];
|
||||
uint32_t sha2_len;
|
||||
} sha2_ctx;
|
||||
|
||||
#else
|
||||
|
||||
#define SHA384_DIGEST_SIZE 48
|
||||
#define SHA384_BLOCK_SIZE 128
|
||||
|
||||
#define SHA512_DIGEST_SIZE 64
|
||||
#define SHA512_BLOCK_SIZE 128
|
||||
|
||||
#define SHA512_128_DIGEST_SIZE 16
|
||||
#define SHA512_128_BLOCK_SIZE SHA512_BLOCK_SIZE
|
||||
|
||||
#define SHA512_192_DIGEST_SIZE 24
|
||||
#define SHA512_192_BLOCK_SIZE SHA512_BLOCK_SIZE
|
||||
|
||||
#define SHA512_224_DIGEST_SIZE 28
|
||||
#define SHA512_224_BLOCK_SIZE SHA512_BLOCK_SIZE
|
||||
|
||||
#define SHA512_256_DIGEST_SIZE 32
|
||||
#define SHA512_256_BLOCK_SIZE SHA512_BLOCK_SIZE
|
||||
|
||||
/* type to hold the SHA384 (and SHA512) context */
|
||||
|
||||
typedef struct
|
||||
{ uint64_t count[2];
|
||||
uint64_t hash[SHA512_DIGEST_SIZE >> 3];
|
||||
uint64_t wbuf[SHA512_BLOCK_SIZE >> 3];
|
||||
} sha512_ctx;
|
||||
|
||||
typedef sha512_ctx sha384_ctx;
|
||||
|
||||
typedef struct
|
||||
{ union
|
||||
{ sha256_ctx ctx256[1];
|
||||
sha512_ctx ctx512[1];
|
||||
} uu[1];
|
||||
uint32_t sha2_len;
|
||||
} sha2_ctx;
|
||||
|
||||
VOID_RETURN sha512_compile(sha512_ctx ctx[1]);
|
||||
|
||||
VOID_RETURN sha384_begin(sha384_ctx ctx[1]);
|
||||
#define sha384_hash sha512_hash
|
||||
VOID_RETURN sha384_end(unsigned char hval[], sha384_ctx ctx[1]);
|
||||
VOID_RETURN sha384(unsigned char hval[], const unsigned char data[], unsigned long len);
|
||||
|
||||
VOID_RETURN sha512_begin(sha512_ctx ctx[1]);
|
||||
VOID_RETURN sha512_hash(const unsigned char data[], unsigned long len, sha512_ctx ctx[1]);
|
||||
VOID_RETURN sha512_end(unsigned char hval[], sha512_ctx ctx[1]);
|
||||
VOID_RETURN sha512(unsigned char hval[], const unsigned char data[], unsigned long len);
|
||||
|
||||
VOID_RETURN sha512_256_begin(sha512_ctx ctx[1]);
|
||||
#define sha512_256_hash sha512_hash
|
||||
VOID_RETURN sha512_256_end(unsigned char hval[], sha512_ctx ctx[1]);
|
||||
VOID_RETURN sha512_256(unsigned char hval[], const unsigned char data[], unsigned long len);
|
||||
|
||||
VOID_RETURN sha512_224_begin(sha512_ctx ctx[1]);
|
||||
#define sha512_224_hash sha512_hash
|
||||
VOID_RETURN sha512_224_end(unsigned char hval[], sha512_ctx ctx[1]);
|
||||
VOID_RETURN sha512_224(unsigned char hval[], const unsigned char data[], unsigned long len);
|
||||
|
||||
VOID_RETURN sha512_192_begin(sha512_ctx ctx[1]);
|
||||
#define sha512_192_hash sha512_hash
|
||||
VOID_RETURN sha512_192_end(unsigned char hval[], sha512_ctx ctx[1]);
|
||||
VOID_RETURN sha512_192(unsigned char hval[], const unsigned char data[], unsigned long len);
|
||||
|
||||
VOID_RETURN sha512_128_begin(sha512_ctx ctx[1]);
|
||||
#define sha512_128_hash sha512_hash
|
||||
VOID_RETURN sha512_128_end(unsigned char hval[], sha512_ctx ctx[1]);
|
||||
VOID_RETURN sha512_128(unsigned char hval[], const unsigned char data[], unsigned long len);
|
||||
|
||||
INT_RETURN sha2_begin(unsigned long size, sha2_ctx ctx[1]);
|
||||
VOID_RETURN sha2_hash(const unsigned char data[], unsigned long len, sha2_ctx ctx[1]);
|
||||
VOID_RETURN sha2_end(unsigned char hval[], sha2_ctx ctx[1]);
|
||||
INT_RETURN sha2(unsigned char hval[], unsigned long size, const unsigned char data[], unsigned long len);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+3
-1
@@ -70,7 +70,7 @@ void BZ2_bz__AssertH__fail ( int errcode )
|
||||
" points in compression, you may have a flaky memory system.\n"
|
||||
" Try a memory-test program. I have used Memtest86\n"
|
||||
" (www.memtest86.com). At the time of writing it is free (GPLd).\n"
|
||||
" Memtest86 tests memory much more thorougly than your BIOSs\n"
|
||||
" Memtest86 tests memory much more thoroughly than your BIOSs\n"
|
||||
" power-on test, and may find failures that the BIOS doesn't.\n"
|
||||
"\n"
|
||||
"* If the error can be repeatably reproduced, this is a bug in\n"
|
||||
@@ -102,6 +102,7 @@ static
|
||||
void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
|
||||
{
|
||||
void* v = malloc ( items * size );
|
||||
(void)opaque;
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -109,6 +110,7 @@ static
|
||||
void default_bzfree ( void* opaque, void* addr )
|
||||
{
|
||||
if (addr != NULL) free ( addr );
|
||||
(void)opaque;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -71,7 +71,7 @@ typedef
|
||||
#endif
|
||||
|
||||
#ifndef BZ_NO_STDIO
|
||||
/* Need a definitition for FILE */
|
||||
/* Need a definition for FILE */
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
|
||||
@@ -158,6 +158,7 @@ void generateMTFValues ( EState* s )
|
||||
|
||||
wr = 0;
|
||||
zPend = 0;
|
||||
yy[0] = 0;
|
||||
for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
|
||||
|
||||
for (i = 0; i < s->nblock; i++) {
|
||||
@@ -579,7 +580,7 @@ void sendMTFValues ( EState* s )
|
||||
# undef BZ_ITAH
|
||||
|
||||
} else {
|
||||
/*--- slow version which correctly handles all situations ---*/
|
||||
/*--- slow version which correctly handles all situations ---*/
|
||||
for (i = gs; i <= ge; i++) {
|
||||
bsW ( s,
|
||||
s->len [s->selector[selCtr]] [mtfv[i]],
|
||||
@@ -595,6 +596,8 @@ void sendMTFValues ( EState* s )
|
||||
|
||||
if (s->verbosity >= 3)
|
||||
VPrintf1( "codes %d\n", s->numZ-nBytes );
|
||||
|
||||
(void)nBytes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -287,7 +287,7 @@ Int32 BZ2_decompress ( DState* s )
|
||||
GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
|
||||
if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
|
||||
GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
|
||||
if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
|
||||
if (nSelectors < 1 || nSelectors > BZ_MAX_SELECTORS) RETURN(BZ_DATA_ERROR);
|
||||
for (i = 0; i < nSelectors; i++) {
|
||||
j = 0;
|
||||
while (True) {
|
||||
|
||||
+3
-1
@@ -115,7 +115,9 @@ void BZ2_hbMakeCodeLengths ( UChar *len,
|
||||
for (i = 1; i <= alphaSize; i++) {
|
||||
j = 0;
|
||||
k = i;
|
||||
while (parent[k] >= 0) { k = parent[k]; j++; }
|
||||
while (k < (BZ_MAX_ALPHA_SIZE * 2) && parent[k] >= 0) {
|
||||
k = parent[k]; j++;
|
||||
}
|
||||
len[i-1] = j;
|
||||
if (j > maxLen) tooLong = True;
|
||||
}
|
||||
|
||||
@@ -7,16 +7,16 @@
|
||||
* format and raw (no headers) streams are supported. Multiple compression
|
||||
* algorithms (filters) are supported. Currently LZMA2 is the primary filter.
|
||||
*
|
||||
* liblzma is part of XZ Utils <http://tukaani.org/xz/>. XZ Utils includes
|
||||
* liblzma is part of XZ Utils <https://tukaani.org/xz/>. XZ Utils includes
|
||||
* a gzip-like command line tool named xz and some other tools. XZ Utils
|
||||
* is developed and maintained by Lasse Collin.
|
||||
*
|
||||
* Major parts of liblzma are based on Igor Pavlov's public domain LZMA SDK
|
||||
* <http://7-zip.org/sdk.html>.
|
||||
* <https://www.7-zip.org/sdk.html>.
|
||||
*
|
||||
* The SHA-256 implementation is based on the public domain code found from
|
||||
* 7-Zip <http://7-zip.org/>, which has a modified version of the public
|
||||
* domain SHA-256 code found from Crypto++ <http://www.cryptopp.com/>.
|
||||
* 7-Zip <https://www.7-zip.org/>, which has a modified version of the public
|
||||
* domain SHA-256 code found from Crypto++ <https://www.cryptopp.com/>.
|
||||
* The SHA-256 code in Crypto++ was written by Kevin Springle and Wei Dai.
|
||||
*/
|
||||
|
||||
|
||||
@@ -447,7 +447,7 @@ typedef struct lzma_internal_s lzma_internal;
|
||||
*
|
||||
* The lzma_stream structure is used for
|
||||
* - passing pointers to input and output buffers to liblzma;
|
||||
* - defining custom memory hander functions; and
|
||||
* - defining custom memory handler functions; and
|
||||
* - holding a pointer to coder-specific internal data structures.
|
||||
*
|
||||
* Typical usage:
|
||||
|
||||
@@ -301,7 +301,7 @@ typedef struct {
|
||||
* (2^ pb =2^2=4), which is often a good choice when there's
|
||||
* no better guess.
|
||||
*
|
||||
* When the aligment is known, setting pb accordingly may reduce
|
||||
* When the alignment is known, setting pb accordingly may reduce
|
||||
* the file size a little. E.g. with text files having one-byte
|
||||
* alignment (US-ASCII, ISO-8859-*, UTF-8), setting pb=0 can
|
||||
* improve compression slightly. For UTF-16 text, pb=1 is a good
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
*
|
||||
* Valid VLI values are in the range [0, LZMA_VLI_MAX]. Unknown value is
|
||||
* indicated with LZMA_VLI_UNKNOWN, which is the maximum value of the
|
||||
* underlaying integer type.
|
||||
* underlying integer type.
|
||||
*
|
||||
* lzma_vli will be uint64_t for the foreseeable future. If a bigger size
|
||||
* is needed in the future, it is guaranteed that 2 * LZMA_VLI_MAX will
|
||||
|
||||
@@ -83,6 +83,8 @@ lzma_check_size(lzma_check type)
|
||||
extern void
|
||||
lzma_check_init(lzma_check_state *check, lzma_check type)
|
||||
{
|
||||
(void)check;
|
||||
|
||||
switch (type) {
|
||||
case LZMA_CHECK_NONE:
|
||||
break;
|
||||
@@ -117,6 +119,10 @@ extern void
|
||||
lzma_check_update(lzma_check_state *check, lzma_check type,
|
||||
const uint8_t *buf, size_t size)
|
||||
{
|
||||
(void)check;
|
||||
(void)buf;
|
||||
(void)size;
|
||||
|
||||
switch (type) {
|
||||
#ifdef HAVE_CHECK_CRC32
|
||||
case LZMA_CHECK_CRC32:
|
||||
@@ -147,6 +153,8 @@ lzma_check_update(lzma_check_state *check, lzma_check type,
|
||||
extern void
|
||||
lzma_check_finish(lzma_check_state *check, lzma_check type)
|
||||
{
|
||||
(void)check;
|
||||
|
||||
switch (type) {
|
||||
#ifdef HAVE_CHECK_CRC32
|
||||
case LZMA_CHECK_CRC32:
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
///
|
||||
/// Calculate the CRC32 using the slice-by-eight algorithm.
|
||||
/// It is explained in this document:
|
||||
/// http://www.intel.com/technology/comms/perfnet/download/CRC_generators.pdf
|
||||
/// https://www.intel.com/technology/comms/perfnet/download/CRC_generators.pdf
|
||||
/// The code in this file is not the same as in Intel's paper, but
|
||||
/// the basic principle is identical.
|
||||
//
|
||||
@@ -20,7 +20,7 @@
|
||||
#include "crc_macros.h"
|
||||
|
||||
|
||||
// If you make any changes, do some bench marking! Seemingly unrelated
|
||||
// If you make any changes, do some benchmarking! Seemingly unrelated
|
||||
// changes can very easily ruin the performance (and very probably is
|
||||
// very compiler dependent).
|
||||
extern LZMA_API(uint32_t)
|
||||
|
||||
@@ -163,7 +163,8 @@ static const lzma_filter_encoder encoders[] = {
|
||||
static const lzma_filter_encoder *
|
||||
encoder_find(lzma_vli id)
|
||||
{
|
||||
for (size_t i = 0; i < ARRAY_SIZE(encoders); ++i)
|
||||
size_t i = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(encoders); ++i)
|
||||
if (encoders[i].id == id)
|
||||
return encoders + i;
|
||||
|
||||
@@ -182,8 +183,9 @@ extern uint64_t
|
||||
lzma_mt_block_size(const lzma_filter *filters)
|
||||
{
|
||||
uint64_t max = 0;
|
||||
size_t i = 0;
|
||||
|
||||
for (size_t i = 0; filters[i].id != LZMA_VLI_UNKNOWN; ++i) {
|
||||
for (i = 0; filters[i].id != LZMA_VLI_UNKNOWN; ++i) {
|
||||
const lzma_filter_encoder *const fe
|
||||
= encoder_find(filters[i].id);
|
||||
if (fe->block_size != NULL) {
|
||||
|
||||
@@ -16,8 +16,12 @@
|
||||
#include "common.h"
|
||||
|
||||
#ifdef HAVE_IMMINTRIN_H
|
||||
#if (defined(__GNUC__) && defined(__SSE2_MATH__)) || \
|
||||
(defined(__INTEL_COMPILER) && defined(__SSE2__)) || \
|
||||
(defined(_MSC_VER) && defined(_M_IX86_FP) && _M_IX86_FP >= 2)
|
||||
# include <immintrin.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/// Find out how many equal bytes the two buffers have.
|
||||
@@ -64,7 +68,8 @@ lzma_memcmplen(const uint8_t *buf1, const uint8_t *buf2,
|
||||
const uint64_t x = *(const uint64_t *)(buf1 + len)
|
||||
- *(const uint64_t *)(buf2 + len);
|
||||
if (x != 0) {
|
||||
# if defined(_M_X64) // MSVC or Intel C compiler on Windows
|
||||
# if defined(_M_X64) && defined(_WIN32) \
|
||||
&& (defined(_MSC_VER) || defined(__INTEL_COMPILER)) // MSVC or Intel C compiler on Windows
|
||||
unsigned long tmp;
|
||||
_BitScanForward64(&tmp, x);
|
||||
len += (uint32_t)tmp >> 3;
|
||||
@@ -102,7 +107,7 @@ lzma_memcmplen(const uint8_t *buf1, const uint8_t *buf2,
|
||||
# if defined(__INTEL_COMPILER)
|
||||
len += _bit_scan_forward(x);
|
||||
# elif defined(_MSC_VER)
|
||||
unsigned long tmp;
|
||||
unsigned long tmp = 0;
|
||||
_BitScanForward(&tmp, x);
|
||||
len += tmp;
|
||||
# else
|
||||
|
||||
@@ -382,7 +382,7 @@ bsr32(uint32_t n)
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
// MSVC isn't supported by tuklib, but since this code exists,
|
||||
// it doesn't hurt to have it here anyway.
|
||||
uint32_t i;
|
||||
uint32_t i = 0;
|
||||
_BitScanReverse(&i, n);
|
||||
return i;
|
||||
|
||||
@@ -427,14 +427,14 @@ clz32(uint32_t n)
|
||||
return __builtin_clz(n);
|
||||
|
||||
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||
uint32_t i;
|
||||
uint32_t i = 0;
|
||||
__asm__("bsrl %1, %0\n\t"
|
||||
"xorl $31, %0"
|
||||
: "=r" (i) : "rm" (n));
|
||||
return i;
|
||||
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
uint32_t i;
|
||||
uint32_t i = 0;
|
||||
_BitScanReverse(&i, n);
|
||||
return i ^ 31U;
|
||||
|
||||
@@ -479,12 +479,12 @@ ctz32(uint32_t n)
|
||||
return __builtin_ctz(n);
|
||||
|
||||
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||
uint32_t i;
|
||||
uint32_t i = 0;
|
||||
__asm__("bsfl %1, %0" : "=r" (i) : "rm" (n));
|
||||
return i;
|
||||
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
uint32_t i;
|
||||
uint32_t i = 0;
|
||||
_BitScanForward(&i, n);
|
||||
return i;
|
||||
|
||||
|
||||
+24
-24
@@ -5,7 +5,7 @@
|
||||
/* #undef AC_APPLE_UNIVERSAL_BUILD */
|
||||
|
||||
/* How many MiB of RAM to assume if the real amount cannot be determined. */
|
||||
#define ASSUME_RAM 128
|
||||
/* #undef ASSUME_RAM 128 */
|
||||
|
||||
/* Define to 1 if translation of program messages to the user's native
|
||||
language is requested. */
|
||||
@@ -47,7 +47,7 @@
|
||||
/* #undef HAVE_CHECK_SHA256 */
|
||||
|
||||
/* Define to 1 if you have the `clock_gettime' function. */
|
||||
#define HAVE_CLOCK_GETTIME 1
|
||||
/* #undef HAVE_CLOCK_GETTIME */
|
||||
|
||||
/* Define to 1 if you have the <CommonCrypto/CommonDigest.h> header file. */
|
||||
/* #undef HAVE_COMMONCRYPTO_COMMONDIGEST_H */
|
||||
@@ -58,11 +58,11 @@
|
||||
|
||||
/* Define to 1 if you have the declaration of `CLOCK_MONOTONIC', and to 0 if
|
||||
you don't. */
|
||||
#define HAVE_DECL_CLOCK_MONOTONIC 1
|
||||
/* #undef HAVE_DECL_CLOCK_MONOTONIC */
|
||||
|
||||
/* Define to 1 if you have the declaration of `program_invocation_name', and
|
||||
to 0 if you don't. */
|
||||
#define HAVE_DECL_PROGRAM_INVOCATION_NAME 0
|
||||
/* #undef HAVE_DECL_PROGRAM_INVOCATION_NAME */
|
||||
|
||||
/* Define to 1 if arm decoder is enabled. */
|
||||
/* #undef HAVE_DECODER_ARM */
|
||||
@@ -122,7 +122,7 @@
|
||||
/* #undef HAVE_ENCODER_X86 */
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
/* #undef HAVE_FCNTL_H 1 */
|
||||
|
||||
/* Define to 1 if you have the `futimens' function. */
|
||||
/* #undef HAVE_FUTIMENS */
|
||||
@@ -134,10 +134,10 @@
|
||||
/* #undef HAVE_FUTIMESAT */
|
||||
|
||||
/* Define to 1 if you have the <getopt.h> header file. */
|
||||
#define HAVE_GETOPT_H 1
|
||||
/* #undef HAVE_GETOPT_H */
|
||||
|
||||
/* Define to 1 if you have the `getopt_long' function. */
|
||||
#define HAVE_GETOPT_LONG 1
|
||||
/* #undef HAVE_GETOPT_LONG */
|
||||
|
||||
/* Define if the GNU gettext() function is already present or preinstalled. */
|
||||
/* #undef HAVE_GETTEXT */
|
||||
@@ -146,19 +146,19 @@
|
||||
/* #undef HAVE_ICONV */
|
||||
|
||||
/* Define to 1 if you have the <immintrin.h> header file. */
|
||||
#define HAVE_IMMINTRIN_H 1
|
||||
/* #undef HAVE_IMMINTRIN_H */
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
/* #undef HAVE_INTTYPES_H */
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#define HAVE_LIMITS_H 1
|
||||
/* #undef HAVE_LIMITS_H */
|
||||
|
||||
/* Define to 1 if mbrtowc and mbstate_t are properly declared. */
|
||||
#define HAVE_MBRTOWC 1
|
||||
/* #undef HAVE_MBRTOWC 1 */
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
/* #undef HAVE_MEMORY_H */
|
||||
|
||||
/* Define to 1 to enable bt2 match finder. */
|
||||
#define HAVE_MF_BT2 1
|
||||
@@ -215,10 +215,10 @@
|
||||
/* #undef HAVE_SMALL */
|
||||
|
||||
/* Define to 1 if stdbool.h conforms to C99. */
|
||||
#define HAVE_STDBOOL_H 1
|
||||
/* #undef HAVE_STDBOOL_H */
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
/* #undef HAVE_STDINT_H */
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
@@ -227,7 +227,7 @@
|
||||
/* #undef HAVE_STRINGS_H */
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
/* #undef HAVE_STRING_H */
|
||||
|
||||
/* Define to 1 if `st_atimensec' is a member of `struct stat'. */
|
||||
/* #undef HAVE_STRUCT_STAT_ST_ATIMENSEC */
|
||||
@@ -251,25 +251,25 @@
|
||||
/* #undef HAVE_SYS_ENDIAN_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
/* #undef HAVE_SYS_PARAM_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
/* #undef HAVE_SYS_STAT_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
/* #undef HAVE_SYS_TIME_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
/* #undef HAVE_SYS_TYPES_H */
|
||||
|
||||
/* Define to 1 if the system has the type `uintptr_t'. */
|
||||
#define HAVE_UINTPTR_T 1
|
||||
/* #undef HAVE_UINTPTR_T */
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
/* #undef HAVE_UNISTD_H */
|
||||
|
||||
/* Define to 1 if you have the `utime' function. */
|
||||
#define HAVE_UTIME 1
|
||||
/* #undef HAVE_UTIME */
|
||||
|
||||
/* Define to 1 if you have the `utimes' function. */
|
||||
/* #undef HAVE_UTIMES */
|
||||
@@ -324,7 +324,7 @@
|
||||
#define PACKAGE_TARNAME "xz"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL "http://tukaani.org/xz/"
|
||||
#define PACKAGE_URL "https://tukaani.org/xz/"
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "5.2.3"
|
||||
@@ -434,7 +434,7 @@
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
/* #undef _FILE_OFFSET_BITS 64 */
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
/* #undef _LARGE_FILES */
|
||||
|
||||
@@ -241,7 +241,7 @@ lzma_lz_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
if (lz_options.dict_size < 4096)
|
||||
lz_options.dict_size = 4096;
|
||||
|
||||
// Make dictionary size a multipe of 16. Some LZ-based decoders like
|
||||
// Make dictionary size a multiple of 16. Some LZ-based decoders like
|
||||
// LZMA use the lowest bits lzma_dict.pos to know the alignment of the
|
||||
// data. Aligned buffer is also good when memcpying from the
|
||||
// dictionary to the output buffer, since applications are
|
||||
|
||||
@@ -33,8 +33,9 @@ lzma_mf_find(lzma_mf *mf, uint32_t *count_ptr, lzma_match *matches)
|
||||
|
||||
if (count > 0) {
|
||||
#ifndef NDEBUG
|
||||
uint32_t i = 0;
|
||||
// Validate the matches.
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
for (i = 0; i < count; ++i) {
|
||||
assert(matches[i].len <= mf->nice_len);
|
||||
assert(matches[i].dist < mf->read_pos);
|
||||
assert(memcmp(mf_ptr(mf) - 1,
|
||||
@@ -108,14 +109,14 @@ static void
|
||||
normalize(lzma_mf *mf)
|
||||
{
|
||||
assert(mf->read_pos + mf->offset == MUST_NORMALIZE_POS);
|
||||
|
||||
uint32_t i = 0;
|
||||
// In future we may not want to touch the lowest bits, because there
|
||||
// may be match finders that use larger resolution than one byte.
|
||||
const uint32_t subvalue
|
||||
= (MUST_NORMALIZE_POS - mf->cyclic_size);
|
||||
// & (~(UINT32_C(1) << 10) - 1);
|
||||
|
||||
for (uint32_t i = 0; i < mf->hash_count; ++i) {
|
||||
for (i = 0; i < mf->hash_count; ++i) {
|
||||
// If the distance is greater than the dictionary size,
|
||||
// we can simply mark the hash element as empty.
|
||||
if (mf->hash[i] <= subvalue)
|
||||
@@ -124,7 +125,7 @@ normalize(lzma_mf *mf)
|
||||
mf->hash[i] -= subvalue;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < mf->sons_count; ++i) {
|
||||
for (i = 0; i < mf->sons_count; ++i) {
|
||||
// Do the same for mf->son.
|
||||
//
|
||||
// NOTE: There may be uninitialized elements in mf->son.
|
||||
|
||||
@@ -14,9 +14,7 @@
|
||||
#ifndef LZMA_RANGE_COMMON_H
|
||||
#define LZMA_RANGE_COMMON_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "common.h"
|
||||
#endif
|
||||
#include "common.h"
|
||||
|
||||
|
||||
///////////////
|
||||
|
||||
+210
@@ -0,0 +1,210 @@
|
||||
/* minigzip.c
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
See the accompanying LICENSE file for the full text of the license.
|
||||
*/
|
||||
|
||||
|
||||
#include "mz.h"
|
||||
#include "mz_os.h"
|
||||
#include "mz_strm.h"
|
||||
#include "mz_strm_os.h"
|
||||
#include "mz_strm_zlib.h"
|
||||
|
||||
#include <stdio.h> /* printf */
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#define MZ_GZIP_COMPRESS (1)
|
||||
#define MZ_GZIP_DECOMPRESS (2)
|
||||
|
||||
int32_t minigzip_banner(void);
|
||||
int32_t minigzip_help(void);
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t minigzip_banner(void)
|
||||
{
|
||||
printf("Minigzip %s - https://github.com/nmoinvaz/minizip\n", MZ_VERSION);
|
||||
printf("---------------------------------------------------\n");
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t minigzip_help(void)
|
||||
{
|
||||
printf("Usage: minigzip [-x] [-d] [-0 to -9] [files]\n\n" \
|
||||
" -x Extract file\n" \
|
||||
" -d Destination directory\n" \
|
||||
" -0 Store only\n" \
|
||||
" -1 Compress faster\n" \
|
||||
" -9 Compress better\n\n");
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t minigzip_copy(const char *path, const char *destination, int16_t operation, int16_t level)
|
||||
{
|
||||
void *target_stream = NULL;
|
||||
void *source_stream = NULL;
|
||||
void *zlib_stream = NULL;
|
||||
const char *filename = NULL;
|
||||
char target_path[1024];
|
||||
int32_t err = 0;
|
||||
|
||||
|
||||
memset(target_path, 0, sizeof(target_path));
|
||||
|
||||
if (destination != NULL)
|
||||
{
|
||||
if (mz_os_file_exists(destination) != MZ_OK)
|
||||
mz_dir_make(destination);
|
||||
}
|
||||
|
||||
if (operation == MZ_GZIP_COMPRESS)
|
||||
{
|
||||
mz_path_combine(target_path, path, sizeof(target_path));
|
||||
strncat(target_path, ".gz", sizeof(target_path) - strlen(target_path) - 1);
|
||||
printf("Compressing to %s\n", target_path);
|
||||
}
|
||||
else if (operation == MZ_GZIP_DECOMPRESS)
|
||||
{
|
||||
if (destination != NULL)
|
||||
mz_path_combine(target_path, destination, sizeof(target_path));
|
||||
|
||||
if (mz_path_get_filename(path, &filename) != MZ_OK)
|
||||
filename = path;
|
||||
|
||||
mz_path_combine(target_path, filename, sizeof(target_path));
|
||||
mz_path_remove_extension(target_path);
|
||||
printf("Decompressing to %s\n", target_path);
|
||||
}
|
||||
|
||||
mz_stream_zlib_create(&zlib_stream);
|
||||
mz_stream_zlib_set_prop_int64(zlib_stream, MZ_STREAM_PROP_COMPRESS_WINDOW, 15 + 16);
|
||||
|
||||
mz_stream_os_create(&source_stream);
|
||||
err = mz_stream_os_open(source_stream, path, MZ_OPEN_MODE_READ);
|
||||
|
||||
if (err == MZ_OK)
|
||||
{
|
||||
mz_stream_os_create(&target_stream);
|
||||
err = mz_stream_os_open(target_stream, target_path, MZ_OPEN_MODE_CREATE | MZ_OPEN_MODE_WRITE);
|
||||
|
||||
if (err == MZ_OK)
|
||||
{
|
||||
if (operation == MZ_GZIP_COMPRESS)
|
||||
{
|
||||
mz_stream_zlib_set_prop_int64(zlib_stream, MZ_STREAM_PROP_COMPRESS_LEVEL, level);
|
||||
mz_stream_zlib_open(zlib_stream, target_path, MZ_OPEN_MODE_WRITE);
|
||||
mz_stream_set_base(zlib_stream, target_stream);
|
||||
err = mz_stream_copy_to_end(zlib_stream, source_stream);
|
||||
}
|
||||
else if (operation == MZ_GZIP_DECOMPRESS)
|
||||
{
|
||||
mz_stream_zlib_open(zlib_stream, path, MZ_OPEN_MODE_READ);
|
||||
mz_stream_set_base(zlib_stream, source_stream);
|
||||
err = mz_stream_copy_to_end(target_stream, zlib_stream);
|
||||
}
|
||||
|
||||
if (err != MZ_OK)
|
||||
printf("Error %d in zlib stream (%d)\n", err, mz_stream_zlib_error(zlib_stream));
|
||||
else
|
||||
printf("Operation completed successfully\n");
|
||||
|
||||
mz_stream_zlib_close(zlib_stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Error %d opening target path %s\n", err, target_path);
|
||||
}
|
||||
|
||||
mz_stream_os_close(target_stream);
|
||||
mz_stream_os_delete(&target_stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Error %d opening source path %s\n", err, path);
|
||||
}
|
||||
|
||||
mz_stream_os_close(source_stream);
|
||||
mz_stream_os_delete(&source_stream);
|
||||
|
||||
mz_stream_zlib_delete(&zlib_stream);
|
||||
return err;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#if !defined(MZ_ZIP_NO_MAIN)
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
int16_t operation_level = MZ_COMPRESS_LEVEL_DEFAULT;
|
||||
int32_t path_arg = 0;
|
||||
int32_t err = 0;
|
||||
int32_t i = 0;
|
||||
uint8_t operation = MZ_GZIP_COMPRESS;
|
||||
const char *path = NULL;
|
||||
const char *destination = NULL;
|
||||
|
||||
|
||||
minigzip_banner();
|
||||
if (argc == 1)
|
||||
{
|
||||
minigzip_help();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Parse command line options */
|
||||
for (i = 1; i < argc; i += 1)
|
||||
{
|
||||
printf("%s ", argv[i]);
|
||||
if (argv[i][0] == '-')
|
||||
{
|
||||
char c = argv[i][1];
|
||||
if ((c == 'x') || (c == 'X'))
|
||||
operation = MZ_GZIP_DECOMPRESS;
|
||||
else if ((c >= '0') && (c <= '9'))
|
||||
operation_level = (c - '0');
|
||||
else if (((c == 'd') || (c == 'D')) && (i + 1 < argc))
|
||||
{
|
||||
destination = argv[i + 1];
|
||||
printf("%s ", argv[i + 1]);
|
||||
i += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
err = MZ_SUPPORT_ERROR;
|
||||
}
|
||||
}
|
||||
else if (path_arg == 0)
|
||||
{
|
||||
path_arg = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
if (err == MZ_SUPPORT_ERROR)
|
||||
{
|
||||
printf("Feature not supported\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
if (path_arg == 0)
|
||||
{
|
||||
minigzip_help();
|
||||
return 0;
|
||||
}
|
||||
|
||||
path = argv[path_arg];
|
||||
err = minigzip_copy(path, destination, operation, operation_level);
|
||||
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
@@ -1,8 +1,8 @@
|
||||
/* mz.h -- Errors codes, zip flags and magic
|
||||
Version 2.3.6, July 11, 2018
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2018 Nathan Moinvaziri
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
@@ -12,22 +12,22 @@
|
||||
#ifndef MZ_H
|
||||
#define MZ_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
// MZ_VERSION
|
||||
#define MZ_VERSION ("2.3.6")
|
||||
/* MZ_VERSION */
|
||||
#define MZ_VERSION ("2.9.2")
|
||||
|
||||
/* MZ_ERROR */
|
||||
#define MZ_OK (0) /* zlib */
|
||||
#define MZ_STREAM_ERROR (-1) /* zlib */
|
||||
#define MZ_DATA_ERROR (-3) /* zlib */
|
||||
#define MZ_MEM_ERROR (-4) /* zlib */
|
||||
#define MZ_BUF_ERROR (-5) /* zlib */
|
||||
#define MZ_VERSION_ERROR (-6) /* zlib */
|
||||
|
||||
// MZ_ERROR
|
||||
#define MZ_OK (0)
|
||||
#define MZ_STREAM_ERROR (-1)
|
||||
#define MZ_DATA_ERROR (-3)
|
||||
#define MZ_MEM_ERROR (-4)
|
||||
#define MZ_END_OF_LIST (-100)
|
||||
#define MZ_END_OF_STREAM (-101)
|
||||
|
||||
#define MZ_PARAM_ERROR (-102)
|
||||
#define MZ_FORMAT_ERROR (-103)
|
||||
#define MZ_INTERNAL_ERROR (-104)
|
||||
@@ -36,8 +36,17 @@ extern "C" {
|
||||
#define MZ_EXIST_ERROR (-107)
|
||||
#define MZ_PASSWORD_ERROR (-108)
|
||||
#define MZ_SUPPORT_ERROR (-109)
|
||||
#define MZ_HASH_ERROR (-110)
|
||||
#define MZ_OPEN_ERROR (-111)
|
||||
#define MZ_CLOSE_ERROR (-112)
|
||||
#define MZ_SEEK_ERROR (-113)
|
||||
#define MZ_TELL_ERROR (-114)
|
||||
#define MZ_READ_ERROR (-115)
|
||||
#define MZ_WRITE_ERROR (-116)
|
||||
#define MZ_SIGN_ERROR (-117)
|
||||
#define MZ_SYMLINK_ERROR (-118)
|
||||
|
||||
// MZ_OPEN
|
||||
/* MZ_OPEN */
|
||||
#define MZ_OPEN_MODE_READ (0x01)
|
||||
#define MZ_OPEN_MODE_WRITE (0x02)
|
||||
#define MZ_OPEN_MODE_READWRITE (MZ_OPEN_MODE_READ | MZ_OPEN_MODE_WRITE)
|
||||
@@ -45,13 +54,13 @@ extern "C" {
|
||||
#define MZ_OPEN_MODE_CREATE (0x08)
|
||||
#define MZ_OPEN_MODE_EXISTING (0x10)
|
||||
|
||||
// MZ_SEEK
|
||||
/* MZ_SEEK */
|
||||
#define MZ_SEEK_SET (0)
|
||||
#define MZ_SEEK_CUR (1)
|
||||
#define MZ_SEEK_END (2)
|
||||
|
||||
// MZ_COMPRESS
|
||||
#define MZ_COMPRESS_METHOD_RAW (0)
|
||||
/* MZ_COMPRESS */
|
||||
#define MZ_COMPRESS_METHOD_STORE (0)
|
||||
#define MZ_COMPRESS_METHOD_DEFLATE (8)
|
||||
#define MZ_COMPRESS_METHOD_BZIP2 (12)
|
||||
#define MZ_COMPRESS_METHOD_LZMA (14)
|
||||
@@ -62,7 +71,7 @@ extern "C" {
|
||||
#define MZ_COMPRESS_LEVEL_NORMAL (6)
|
||||
#define MZ_COMPRESS_LEVEL_BEST (9)
|
||||
|
||||
// MZ_ZIP
|
||||
/* MZ_ZIP_FLAG */
|
||||
#define MZ_ZIP_FLAG_ENCRYPTED (1 << 0)
|
||||
#define MZ_ZIP_FLAG_LZMA_EOS_MARKER (1 << 1)
|
||||
#define MZ_ZIP_FLAG_DEFLATE_MAX (1 << 1)
|
||||
@@ -71,25 +80,62 @@ extern "C" {
|
||||
#define MZ_ZIP_FLAG_DEFLATE_SUPER_FAST (MZ_ZIP_FLAG_DEFLATE_FAST | \
|
||||
MZ_ZIP_FLAG_DEFLATE_MAX)
|
||||
#define MZ_ZIP_FLAG_DATA_DESCRIPTOR (1 << 3)
|
||||
#define MZ_ZIP_FLAG_UTF8 (1 << 11)
|
||||
#define MZ_ZIP_FLAG_MASK_LOCAL_INFO (1 << 13)
|
||||
|
||||
// MZ_ZIP64
|
||||
/* MZ_ZIP_EXTENSION */
|
||||
#define MZ_ZIP_EXTENSION_ZIP64 (0x0001)
|
||||
#define MZ_ZIP_EXTENSION_NTFS (0x000a)
|
||||
#define MZ_ZIP_EXTENSION_AES (0x9901)
|
||||
#define MZ_ZIP_EXTENSION_UNIX1 (0x000d)
|
||||
#define MZ_ZIP_EXTENSION_SIGN (0x10c5)
|
||||
#define MZ_ZIP_EXTENSION_HASH (0x1a51)
|
||||
#define MZ_ZIP_EXTENSION_CDCD (0xcdcd)
|
||||
|
||||
/* MZ_ZIP64 */
|
||||
#define MZ_ZIP64_AUTO (0)
|
||||
#define MZ_ZIP64_FORCE (1)
|
||||
#define MZ_ZIP64_DISABLE (2)
|
||||
|
||||
// MZ_HOST_SYSTEM
|
||||
/* MZ_HOST_SYSTEM */
|
||||
#define MZ_HOST_SYSTEM(VERSION_MADEBY) ((uint8_t)(VERSION_MADEBY >> 8))
|
||||
#define MZ_HOST_SYSTEM_MSDOS (0)
|
||||
#define MZ_HOST_SYSTEM_UNIX (3)
|
||||
#define MZ_HOST_SYSTEM_WINDOWS_NTFS (10)
|
||||
#define MZ_HOST_SYSTEM_RISCOS (13)
|
||||
#define MZ_HOST_SYSTEM_OSX_DARWIN (19)
|
||||
|
||||
// MZ_AES
|
||||
/* MZ_PKCRYPT */
|
||||
#define MZ_PKCRYPT_HEADER_SIZE (12)
|
||||
|
||||
/* MZ_AES */
|
||||
#define MZ_AES_VERSION (1)
|
||||
#define MZ_AES_ENCRYPTION_MODE_128 (0x01)
|
||||
#define MZ_AES_ENCRYPTION_MODE_192 (0x02)
|
||||
#define MZ_AES_ENCRYPTION_MODE_256 (0x03)
|
||||
#define MZ_AES_KEY_LENGTH(MODE) (8 * (MODE & 3) + 8)
|
||||
#define MZ_AES_KEY_LENGTH_MAX (32)
|
||||
#define MZ_AES_BLOCK_SIZE (16)
|
||||
#define MZ_AES_HEADER_SIZE(MODE) ((4 * (MODE & 3) + 4) + 2)
|
||||
#define MZ_AES_FOOTER_SIZE (10)
|
||||
|
||||
// MZ_UTILITY
|
||||
/* MZ_HASH */
|
||||
#define MZ_HASH_MD5 (10)
|
||||
#define MZ_HASH_MD5_SIZE (16)
|
||||
#define MZ_HASH_SHA1 (20)
|
||||
#define MZ_HASH_SHA1_SIZE (20)
|
||||
#define MZ_HASH_SHA256 (23)
|
||||
#define MZ_HASH_SHA256_SIZE (32)
|
||||
#define MZ_HASH_MAX_SIZE (256)
|
||||
|
||||
/* MZ_ENCODING */
|
||||
#define MZ_ENCODING_CODEPAGE_437 (437)
|
||||
#define MZ_ENCODING_CODEPAGE_932 (932)
|
||||
#define MZ_ENCODING_CODEPAGE_936 (936)
|
||||
#define MZ_ENCODING_CODEPAGE_950 (950)
|
||||
#define MZ_ENCODING_UTF8 (65001)
|
||||
|
||||
/* MZ_UTILITY */
|
||||
#define MZ_UNUSED(SYMBOL) ((void)SYMBOL)
|
||||
|
||||
#ifndef MZ_CUSTOM_ALLOC
|
||||
@@ -99,10 +145,108 @@ extern "C" {
|
||||
#define MZ_FREE(PTR) (free(PTR))
|
||||
#endif
|
||||
|
||||
#if defined(_WINDOWS) && defined(MZ_EXPORTS)
|
||||
#define MZ_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define MZ_EXPORT
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#include <stdlib.h> /* size_t, NULL, malloc */
|
||||
#include <time.h> /* time_t, time() */
|
||||
#include <string.h> /* memset, strncpy, strlen */
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
#ifndef __INT8_TYPE__
|
||||
typedef signed char int8_t;
|
||||
#endif
|
||||
#ifndef __INT16_TYPE__
|
||||
typedef short int16_t;
|
||||
#endif
|
||||
#ifndef __INT32_TYPE__
|
||||
typedef int int32_t;
|
||||
#endif
|
||||
#ifndef __INT64_TYPE__
|
||||
typedef long long int64_t;
|
||||
#endif
|
||||
#ifndef __UINT8_TYPE__
|
||||
typedef unsigned char uint8_t;
|
||||
#endif
|
||||
#ifndef __UINT16_TYPE__
|
||||
typedef unsigned short uint16_t;
|
||||
#endif
|
||||
#ifndef __UINT32_TYPE__
|
||||
typedef unsigned int uint32_t;
|
||||
#endif
|
||||
#ifndef __UINT64_TYPE__
|
||||
typedef unsigned long long uint64_t;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#ifndef PRId8
|
||||
# define PRId8 "hhd"
|
||||
#endif
|
||||
#ifndef PRId16
|
||||
# define PRId16 "hd"
|
||||
#endif
|
||||
#ifndef PRId32
|
||||
# define PRId32 "d"
|
||||
#endif
|
||||
#ifndef PRIu32
|
||||
# define PRIu32 "u"
|
||||
#endif
|
||||
#ifndef PRIx32
|
||||
# define PRIx32 "x"
|
||||
#endif
|
||||
#if ULONG_MAX == 4294967295UL
|
||||
# ifndef PRId64
|
||||
# define PRId64 "lld"
|
||||
# endif
|
||||
# ifndef PRIu64
|
||||
# define PRIu64 "llu"
|
||||
# endif
|
||||
# ifndef PRIx64
|
||||
# define PRIx64 "llx"
|
||||
# endif
|
||||
#else
|
||||
# ifndef PRId64
|
||||
# define PRId64 "ld"
|
||||
# endif
|
||||
# ifndef PRIu64
|
||||
# define PRIu64 "lu"
|
||||
# endif
|
||||
# ifndef PRIx64
|
||||
# define PRIx64 "lx"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef INT16_MAX
|
||||
# define INT16_MAX 32767
|
||||
#endif
|
||||
#ifndef INT32_MAX
|
||||
# define INT32_MAX 2147483647L
|
||||
#endif
|
||||
#ifndef INT64_MAX
|
||||
# define INT64_MAX 9223372036854775807LL
|
||||
#endif
|
||||
#ifndef UINT16_MAX
|
||||
# define UINT16_MAX 65535U
|
||||
#endif
|
||||
#ifndef UINT32_MAX
|
||||
# define UINT32_MAX 4294967295UL
|
||||
#endif
|
||||
#ifndef UINT64_MAX
|
||||
# define UINT64_MAX 18446744073709551615ULL
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#endif
|
||||
|
||||
+522
-127
File diff suppressed because it is too large
Load Diff
+182
-141
@@ -1,11 +1,11 @@
|
||||
/* mz_compat.h -- Backwards compatible interface for older versions
|
||||
Version 2.3.6, July 11, 2018
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2018 Nathan Moinvaziri
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
Copyright (C) 1998-2010 Gilles Vollant
|
||||
http://www.winimage.com/zLibDll/minizip.html
|
||||
https://www.winimage.com/zLibDll/minizip.html
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
See the accompanying LICENSE file for the full text of the license.
|
||||
@@ -14,44 +14,32 @@
|
||||
#ifndef MZ_COMPAT_H
|
||||
#define MZ_COMPAT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "mz.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
#include "zlib.h"
|
||||
#else
|
||||
#define ZEXPORT
|
||||
/***************************************************************************/
|
||||
|
||||
#if defined(HAVE_ZLIB) && defined(MAX_MEM_LEVEL)
|
||||
#ifndef DEF_MEM_LEVEL
|
||||
# if MAX_MEM_LEVEL >= 8
|
||||
# define DEF_MEM_LEVEL 8
|
||||
# else
|
||||
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
#ifndef MAX_WBITS
|
||||
#define MAX_WBITS (15)
|
||||
#endif
|
||||
#ifndef DEF_MEM_LEVEL
|
||||
#define DEF_MEM_LEVEL (8)
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#if defined(USE_FILE32API)
|
||||
# define MZ_USE_FILE32API
|
||||
# define fopen64 fopen
|
||||
# define ftello64 ftell
|
||||
# define fseeko64 fseek
|
||||
#else
|
||||
# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \
|
||||
defined(__OpenBSD__) || defined(__APPLE__) || defined(__ANDROID__)
|
||||
# define fopen64 fopen
|
||||
# define ftello64 ftello
|
||||
# define fseeko64 fseeko
|
||||
# endif
|
||||
# ifdef _MSC_VER
|
||||
# define fopen64 fopen
|
||||
# if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC)))
|
||||
# define ftello64 _ftelli64
|
||||
# define fseeko64 _fseeki64
|
||||
# else /* old MSC */
|
||||
# define ftello64 ftell
|
||||
# define fseeko64 fseek
|
||||
# endif
|
||||
# endif
|
||||
#ifndef ZEXPORT
|
||||
# define ZEXPORT MZ_EXPORT
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
@@ -78,12 +66,18 @@ typedef uint64_t ZPOS64_T;
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#if MZ_COMPAT_VERSION <= 110
|
||||
#define mz_dos_date dosDate
|
||||
#else
|
||||
#define mz_dos_date dos_date
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t dosDate;
|
||||
uint32_t mz_dos_date;
|
||||
struct tm tmz_date;
|
||||
uint16_t internal_fa; // internal file attributes 2 bytes
|
||||
uint32_t external_fa; // external file attributes 4 bytes
|
||||
uint16_t internal_fa; /* internal file attributes 2 bytes */
|
||||
uint32_t external_fa; /* external file attributes 4 bytes */
|
||||
} zip_fileinfo;
|
||||
|
||||
/***************************************************************************/
|
||||
@@ -97,55 +91,75 @@ typedef struct
|
||||
|
||||
#define Z_BZIP2ED (12)
|
||||
|
||||
#define APPEND_STATUS_CREATE (1)
|
||||
#define APPEND_STATUS_CREATEAFTER (2)
|
||||
#define APPEND_STATUS_ADDINZIP (3)
|
||||
#define APPEND_STATUS_CREATE (0)
|
||||
#define APPEND_STATUS_CREATEAFTER (1)
|
||||
#define APPEND_STATUS_ADDINZIP (2)
|
||||
|
||||
/***************************************************************************/
|
||||
/* Writing a zip file */
|
||||
|
||||
extern zipFile ZEXPORT zipOpen(const char *path, int append);
|
||||
extern zipFile ZEXPORT zipOpen64(const void *path, int append);
|
||||
extern zipFile ZEXPORT zipOpen2(const char *path, int append, const char **globalcomment,
|
||||
ZEXPORT zipFile zipOpen(const char *path, int append);
|
||||
ZEXPORT zipFile zipOpen64(const void *path, int append);
|
||||
ZEXPORT zipFile zipOpen2(const char *path, int append, const char **globalcomment,
|
||||
zlib_filefunc_def *pzlib_filefunc_def);
|
||||
extern zipFile ZEXPORT zipOpen2_64(const void *path, int append, const char **globalcomment,
|
||||
ZEXPORT zipFile zipOpen2_64(const void *path, int append, const char **globalcomment,
|
||||
zlib_filefunc64_def *pzlib_filefunc_def);
|
||||
zipFile zipOpen_MZ(void *stream, int append, const char **globalcomment);
|
||||
|
||||
extern int ZEXPORT zipOpenNewFileInZip3(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
||||
ZEXPORT int zipOpenNewFileInZip(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
||||
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
||||
uint16_t size_extrafield_global, const char *comment, uint16_t compression_method, int level);
|
||||
ZEXPORT int zipOpenNewFileInZip_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
||||
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
||||
uint16_t size_extrafield_global, const char *comment, uint16_t compression_method, int level,
|
||||
int zip64);
|
||||
ZEXPORT int zipOpenNewFileInZip2(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
||||
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
||||
uint16_t size_extrafield_global, const char *comment, uint16_t compression_method, int level,
|
||||
int raw);
|
||||
ZEXPORT int zipOpenNewFileInZip2_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
||||
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
||||
uint16_t size_extrafield_global, const char *comment, uint16_t compression_method, int level,
|
||||
int raw, int zip64);
|
||||
ZEXPORT int zipOpenNewFileInZip3(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
||||
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
||||
uint16_t size_extrafield_global, const char *comment, uint16_t compression_method, int level,
|
||||
int raw, int windowBits, int memLevel, int strategy, const char *password,
|
||||
uint32_t crc_for_crypting);
|
||||
extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
||||
ZEXPORT int zipOpenNewFileInZip3_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
||||
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
||||
uint16_t size_extrafield_global, const char *comment, uint16_t compression_method, int level,
|
||||
int raw, int windowBits, int memLevel, int strategy, const char *password,
|
||||
uint32_t crc_for_crypting, int zip64);
|
||||
extern int ZEXPORT zipOpenNewFileInZip4(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
||||
ZEXPORT int zipOpenNewFileInZip4(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
||||
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
||||
uint16_t size_extrafield_global, const char *comment, uint16_t compression_method, int level,
|
||||
int raw, int windowBits, int memLevel, int strategy, const char *password,
|
||||
uint32_t crc_for_crypting, uint16_t version_madeby, uint16_t flag_base);
|
||||
extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
||||
ZEXPORT int zipOpenNewFileInZip4_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
||||
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
||||
uint16_t size_extrafield_global, const char *comment, uint16_t compression_method, int level,
|
||||
int raw, int windowBits, int memLevel, int strategy, const char *password,
|
||||
uint32_t crc_for_crypting, uint16_t version_madeby, uint16_t flag_base, int zip64);
|
||||
extern int ZEXPORT zipOpenNewFileInZip5(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
||||
ZEXPORT int zipOpenNewFileInZip5(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
||||
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
||||
uint16_t size_extrafield_global, const char *comment, uint16_t compression_method, int level,
|
||||
int raw, int windowBits, int memLevel, int strategy, const char *password,
|
||||
uint32_t crc_for_crypting, uint16_t version_madeby, uint16_t flag_base, int zip64);
|
||||
|
||||
extern int ZEXPORT zipWriteInFileInZip(zipFile file, const void *buf, uint32_t len);
|
||||
ZEXPORT int zipWriteInFileInZip(zipFile file, const void *buf, uint32_t len);
|
||||
|
||||
extern int ZEXPORT zipCloseFileInZipRaw(zipFile file, uint32_t uncompressed_size, uint32_t crc32);
|
||||
extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, uint64_t uncompressed_size, uint32_t crc32);
|
||||
extern int ZEXPORT zipCloseFileInZip(zipFile file);
|
||||
extern int ZEXPORT zipCloseFileInZip64(zipFile file);
|
||||
ZEXPORT int zipCloseFileInZipRaw(zipFile file, uint32_t uncompressed_size, uint32_t crc32);
|
||||
ZEXPORT int zipCloseFileInZipRaw64(zipFile file, int64_t uncompressed_size, uint32_t crc32);
|
||||
ZEXPORT int zipCloseFileInZip(zipFile file);
|
||||
ZEXPORT int zipCloseFileInZip64(zipFile file);
|
||||
|
||||
extern int ZEXPORT zipClose(zipFile file, const char *global_comment);
|
||||
extern int ZEXPORT zipClose_64(zipFile file, const char *global_comment);
|
||||
extern int ZEXPORT zipClose2_64(zipFile file, const char *global_comment, uint16_t version_madeby);
|
||||
ZEXPORT int zipClose(zipFile file, const char *global_comment);
|
||||
ZEXPORT int zipClose_64(zipFile file, const char *global_comment);
|
||||
ZEXPORT int zipClose2_64(zipFile file, const char *global_comment, uint16_t version_madeby);
|
||||
int zipClose_MZ(zipFile file, const char *global_comment);
|
||||
int zipClose2_MZ(zipFile file, const char *global_comment, uint16_t version_madeby);
|
||||
ZEXPORT void* zipGetStream(zipFile file);
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
@@ -174,36 +188,36 @@ typedef void *unzFile;
|
||||
|
||||
typedef struct unz_global_info64_s
|
||||
{
|
||||
uint64_t number_entry; // total number of entries in the central dir on this disk
|
||||
uint32_t number_disk_with_CD; // number the the disk with central dir, used for spanning ZIP
|
||||
uint16_t size_comment; // size of the global comment of the zipfile
|
||||
uint64_t number_entry; /* total number of entries in the central dir on this disk */
|
||||
uint32_t number_disk_with_CD; /* number the the disk with central dir, used for spanning ZIP */
|
||||
uint16_t size_comment; /* size of the global comment of the zipfile */
|
||||
} unz_global_info64;
|
||||
|
||||
typedef struct unz_global_info_s
|
||||
{
|
||||
uint32_t number_entry; // total number of entries in the central dir on this disk
|
||||
uint32_t number_disk_with_CD; // number the the disk with central dir, used for spanning ZIP
|
||||
uint16_t size_comment; // size of the global comment of the zipfile
|
||||
uint32_t number_entry; /* total number of entries in the central dir on this disk */
|
||||
uint32_t number_disk_with_CD; /* number the the disk with central dir, used for spanning ZIP */
|
||||
uint16_t size_comment; /* size of the global comment of the zipfile */
|
||||
} unz_global_info;
|
||||
|
||||
typedef struct unz_file_info64_s
|
||||
{
|
||||
uint16_t version; // version made by 2 bytes
|
||||
uint16_t version_needed; // version needed to extract 2 bytes
|
||||
uint16_t flag; // general purpose bit flag 2 bytes
|
||||
uint16_t compression_method; // compression method 2 bytes
|
||||
uint32_t dosDate; // last mod file date in Dos fmt 4 bytes
|
||||
uint16_t version; /* version made by 2 bytes */
|
||||
uint16_t version_needed; /* version needed to extract 2 bytes */
|
||||
uint16_t flag; /* general purpose bit flag 2 bytes */
|
||||
uint16_t compression_method; /* compression method 2 bytes */
|
||||
uint32_t mz_dos_date; /* last mod file date in Dos fmt 4 bytes */
|
||||
struct tm tmu_date;
|
||||
uint32_t crc; // crc-32 4 bytes
|
||||
uint64_t compressed_size; // compressed size 8 bytes
|
||||
uint64_t uncompressed_size; // uncompressed size 8 bytes
|
||||
uint16_t size_filename; // filename length 2 bytes
|
||||
uint16_t size_file_extra; // extra field length 2 bytes
|
||||
uint16_t size_file_comment; // file comment length 2 bytes
|
||||
uint32_t crc; /* crc-32 4 bytes */
|
||||
uint64_t compressed_size; /* compressed size 8 bytes */
|
||||
uint64_t uncompressed_size; /* uncompressed size 8 bytes */
|
||||
uint16_t size_filename; /* filename length 2 bytes */
|
||||
uint16_t size_file_extra; /* extra field length 2 bytes */
|
||||
uint16_t size_file_comment; /* file comment length 2 bytes */
|
||||
|
||||
uint32_t disk_num_start; // disk number start 4 bytes
|
||||
uint16_t internal_fa; // internal file attributes 2 bytes
|
||||
uint32_t external_fa; // external file attributes 4 bytes
|
||||
uint32_t disk_num_start; /* disk number start 4 bytes */
|
||||
uint16_t internal_fa; /* internal file attributes 2 bytes */
|
||||
uint32_t external_fa; /* external file attributes 4 bytes */
|
||||
|
||||
uint64_t disk_offset;
|
||||
|
||||
@@ -212,22 +226,22 @@ typedef struct unz_file_info64_s
|
||||
|
||||
typedef struct unz_file_info_s
|
||||
{
|
||||
uint16_t version; // version made by 2 bytes
|
||||
uint16_t version_needed; // version needed to extract 2 bytes
|
||||
uint16_t flag; // general purpose bit flag 2 bytes
|
||||
uint16_t compression_method; // compression method 2 bytes
|
||||
uint32_t dosDate; // last mod file date in Dos fmt 4 bytes
|
||||
uint16_t version; /* version made by 2 bytes */
|
||||
uint16_t version_needed; /* version needed to extract 2 bytes */
|
||||
uint16_t flag; /* general purpose bit flag 2 bytes */
|
||||
uint16_t compression_method; /* compression method 2 bytes */
|
||||
uint32_t mz_dos_date; /* last mod file date in Dos fmt 4 bytes */
|
||||
struct tm tmu_date;
|
||||
uint32_t crc; // crc-32 4 bytes
|
||||
uint32_t compressed_size; // compressed size 4 bytes
|
||||
uint32_t uncompressed_size; // uncompressed size 4 bytes
|
||||
uint16_t size_filename; // filename length 2 bytes
|
||||
uint16_t size_file_extra; // extra field length 2 bytes
|
||||
uint16_t size_file_comment; // file comment length 2 bytes
|
||||
uint32_t crc; /* crc-32 4 bytes */
|
||||
uint32_t compressed_size; /* compressed size 4 bytes */
|
||||
uint32_t uncompressed_size; /* uncompressed size 4 bytes */
|
||||
uint16_t size_filename; /* filename length 2 bytes */
|
||||
uint16_t size_file_extra; /* extra field length 2 bytes */
|
||||
uint16_t size_file_comment; /* file comment length 2 bytes */
|
||||
|
||||
uint16_t disk_num_start; // disk number start 2 bytes
|
||||
uint16_t internal_fa; // internal file attributes 2 bytes
|
||||
uint32_t external_fa; // external file attributes 4 bytes
|
||||
uint16_t disk_num_start; /* disk number start 2 bytes */
|
||||
uint16_t internal_fa; /* internal file attributes 2 bytes */
|
||||
uint32_t external_fa; /* external file attributes 4 bytes */
|
||||
|
||||
uint64_t disk_offset;
|
||||
} unz_file_info;
|
||||
@@ -237,61 +251,88 @@ typedef struct unz_file_info_s
|
||||
typedef int (*unzFileNameComparer)(unzFile file, const char *filename1, const char *filename2);
|
||||
typedef int (*unzIteratorFunction)(unzFile file);
|
||||
typedef int (*unzIteratorFunction2)(unzFile file, unz_file_info64 *pfile_info, char *filename,
|
||||
uint16_t filename_size, void *extrafield, uint16_t extrafield_size, char *comment, uint16_t comment_size);
|
||||
uint16_t filename_size, void *extrafield, uint16_t extrafield_size, char *comment,
|
||||
uint16_t comment_size);
|
||||
|
||||
/***************************************************************************/
|
||||
/* Reading a zip file */
|
||||
|
||||
ZEXPORT unzFile unzOpen(const char *path);
|
||||
ZEXPORT unzFile unzOpen64(const void *path);
|
||||
ZEXPORT unzFile unzOpen2(const char *path, zlib_filefunc_def *pzlib_filefunc_def);
|
||||
ZEXPORT unzFile unzOpen2_64(const void *path, zlib_filefunc64_def *pzlib_filefunc_def);
|
||||
unzFile unzOpen_MZ(void *stream);
|
||||
|
||||
ZEXPORT int unzClose(unzFile file);
|
||||
int unzClose_MZ(unzFile file);
|
||||
|
||||
ZEXPORT int unzGetGlobalInfo(unzFile file, unz_global_info* pglobal_info32);
|
||||
ZEXPORT int unzGetGlobalInfo64(unzFile file, unz_global_info64 *pglobal_info);
|
||||
ZEXPORT int unzGetGlobalComment(unzFile file, char *comment, uint16_t comment_size);
|
||||
|
||||
ZEXPORT int unzOpenCurrentFile(unzFile file);
|
||||
ZEXPORT int unzOpenCurrentFilePassword(unzFile file, const char *password);
|
||||
ZEXPORT int unzOpenCurrentFile2(unzFile file, int *method, int *level, int raw);
|
||||
ZEXPORT int unzOpenCurrentFile3(unzFile file, int *method, int *level, int raw, const char *password);
|
||||
ZEXPORT int unzReadCurrentFile(unzFile file, void *buf, uint32_t len);
|
||||
ZEXPORT int unzCloseCurrentFile(unzFile file);
|
||||
|
||||
|
||||
ZEXPORT int unzGetCurrentFileInfo(unzFile file, unz_file_info *pfile_info, char *filename,
|
||||
uint16_t filename_size, void *extrafield, uint16_t extrafield_size, char *comment,
|
||||
uint16_t comment_size);
|
||||
ZEXPORT int unzGetCurrentFileInfo64(unzFile file, unz_file_info64 * pfile_info, char *filename,
|
||||
uint16_t filename_size, void *extrafield, uint16_t extrafield_size, char *comment,
|
||||
uint16_t comment_size);
|
||||
|
||||
ZEXPORT int unzGoToFirstFile(unzFile file);
|
||||
ZEXPORT int unzGoToNextFile(unzFile file);
|
||||
ZEXPORT int unzLocateFile(unzFile file, const char *filename, unzFileNameComparer filename_compare_func);
|
||||
|
||||
ZEXPORT int unzGetLocalExtrafield(unzFile file, void *buf, unsigned int len);
|
||||
|
||||
/***************************************************************************/
|
||||
/* Raw access to zip file */
|
||||
|
||||
typedef struct unz_file_pos_s
|
||||
{
|
||||
uint32_t pos_in_zip_directory; /* offset in zip file directory */
|
||||
uint32_t num_of_file; /* # of file */
|
||||
} unz_file_pos;
|
||||
|
||||
ZEXPORT int unzGetFilePos(unzFile file, unz_file_pos *file_pos);
|
||||
ZEXPORT int unzGoToFilePos(unzFile file, unz_file_pos *file_pos);
|
||||
|
||||
typedef struct unz64_file_pos_s
|
||||
{
|
||||
int64_t pos_in_zip_directory; /* offset in zip file directory */
|
||||
uint64_t num_of_file; /* # of file */
|
||||
} unz64_file_pos;
|
||||
|
||||
ZEXPORT int unzGetFilePos64(unzFile file, unz64_file_pos *file_pos);
|
||||
ZEXPORT int unzGoToFilePos64(unzFile file, const unz64_file_pos *file_pos);
|
||||
|
||||
ZEXPORT int64_t unzGetOffset64(unzFile file);
|
||||
ZEXPORT int32_t unzGetOffset(unzFile file);
|
||||
ZEXPORT int unzSetOffset64(unzFile file, int64_t pos);
|
||||
ZEXPORT int unzSetOffset(unzFile file, uint32_t pos);
|
||||
ZEXPORT int64_t unztell(unzFile file);
|
||||
ZEXPORT int32_t unzTell(unzFile file);
|
||||
ZEXPORT int64_t unzTell64(unzFile file);
|
||||
ZEXPORT int unzSeek(unzFile file, int32_t offset, int origin);
|
||||
ZEXPORT int unzSeek64(unzFile file, int64_t offset, int origin);
|
||||
ZEXPORT int unzEndOfFile(unzFile file);
|
||||
ZEXPORT void* unzGetStream(unzFile file);
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
extern unzFile ZEXPORT unzOpen(const char *path);
|
||||
extern unzFile ZEXPORT unzOpen64(const void *path);
|
||||
extern unzFile ZEXPORT unzOpen2(const char *path, zlib_filefunc_def *pzlib_filefunc_def);
|
||||
extern unzFile ZEXPORT unzOpen2_64(const void *path, zlib_filefunc64_def *pzlib_filefunc_def);
|
||||
|
||||
extern int ZEXPORT unzClose(unzFile file);
|
||||
extern int ZEXPORT unzGetGlobalInfo(unzFile file, unz_global_info* pglobal_info32);
|
||||
extern int ZEXPORT unzGetGlobalInfo64(unzFile file, unz_global_info64 *pglobal_info);
|
||||
extern int ZEXPORT unzGetGlobalComment(unzFile file, char *comment, uint16_t comment_size);
|
||||
extern int ZEXPORT unzOpenCurrentFile(unzFile file);
|
||||
extern int ZEXPORT unzOpenCurrentFilePassword(unzFile file, const char *password);
|
||||
extern int ZEXPORT unzOpenCurrentFile2(unzFile file, int *method, int *level, int raw);
|
||||
extern int ZEXPORT unzOpenCurrentFile3(unzFile file, int *method, int *level, int raw, const char *password);
|
||||
extern int ZEXPORT unzReadCurrentFile(unzFile file, void *buf, uint32_t len);
|
||||
extern int ZEXPORT unzCloseCurrentFile(unzFile file);
|
||||
|
||||
extern int ZEXPORT unzGetCurrentFileInfo(unzFile file, unz_file_info *pfile_info, char *filename,
|
||||
uint16_t filename_size, void *extrafield, uint16_t extrafield_size, char *comment, uint16_t comment_size);
|
||||
extern int ZEXPORT unzGetCurrentFileInfo64(unzFile file, unz_file_info64 * pfile_info, char *filename,
|
||||
uint16_t filename_size, void *extrafield, uint16_t extrafield_size, char *comment, uint16_t comment_size);
|
||||
extern int ZEXPORT unzGoToFirstFile(unzFile file);
|
||||
extern int ZEXPORT unzGoToNextFile(unzFile file);
|
||||
extern int ZEXPORT unzLocateFile(unzFile file, const char *filename, unzFileNameComparer filename_compare_func);
|
||||
|
||||
extern int64_t ZEXPORT unzGetOffset64(unzFile file);
|
||||
extern int32_t ZEXPORT unzGetOffset(unzFile file);
|
||||
extern int ZEXPORT unzSetOffset64(unzFile file, uint64_t pos);
|
||||
extern int ZEXPORT unzSetOffset(unzFile file, uint32_t pos);
|
||||
extern int ZEXPORT unzGetLocalExtrafield(unzFile file, void *buf, unsigned len);
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void fill_fopen_filefunc(zlib_filefunc_def *pzlib_filefunc_def);
|
||||
void fill_fopen64_filefunc(zlib_filefunc64_def *pzlib_filefunc_def);
|
||||
void fill_win32_filefunc(zlib_filefunc_def *pzlib_filefunc_def);
|
||||
void fill_win32_filefunc64(zlib_filefunc64_def *pzlib_filefunc_def);
|
||||
void fill_win32_filefunc64A(zlib_filefunc64_def *pzlib_filefunc_def);
|
||||
void fill_win32_filefunc64W(zlib_filefunc64_def *pzlib_filefunc_def);
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#define check_file_exists mz_os_file_exists
|
||||
#define dosdate_to_tm mz_zip_dosdate_to_tm
|
||||
#define change_file_date mz_os_set_file_date
|
||||
#define get_file_date mz_os_get_file_date
|
||||
#define is_large_file(x) (mz_os_get_file_size(x) >= UINT32_MAX)
|
||||
#define makedir mz_make_dir
|
||||
#define get_file_crc(p,b,bs,rc) mz_get_file_crc(p,rc)
|
||||
|
||||
#define MKDIR mz_os_make_dir
|
||||
#define CHDIR chdir
|
||||
ZEXPORT void fill_fopen_filefunc(zlib_filefunc_def *pzlib_filefunc_def);
|
||||
ZEXPORT void fill_fopen64_filefunc(zlib_filefunc64_def *pzlib_filefunc_def);
|
||||
ZEXPORT void fill_win32_filefunc(zlib_filefunc_def *pzlib_filefunc_def);
|
||||
ZEXPORT void fill_win32_filefunc64(zlib_filefunc64_def *pzlib_filefunc_def);
|
||||
ZEXPORT void fill_win32_filefunc64A(zlib_filefunc64_def *pzlib_filefunc_def);
|
||||
ZEXPORT void fill_win32_filefunc64W(zlib_filefunc64_def *pzlib_filefunc_def);
|
||||
ZEXPORT void fill_memory_filefunc(zlib_filefunc_def *pzlib_filefunc_def);
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
/* mz_crypt.c -- Crypto/hash functions
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
See the accompanying LICENSE file for the full text of the license.
|
||||
*/
|
||||
|
||||
|
||||
#include "mz.h"
|
||||
#include "mz_crypt.h"
|
||||
|
||||
#if defined(HAVE_ZLIB)
|
||||
# include "zlib.h"
|
||||
# if defined(ZLIBNG_VERNUM) && !defined(ZLIB_COMPAT)
|
||||
# include "zlib-ng.h"
|
||||
# endif
|
||||
#elif defined(HAVE_LZMA)
|
||||
# include "lzma.h"
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
/* Define z_crc_t in zlib 1.2.5 and less or if using zlib-ng */
|
||||
|
||||
#if defined(HAVE_ZLIB) && defined(ZLIBNG_VERNUM)
|
||||
# if defined(ZLIB_COMPAT)
|
||||
# define ZLIB_PREFIX(x) x
|
||||
# else
|
||||
# define ZLIB_PREFIX(x) zng_ ## x
|
||||
# endif
|
||||
typedef uint32_t z_crc_t;
|
||||
#elif defined(HAVE_ZLIB)
|
||||
# define ZLIB_PREFIX(x) x
|
||||
# if (ZLIB_VERNUM < 0x1270)
|
||||
typedef unsigned long z_crc_t;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
uint32_t mz_crypt_crc32_update(uint32_t value, const uint8_t *buf, int32_t size)
|
||||
{
|
||||
#if defined(HAVE_ZLIB)
|
||||
return (uint32_t)ZLIB_PREFIX(crc32)((z_crc_t)value, buf, (uInt)size);
|
||||
#elif defined(HAVE_LZMA)
|
||||
return (uint32_t)lzma_crc32(buf, (size_t)size, (uint32_t)value);
|
||||
#else
|
||||
static uint32_t crc32_table[256] = {
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
|
||||
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
|
||||
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
|
||||
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
|
||||
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
|
||||
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
|
||||
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
|
||||
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
||||
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
|
||||
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
|
||||
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
|
||||
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
|
||||
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
||||
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
|
||||
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
|
||||
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
|
||||
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
|
||||
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
|
||||
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
|
||||
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
||||
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
|
||||
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
|
||||
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
||||
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
|
||||
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
|
||||
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||
};
|
||||
value = ~value;
|
||||
|
||||
while (size > 0)
|
||||
{
|
||||
value = (value >> 8) ^ crc32_table[(value ^ *buf) & 0xFF];
|
||||
|
||||
buf += 1;
|
||||
size -= 1;
|
||||
}
|
||||
|
||||
return ~value;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef MZ_ZIP_NO_ENCRYPTION
|
||||
int32_t mz_crypt_pbkdf2(uint8_t *password, int32_t password_length, uint8_t *salt,
|
||||
int32_t salt_length, int32_t iteration_count, uint8_t *key, int32_t key_length)
|
||||
{
|
||||
void *hmac1 = NULL;
|
||||
void *hmac2 = NULL;
|
||||
void *hmac3 = NULL;
|
||||
int32_t err = MZ_OK;
|
||||
uint16_t i = 0;
|
||||
uint16_t j = 0;
|
||||
uint16_t k = 0;
|
||||
uint16_t block_count = 0;
|
||||
uint8_t uu[MZ_HASH_SHA1_SIZE];
|
||||
uint8_t ux[MZ_HASH_SHA1_SIZE];
|
||||
|
||||
if (password == NULL || salt == NULL || key == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
memset(key, 0, key_length);
|
||||
|
||||
mz_crypt_hmac_create(&hmac1);
|
||||
mz_crypt_hmac_create(&hmac2);
|
||||
mz_crypt_hmac_create(&hmac3);
|
||||
|
||||
mz_crypt_hmac_set_algorithm(hmac1, MZ_HASH_SHA1);
|
||||
mz_crypt_hmac_set_algorithm(hmac2, MZ_HASH_SHA1);
|
||||
mz_crypt_hmac_set_algorithm(hmac3, MZ_HASH_SHA1);
|
||||
|
||||
err = mz_crypt_hmac_init(hmac1, password, password_length);
|
||||
if (err == MZ_OK)
|
||||
err = mz_crypt_hmac_init(hmac2, password, password_length);
|
||||
if (err == MZ_OK)
|
||||
err = mz_crypt_hmac_update(hmac2, salt, salt_length);
|
||||
|
||||
block_count = 1 + ((uint16_t)key_length - 1) / MZ_HASH_SHA1_SIZE;
|
||||
|
||||
for (i = 0; (err == MZ_OK) && (i < block_count); i += 1)
|
||||
{
|
||||
memset(ux, 0, sizeof(ux));
|
||||
|
||||
err = mz_crypt_hmac_copy(hmac2, hmac3);
|
||||
if (err != MZ_OK)
|
||||
break;
|
||||
|
||||
uu[0] = (uint8_t)((i + 1) >> 24);
|
||||
uu[1] = (uint8_t)((i + 1) >> 16);
|
||||
uu[2] = (uint8_t)((i + 1) >> 8);
|
||||
uu[3] = (uint8_t)(i + 1);
|
||||
|
||||
for (j = 0, k = 4; j < iteration_count; j += 1)
|
||||
{
|
||||
err = mz_crypt_hmac_update(hmac3, uu, k);
|
||||
if (err == MZ_OK)
|
||||
err = mz_crypt_hmac_end(hmac3, uu, sizeof(uu));
|
||||
if (err != MZ_OK)
|
||||
break;
|
||||
|
||||
for(k = 0; k < MZ_HASH_SHA1_SIZE; k += 1)
|
||||
ux[k] ^= uu[k];
|
||||
|
||||
err = mz_crypt_hmac_copy(hmac1, hmac3);
|
||||
if (err != MZ_OK)
|
||||
break;
|
||||
}
|
||||
|
||||
if (err != MZ_OK)
|
||||
break;
|
||||
|
||||
j = 0;
|
||||
k = i * MZ_HASH_SHA1_SIZE;
|
||||
|
||||
while (j < MZ_HASH_SHA1_SIZE && k < key_length)
|
||||
key[k++] = ux[j++];
|
||||
}
|
||||
|
||||
/* hmac3 uses the same provider as hmac2, so it must be deleted
|
||||
before the context is destroyed. */
|
||||
mz_crypt_hmac_delete(&hmac3);
|
||||
mz_crypt_hmac_delete(&hmac1);
|
||||
mz_crypt_hmac_delete(&hmac2);
|
||||
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/* mz_crypt.h -- Crypto/hash functions
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
See the accompanying LICENSE file for the full text of the license.
|
||||
*/
|
||||
|
||||
#ifndef MZ_CRYPT_H
|
||||
#define MZ_CRYPT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
uint32_t mz_crypt_crc32_update(uint32_t value, const uint8_t *buf, int32_t size);
|
||||
|
||||
int32_t mz_crypt_pbkdf2(uint8_t *password, int32_t password_length, uint8_t *salt,
|
||||
int32_t salt_length, int32_t iteration_count, uint8_t *key, int32_t key_length);
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t mz_crypt_rand(uint8_t *buf, int32_t size);
|
||||
|
||||
void mz_crypt_sha_reset(void *handle);
|
||||
int32_t mz_crypt_sha_begin(void *handle);
|
||||
int32_t mz_crypt_sha_update(void *handle, const void *buf, int32_t size);
|
||||
int32_t mz_crypt_sha_end(void *handle, uint8_t *digest, int32_t digest_size);
|
||||
void mz_crypt_sha_set_algorithm(void *handle, uint16_t algorithm);
|
||||
void* mz_crypt_sha_create(void **handle);
|
||||
void mz_crypt_sha_delete(void **handle);
|
||||
|
||||
void mz_crypt_aes_reset(void *handle);
|
||||
int32_t mz_crypt_aes_encrypt(void *handle, uint8_t *buf, int32_t size);
|
||||
int32_t mz_crypt_aes_decrypt(void *handle, uint8_t *buf, int32_t size);
|
||||
int32_t mz_crypt_aes_set_encrypt_key(void *handle, const void *key, int32_t key_length);
|
||||
int32_t mz_crypt_aes_set_decrypt_key(void *handle, const void *key, int32_t key_length);
|
||||
void mz_crypt_aes_set_mode(void *handle, int32_t mode);
|
||||
void* mz_crypt_aes_create(void **handle);
|
||||
void mz_crypt_aes_delete(void **handle);
|
||||
|
||||
void mz_crypt_hmac_reset(void *handle);
|
||||
int32_t mz_crypt_hmac_init(void *handle, const void *key, int32_t key_length);
|
||||
int32_t mz_crypt_hmac_update(void *handle, const void *buf, int32_t size);
|
||||
int32_t mz_crypt_hmac_end(void *handle, uint8_t *digest, int32_t digest_size);
|
||||
int32_t mz_crypt_hmac_copy(void *src_handle, void *target_handle);
|
||||
void mz_crypt_hmac_set_algorithm(void *handle, uint16_t algorithm);
|
||||
void* mz_crypt_hmac_create(void **handle);
|
||||
void mz_crypt_hmac_delete(void **handle);
|
||||
|
||||
int32_t mz_crypt_sign(uint8_t *message, int32_t message_size, uint8_t *cert_data, int32_t cert_data_size,
|
||||
const char *cert_pwd, uint8_t **signature, int32_t *signature_size);
|
||||
int32_t mz_crypt_sign_verify(uint8_t *message, int32_t message_size, uint8_t *signature, int32_t signature_size);
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,532 @@
|
||||
/* mz_crypt_apple.c -- Crypto/hash functions for Apple
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
See the accompanying LICENSE file for the full text of the license.
|
||||
*/
|
||||
|
||||
|
||||
#include "mz.h"
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <CommonCrypto/CommonCryptor.h>
|
||||
#include <CommonCrypto/CommonDigest.h>
|
||||
#include <CommonCrypto/CommonHMAC.h>
|
||||
#include <Security/Security.h>
|
||||
#include <Security/SecPolicy.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t mz_crypt_rand(uint8_t *buf, int32_t size)
|
||||
{
|
||||
if (SecRandomCopyBytes(kSecRandomDefault, size, buf) != errSecSuccess)
|
||||
return 0;
|
||||
return size;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
typedef struct mz_crypt_sha_s {
|
||||
CC_SHA1_CTX ctx1;
|
||||
CC_SHA256_CTX ctx256;
|
||||
int32_t error;
|
||||
int32_t initialized;
|
||||
uint16_t algorithm;
|
||||
} mz_crypt_sha;
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void mz_crypt_sha_reset(void *handle)
|
||||
{
|
||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
||||
|
||||
sha->error = 0;
|
||||
sha->initialized = 0;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_sha_begin(void *handle)
|
||||
{
|
||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
||||
|
||||
if (sha == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
mz_crypt_sha_reset(handle);
|
||||
|
||||
if (sha->algorithm == MZ_HASH_SHA1)
|
||||
sha->error = CC_SHA1_Init(&sha->ctx1);
|
||||
else if (sha->algorithm == MZ_HASH_SHA256)
|
||||
sha->error = CC_SHA256_Init(&sha->ctx256);
|
||||
else
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
if (!sha->error)
|
||||
return MZ_HASH_ERROR;
|
||||
|
||||
sha->initialized = 1;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_sha_update(void *handle, const void *buf, int32_t size)
|
||||
{
|
||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
||||
|
||||
if (sha == NULL || buf == NULL || !sha->initialized)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
if (sha->algorithm == MZ_HASH_SHA1)
|
||||
sha->error = CC_SHA1_Update(&sha->ctx1, buf, size);
|
||||
else
|
||||
sha->error = CC_SHA256_Update(&sha->ctx256, buf, size);
|
||||
|
||||
if (!sha->error)
|
||||
return MZ_HASH_ERROR;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_sha_end(void *handle, uint8_t *digest, int32_t digest_size)
|
||||
{
|
||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
||||
|
||||
if (sha == NULL || digest == NULL || !sha->initialized)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
if (sha->algorithm == MZ_HASH_SHA1)
|
||||
{
|
||||
if (digest_size < MZ_HASH_SHA1_SIZE)
|
||||
return MZ_BUF_ERROR;
|
||||
sha->error = CC_SHA1_Final(digest, &sha->ctx1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (digest_size < MZ_HASH_SHA256_SIZE)
|
||||
return MZ_BUF_ERROR;
|
||||
sha->error = CC_SHA256_Final(digest, &sha->ctx256);
|
||||
}
|
||||
|
||||
if (!sha->error)
|
||||
return MZ_HASH_ERROR;
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
void mz_crypt_sha_set_algorithm(void *handle, uint16_t algorithm)
|
||||
{
|
||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
||||
sha->algorithm = algorithm;
|
||||
}
|
||||
|
||||
void *mz_crypt_sha_create(void **handle)
|
||||
{
|
||||
mz_crypt_sha *sha = NULL;
|
||||
|
||||
sha = (mz_crypt_sha *)MZ_ALLOC(sizeof(mz_crypt_sha));
|
||||
if (sha != NULL)
|
||||
{
|
||||
memset(sha, 0, sizeof(mz_crypt_sha));
|
||||
sha->algorithm = MZ_HASH_SHA256;
|
||||
}
|
||||
if (handle != NULL)
|
||||
*handle = sha;
|
||||
|
||||
return sha;
|
||||
}
|
||||
|
||||
void mz_crypt_sha_delete(void **handle)
|
||||
{
|
||||
mz_crypt_sha *sha = NULL;
|
||||
if (handle == NULL)
|
||||
return;
|
||||
sha = (mz_crypt_sha *)*handle;
|
||||
if (sha != NULL)
|
||||
{
|
||||
mz_crypt_sha_reset(*handle);
|
||||
MZ_FREE(sha);
|
||||
}
|
||||
*handle = NULL;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
typedef struct mz_crypt_aes_s {
|
||||
CCCryptorRef crypt;
|
||||
int32_t mode;
|
||||
int32_t error;
|
||||
} mz_crypt_aes;
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void mz_crypt_aes_reset(void *handle)
|
||||
{
|
||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
||||
|
||||
if (aes->crypt != NULL)
|
||||
CCCryptorRelease(aes->crypt);
|
||||
aes->crypt = NULL;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_aes_encrypt(void *handle, uint8_t *buf, int32_t size)
|
||||
{
|
||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
||||
size_t data_moved = 0;
|
||||
|
||||
if (aes == NULL || buf == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
if (size != MZ_AES_BLOCK_SIZE)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
aes->error = CCCryptorUpdate(aes->crypt, buf, size, buf, size, &data_moved);
|
||||
|
||||
if (aes->error != kCCSuccess)
|
||||
return MZ_HASH_ERROR;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_aes_decrypt(void *handle, uint8_t *buf, int32_t size)
|
||||
{
|
||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
||||
size_t data_moved = 0;
|
||||
|
||||
if (aes == NULL || buf == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
if (size != MZ_AES_BLOCK_SIZE)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
aes->error = CCCryptorUpdate(aes->crypt, buf, size, buf, size, &data_moved);
|
||||
|
||||
if (aes->error != kCCSuccess)
|
||||
return MZ_HASH_ERROR;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_aes_set_encrypt_key(void *handle, const void *key, int32_t key_length)
|
||||
{
|
||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
||||
|
||||
|
||||
if (aes == NULL || key == NULL || key_length == 0)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
mz_crypt_aes_reset(handle);
|
||||
|
||||
aes->error = CCCryptorCreate(kCCEncrypt, kCCAlgorithmAES, kCCOptionECBMode,
|
||||
key, key_length, NULL, &aes->crypt);
|
||||
|
||||
if (aes->error != kCCSuccess)
|
||||
return MZ_HASH_ERROR;
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_aes_set_decrypt_key(void *handle, const void *key, int32_t key_length)
|
||||
{
|
||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
||||
|
||||
|
||||
if (aes == NULL || key == NULL || key_length == 0)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
mz_crypt_aes_reset(handle);
|
||||
|
||||
aes->error = CCCryptorCreate(kCCDecrypt, kCCAlgorithmAES, kCCOptionECBMode,
|
||||
key, key_length, NULL, &aes->crypt);
|
||||
|
||||
if (aes->error != kCCSuccess)
|
||||
return MZ_HASH_ERROR;
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
void mz_crypt_aes_set_mode(void *handle, int32_t mode)
|
||||
{
|
||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
||||
aes->mode = mode;
|
||||
}
|
||||
|
||||
void *mz_crypt_aes_create(void **handle)
|
||||
{
|
||||
mz_crypt_aes *aes = NULL;
|
||||
|
||||
aes = (mz_crypt_aes *)MZ_ALLOC(sizeof(mz_crypt_aes));
|
||||
if (aes != NULL)
|
||||
memset(aes, 0, sizeof(mz_crypt_aes));
|
||||
if (handle != NULL)
|
||||
*handle = aes;
|
||||
|
||||
return aes;
|
||||
}
|
||||
|
||||
void mz_crypt_aes_delete(void **handle)
|
||||
{
|
||||
mz_crypt_aes *aes = NULL;
|
||||
if (handle == NULL)
|
||||
return;
|
||||
aes = (mz_crypt_aes *)*handle;
|
||||
if (aes != NULL)
|
||||
{
|
||||
mz_crypt_aes_reset(*handle);
|
||||
MZ_FREE(aes);
|
||||
}
|
||||
*handle = NULL;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
typedef struct mz_crypt_hmac_s {
|
||||
CCHmacContext ctx;
|
||||
int32_t initialized;
|
||||
int32_t error;
|
||||
uint16_t algorithm;
|
||||
} mz_crypt_hmac;
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void mz_crypt_hmac_free(void *handle)
|
||||
{
|
||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
||||
memset(&hmac->ctx, 0, sizeof(hmac->ctx));
|
||||
}
|
||||
|
||||
void mz_crypt_hmac_reset(void *handle)
|
||||
{
|
||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
||||
mz_crypt_hmac_free(handle);
|
||||
hmac->error = 0;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_hmac_init(void *handle, const void *key, int32_t key_length)
|
||||
{
|
||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
||||
CCHmacAlgorithm algorithm = 0;
|
||||
|
||||
if (hmac == NULL || key == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
mz_crypt_hmac_reset(handle);
|
||||
|
||||
if (hmac->algorithm == MZ_HASH_SHA1)
|
||||
algorithm = kCCHmacAlgSHA1;
|
||||
else if (hmac->algorithm == MZ_HASH_SHA256)
|
||||
algorithm = kCCHmacAlgSHA256;
|
||||
else
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
CCHmacInit(&hmac->ctx, algorithm, key, key_length);
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_hmac_update(void *handle, const void *buf, int32_t size)
|
||||
{
|
||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
||||
|
||||
if (hmac == NULL || buf == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
CCHmacUpdate(&hmac->ctx, buf, size);
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_hmac_end(void *handle, uint8_t *digest, int32_t digest_size)
|
||||
{
|
||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
||||
|
||||
if (hmac == NULL || digest == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
if (hmac->algorithm == MZ_HASH_SHA1)
|
||||
{
|
||||
if (digest_size < MZ_HASH_SHA1_SIZE)
|
||||
return MZ_BUF_ERROR;
|
||||
CCHmacFinal(&hmac->ctx, digest);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (digest_size < MZ_HASH_SHA256_SIZE)
|
||||
return MZ_BUF_ERROR;
|
||||
CCHmacFinal(&hmac->ctx, digest);
|
||||
}
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
void mz_crypt_hmac_set_algorithm(void *handle, uint16_t algorithm)
|
||||
{
|
||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
||||
hmac->algorithm = algorithm;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_hmac_copy(void *src_handle, void *target_handle)
|
||||
{
|
||||
mz_crypt_hmac *source = (mz_crypt_hmac *)src_handle;
|
||||
mz_crypt_hmac *target = (mz_crypt_hmac *)target_handle;
|
||||
|
||||
if (source == NULL || target == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
memcpy(&target->ctx, &source->ctx, sizeof(CCHmacContext));
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
void *mz_crypt_hmac_create(void **handle)
|
||||
{
|
||||
mz_crypt_hmac *hmac = NULL;
|
||||
|
||||
hmac = (mz_crypt_hmac *)MZ_ALLOC(sizeof(mz_crypt_hmac));
|
||||
if (hmac != NULL)
|
||||
{
|
||||
memset(hmac, 0, sizeof(mz_crypt_hmac));
|
||||
hmac->algorithm = MZ_HASH_SHA256;
|
||||
}
|
||||
if (handle != NULL)
|
||||
*handle = hmac;
|
||||
|
||||
return hmac;
|
||||
}
|
||||
|
||||
void mz_crypt_hmac_delete(void **handle)
|
||||
{
|
||||
mz_crypt_hmac *hmac = NULL;
|
||||
if (handle == NULL)
|
||||
return;
|
||||
hmac = (mz_crypt_hmac *)*handle;
|
||||
if (hmac != NULL)
|
||||
{
|
||||
mz_crypt_hmac_free(*handle);
|
||||
MZ_FREE(hmac);
|
||||
}
|
||||
*handle = NULL;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#if defined(MZ_ZIP_SIGNING)
|
||||
int32_t mz_crypt_sign(uint8_t *message, int32_t message_size, uint8_t *cert_data, int32_t cert_data_size,
|
||||
const char *cert_pwd, uint8_t **signature, int32_t *signature_size)
|
||||
{
|
||||
CFStringRef password_ref = NULL;
|
||||
CFDictionaryRef options_dict = NULL;
|
||||
CFDictionaryRef identity_trust = NULL;
|
||||
CFDataRef signature_out = NULL;
|
||||
CFDataRef pkcs12_data = NULL;
|
||||
CFArrayRef items = 0;
|
||||
SecIdentityRef identity = NULL;
|
||||
SecTrustRef trust = NULL;
|
||||
OSStatus status = noErr;
|
||||
const void *options_key[2] = { kSecImportExportPassphrase, kSecReturnRef };
|
||||
const void *options_values[2] = { 0, kCFBooleanTrue };
|
||||
int32_t err = MZ_SIGN_ERROR;
|
||||
|
||||
|
||||
if (message == NULL || cert_data == NULL || signature == NULL || signature_size == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
*signature = NULL;
|
||||
*signature_size = 0;
|
||||
|
||||
password_ref = CFStringCreateWithCString(0, cert_pwd, kCFStringEncodingUTF8);
|
||||
options_values[0] = password_ref;
|
||||
|
||||
options_dict = CFDictionaryCreate(0, options_key, options_values, 2, 0, 0);
|
||||
if (options_dict)
|
||||
pkcs12_data = CFDataCreate(0, cert_data, cert_data_size);
|
||||
if (pkcs12_data)
|
||||
status = SecPKCS12Import(pkcs12_data, options_dict, &items);
|
||||
if (status == noErr)
|
||||
identity_trust = CFArrayGetValueAtIndex(items, 0);
|
||||
if (identity_trust)
|
||||
identity = (SecIdentityRef)CFDictionaryGetValue(identity_trust, kSecImportItemIdentity);
|
||||
if (identity)
|
||||
trust = (SecTrustRef)CFDictionaryGetValue(identity_trust, kSecImportItemTrust);
|
||||
if (trust)
|
||||
{
|
||||
status = CMSEncodeContent(identity, NULL, NULL, FALSE, 0, message, message_size, &signature_out);
|
||||
|
||||
if (status == errSecSuccess)
|
||||
{
|
||||
*signature_size = CFDataGetLength(signature_out);
|
||||
*signature = (uint8_t *)MZ_ALLOC(*signature_size);
|
||||
|
||||
memcpy(*signature, CFDataGetBytePtr(signature_out), *signature_size);
|
||||
|
||||
err = MZ_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (signature_out)
|
||||
CFRelease(signature_out);
|
||||
if (items)
|
||||
CFRelease(items);
|
||||
if (pkcs12_data)
|
||||
CFRelease(pkcs12_data);
|
||||
if (options_dict)
|
||||
CFRelease(options_dict);
|
||||
if (password_ref)
|
||||
CFRelease(password_ref);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_sign_verify(uint8_t *message, int32_t message_size, uint8_t *signature, int32_t signature_size)
|
||||
{
|
||||
CMSDecoderRef decoder = NULL;
|
||||
CMSSignerStatus signer_status = 0;
|
||||
CFDataRef message_out = NULL;
|
||||
SecPolicyRef trust_policy = NULL;
|
||||
OSStatus status = noErr;
|
||||
OSStatus verify_status = noErr;
|
||||
size_t signer_count = 0;
|
||||
size_t i = 0;
|
||||
int32_t err = MZ_SIGN_ERROR;
|
||||
|
||||
if (message == NULL || signature == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
status = CMSDecoderCreate(&decoder);
|
||||
if (status == errSecSuccess)
|
||||
status = CMSDecoderUpdateMessage(decoder, signature, signature_size);
|
||||
if (status == errSecSuccess)
|
||||
status = CMSDecoderFinalizeMessage(decoder);
|
||||
if (status == errSecSuccess)
|
||||
trust_policy = SecPolicyCreateBasicX509();
|
||||
|
||||
if (status == errSecSuccess && trust_policy)
|
||||
{
|
||||
CMSDecoderGetNumSigners(decoder, &signer_count);
|
||||
if (signer_count > 0)
|
||||
err = MZ_OK;
|
||||
for (i = 0; i < signer_count; i += 1)
|
||||
{
|
||||
status = CMSDecoderCopySignerStatus(decoder, i, trust_policy, TRUE, &signer_status, NULL, &verify_status);
|
||||
if (status != errSecSuccess || verify_status != 0 || signer_status != kCMSSignerValid)
|
||||
{
|
||||
err = MZ_SIGN_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (err == MZ_OK)
|
||||
{
|
||||
status = CMSDecoderCopyContent(decoder, &message_out);
|
||||
if ((status != errSecSuccess) ||
|
||||
(CFDataGetLength(message_out) != message_size) ||
|
||||
(memcmp(message, CFDataGetBytePtr(message_out), message_size) != 0))
|
||||
err = MZ_SIGN_ERROR;
|
||||
}
|
||||
|
||||
if (trust_policy)
|
||||
CFRelease(trust_policy);
|
||||
if (decoder)
|
||||
CFRelease(decoder);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
+444
@@ -0,0 +1,444 @@
|
||||
/* mz_crypt_brg.c -- Crypto/hash functions using Brian Gladman's library
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
See the accompanying LICENSE file for the full text of the license.
|
||||
*/
|
||||
|
||||
|
||||
#include "mz.h"
|
||||
#include "mz_os.h"
|
||||
|
||||
#if defined(HAVE_GETRANDOM)
|
||||
# include <sys/random.h>
|
||||
#endif
|
||||
#if defined(HAVE_LIBBSD)
|
||||
# include <sys/types.h>
|
||||
# ifndef __u_char_defined
|
||||
typedef unsigned char u_char;
|
||||
# endif
|
||||
# include <bsd/stdlib.h> /* arc4random_buf */
|
||||
#endif
|
||||
|
||||
#include "aes.h"
|
||||
#include "sha1.h"
|
||||
#include "sha2.h"
|
||||
#include "hmac.h"
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#if defined(HAVE_ARC4RANDOM_BUF)
|
||||
int32_t mz_crypt_rand(uint8_t *buf, int32_t size)
|
||||
{
|
||||
if (size < 0)
|
||||
return 0;
|
||||
arc4random_buf(buf, (uint32_t)size);
|
||||
return size;
|
||||
}
|
||||
#elif defined(HAVE_ARC4RANDOM)
|
||||
int32_t mz_crypt_rand(uint8_t *buf, int32_t size)
|
||||
{
|
||||
int32_t left = size;
|
||||
for (; left > 2; left -= 3, buf += 3)
|
||||
{
|
||||
uint32_t val = arc4random();
|
||||
|
||||
buf[0] = (val) & 0xFF;
|
||||
buf[1] = (val >> 8) & 0xFF;
|
||||
buf[2] = (val >> 16) & 0xFF;
|
||||
}
|
||||
for (; left > 0; left--, buf++)
|
||||
{
|
||||
*buf = arc4random() & 0xFF;
|
||||
}
|
||||
return size - left;
|
||||
}
|
||||
#elif defined(HAVE_GETRANDOM)
|
||||
int32_t mz_crypt_rand(uint8_t *buf, int32_t size)
|
||||
{
|
||||
int32_t left = size;
|
||||
int32_t written = 0;
|
||||
|
||||
while (left > 0)
|
||||
{
|
||||
written = getrandom(buf, left, 0);
|
||||
if (written < 0)
|
||||
return MZ_INTERNAL_ERROR;
|
||||
|
||||
buf += written;
|
||||
left -= written;
|
||||
}
|
||||
return size - left;
|
||||
}
|
||||
#else
|
||||
#if !defined(FORCE_LOWQUALITY_ENTROPY)
|
||||
#pragma message("Warning: Low quality entropy function used for encryption")
|
||||
#endif
|
||||
int32_t mz_crypt_rand(uint8_t *buf, int32_t size)
|
||||
{
|
||||
return mz_os_rand(buf, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
typedef struct mz_crypt_sha_s {
|
||||
sha256_ctx ctx256;
|
||||
sha1_ctx ctx1;
|
||||
int32_t initialized;
|
||||
uint16_t algorithm;
|
||||
} mz_crypt_sha;
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void mz_crypt_sha_reset(void *handle)
|
||||
{
|
||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
||||
sha->initialized = 0;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_sha_begin(void *handle)
|
||||
{
|
||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
||||
|
||||
if (sha == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
if (sha->algorithm == MZ_HASH_SHA1)
|
||||
sha1_begin(&sha->ctx1);
|
||||
else
|
||||
sha256_begin(&sha->ctx256);
|
||||
|
||||
sha->initialized = 1;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_sha_update(void *handle, const void *buf, int32_t size)
|
||||
{
|
||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
||||
|
||||
if (sha == NULL || buf == NULL || !sha->initialized)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
if (sha->algorithm == MZ_HASH_SHA1)
|
||||
sha1_hash(buf, size, &sha->ctx1);
|
||||
else
|
||||
sha256_hash(buf, size, &sha->ctx256);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_sha_end(void *handle, uint8_t *digest, int32_t digest_size)
|
||||
{
|
||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
||||
|
||||
if (sha == NULL || digest == NULL || !sha->initialized)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
if (sha->algorithm == MZ_HASH_SHA1)
|
||||
{
|
||||
if (digest_size < MZ_HASH_SHA1_SIZE)
|
||||
return MZ_BUF_ERROR;
|
||||
sha1_end(digest, &sha->ctx1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (digest_size < MZ_HASH_SHA256_SIZE)
|
||||
return MZ_BUF_ERROR;
|
||||
sha256_end(digest, &sha->ctx256);
|
||||
}
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
void mz_crypt_sha_set_algorithm(void *handle, uint16_t algorithm)
|
||||
{
|
||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
||||
sha->algorithm = algorithm;
|
||||
}
|
||||
|
||||
void *mz_crypt_sha_create(void **handle)
|
||||
{
|
||||
mz_crypt_sha *sha = NULL;
|
||||
|
||||
sha = (mz_crypt_sha *)MZ_ALLOC(sizeof(mz_crypt_sha));
|
||||
if (sha != NULL)
|
||||
{
|
||||
memset(sha, 0, sizeof(mz_crypt_sha));
|
||||
sha->algorithm = MZ_HASH_SHA256;
|
||||
}
|
||||
if (handle != NULL)
|
||||
*handle = sha;
|
||||
|
||||
return sha;
|
||||
}
|
||||
|
||||
void mz_crypt_sha_delete(void **handle)
|
||||
{
|
||||
mz_crypt_sha *sha = NULL;
|
||||
if (handle == NULL)
|
||||
return;
|
||||
sha = (mz_crypt_sha *)*handle;
|
||||
if (sha != NULL)
|
||||
{
|
||||
mz_crypt_sha_reset(*handle);
|
||||
MZ_FREE(sha);
|
||||
}
|
||||
*handle = NULL;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
typedef struct mz_crypt_aes_s {
|
||||
aes_encrypt_ctx encrypt_ctx;
|
||||
aes_decrypt_ctx decrypt_ctx;
|
||||
int32_t mode;
|
||||
int32_t error;
|
||||
} mz_crypt_aes;
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void mz_crypt_aes_reset(void *handle)
|
||||
{
|
||||
MZ_UNUSED(handle);
|
||||
}
|
||||
|
||||
int32_t mz_crypt_aes_encrypt(void *handle, uint8_t *buf, int32_t size)
|
||||
{
|
||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
||||
|
||||
if (aes == NULL || buf == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
if (size != MZ_AES_BLOCK_SIZE)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
aes->error = aes_encrypt(buf, buf, &aes->encrypt_ctx);
|
||||
if (aes->error)
|
||||
return MZ_CRYPT_ERROR;
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_aes_decrypt(void *handle, uint8_t *buf, int32_t size)
|
||||
{
|
||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
||||
if (aes == NULL || buf == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
if (size != MZ_AES_BLOCK_SIZE)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
aes->error = aes_decrypt(buf, buf, &aes->decrypt_ctx);
|
||||
if (aes->error)
|
||||
return MZ_CRYPT_ERROR;
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_aes_set_encrypt_key(void *handle, const void *key, int32_t key_length)
|
||||
{
|
||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
||||
|
||||
|
||||
if (aes == NULL || key == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
mz_crypt_aes_reset(handle);
|
||||
|
||||
aes->error = aes_encrypt_key(key, key_length, &aes->encrypt_ctx);
|
||||
if (aes->error)
|
||||
return MZ_HASH_ERROR;
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_aes_set_decrypt_key(void *handle, const void *key, int32_t key_length)
|
||||
{
|
||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
||||
|
||||
|
||||
if (aes == NULL || key == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
mz_crypt_aes_reset(handle);
|
||||
|
||||
aes->error = aes_decrypt_key(key, key_length, &aes->decrypt_ctx);
|
||||
if (aes->error)
|
||||
return MZ_HASH_ERROR;
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
void mz_crypt_aes_set_mode(void *handle, int32_t mode)
|
||||
{
|
||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
||||
aes->mode = mode;
|
||||
}
|
||||
|
||||
void *mz_crypt_aes_create(void **handle)
|
||||
{
|
||||
mz_crypt_aes *aes = NULL;
|
||||
|
||||
aes = (mz_crypt_aes *)MZ_ALLOC(sizeof(mz_crypt_aes));
|
||||
if (aes != NULL)
|
||||
memset(aes, 0, sizeof(mz_crypt_aes));
|
||||
if (handle != NULL)
|
||||
*handle = aes;
|
||||
|
||||
return aes;
|
||||
}
|
||||
|
||||
void mz_crypt_aes_delete(void **handle)
|
||||
{
|
||||
mz_crypt_aes *aes = NULL;
|
||||
if (handle == NULL)
|
||||
return;
|
||||
aes = (mz_crypt_aes *)*handle;
|
||||
if (aes != NULL)
|
||||
MZ_FREE(aes);
|
||||
*handle = NULL;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
typedef struct mz_crypt_hmac_s {
|
||||
hmac_ctx ctx;
|
||||
int32_t initialized;
|
||||
int32_t error;
|
||||
uint16_t algorithm;
|
||||
} mz_crypt_hmac;
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void mz_crypt_hmac_reset(void *handle)
|
||||
{
|
||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
||||
hmac->error = 0;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_hmac_init(void *handle, const void *key, int32_t key_length)
|
||||
{
|
||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
||||
|
||||
if (hmac == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
mz_crypt_hmac_reset(handle);
|
||||
|
||||
if (hmac->algorithm == MZ_HASH_SHA1)
|
||||
hmac_sha_begin(HMAC_SHA1, &hmac->ctx);
|
||||
else
|
||||
hmac_sha_begin(HMAC_SHA256, &hmac->ctx);
|
||||
|
||||
hmac_sha_key(key, key_length, &hmac->ctx);
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_hmac_update(void *handle, const void *buf, int32_t size)
|
||||
{
|
||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
||||
|
||||
if (hmac == NULL || buf == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
hmac_sha_data(buf, size, &hmac->ctx);
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_hmac_end(void *handle, uint8_t *digest, int32_t digest_size)
|
||||
{
|
||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
||||
|
||||
if (hmac == NULL || digest == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
if (hmac->algorithm == MZ_HASH_SHA1)
|
||||
{
|
||||
if (digest_size < MZ_HASH_SHA1_SIZE)
|
||||
return MZ_BUF_ERROR;
|
||||
hmac_sha_end(digest, digest_size, &hmac->ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (digest_size < MZ_HASH_SHA256_SIZE)
|
||||
return MZ_BUF_ERROR;
|
||||
hmac_sha_end(digest, digest_size, &hmac->ctx);
|
||||
}
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
void mz_crypt_hmac_set_algorithm(void *handle, uint16_t algorithm)
|
||||
{
|
||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
||||
hmac->algorithm = algorithm;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_hmac_copy(void *src_handle, void *target_handle)
|
||||
{
|
||||
mz_crypt_hmac *source = (mz_crypt_hmac *)src_handle;
|
||||
mz_crypt_hmac *target = (mz_crypt_hmac *)target_handle;
|
||||
|
||||
if (target == NULL || source == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
memcpy(&target->ctx, &source->ctx, sizeof(hmac_ctx));
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
void *mz_crypt_hmac_create(void **handle)
|
||||
{
|
||||
mz_crypt_hmac *hmac = NULL;
|
||||
|
||||
hmac = (mz_crypt_hmac *)MZ_ALLOC(sizeof(mz_crypt_hmac));
|
||||
if (hmac != NULL)
|
||||
{
|
||||
memset(hmac, 0, sizeof(mz_crypt_hmac));
|
||||
hmac->algorithm = MZ_HASH_SHA256;
|
||||
}
|
||||
if (handle != NULL)
|
||||
*handle = hmac;
|
||||
|
||||
return hmac;
|
||||
}
|
||||
|
||||
void mz_crypt_hmac_delete(void **handle)
|
||||
{
|
||||
mz_crypt_hmac *hmac = NULL;
|
||||
if (handle == NULL)
|
||||
return;
|
||||
hmac = (mz_crypt_hmac *)*handle;
|
||||
if (hmac != NULL)
|
||||
MZ_FREE(hmac);
|
||||
*handle = NULL;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#if defined(MZ_ZIP_SIGNING)
|
||||
int32_t mz_crypt_sign(uint8_t *message, int32_t message_size, uint8_t *cert_data, int32_t cert_data_size,
|
||||
const char *cert_pwd, uint8_t **signature, int32_t *signature_size)
|
||||
{
|
||||
MZ_UNUSED(message);
|
||||
MZ_UNUSED(message_size);
|
||||
MZ_UNUSED(cert_data);
|
||||
MZ_UNUSED(cert_data_size);
|
||||
MZ_UNUSED(cert_pwd);
|
||||
MZ_UNUSED(signature);
|
||||
MZ_UNUSED(signature_size);
|
||||
|
||||
return MZ_SUPPORT_ERROR;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_sign_verify(uint8_t *message, int32_t message_size, uint8_t *signature, int32_t signature_size)
|
||||
{
|
||||
MZ_UNUSED(message);
|
||||
MZ_UNUSED(message_size);
|
||||
MZ_UNUSED(signature);
|
||||
MZ_UNUSED(signature_size);
|
||||
|
||||
return MZ_SUPPORT_ERROR;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,691 @@
|
||||
/* mz_crypt_openssl.c -- Crypto/hash functions for OpenSSL
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
See the accompanying LICENSE file for the full text of the license.
|
||||
*/
|
||||
|
||||
|
||||
#include "mz.h"
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/pkcs12.h>
|
||||
#include <openssl/cms.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void mz_crypt_init(void)
|
||||
{
|
||||
static int32_t openssl_initialized = 0;
|
||||
if (openssl_initialized == 0)
|
||||
{
|
||||
OpenSSL_add_all_algorithms();
|
||||
|
||||
ERR_load_BIO_strings();
|
||||
ERR_load_crypto_strings();
|
||||
|
||||
ENGINE_load_builtin_engines();
|
||||
ENGINE_register_all_complete();
|
||||
|
||||
openssl_initialized = 1;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t mz_crypt_rand(uint8_t *buf, int32_t size)
|
||||
{
|
||||
int32_t result = 0;
|
||||
|
||||
result = RAND_bytes(buf, size);
|
||||
|
||||
if (!result)
|
||||
return MZ_CRYPT_ERROR;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
typedef struct mz_crypt_sha_s {
|
||||
SHA256_CTX ctx256;
|
||||
SHA_CTX ctx1;
|
||||
int32_t initialized;
|
||||
int32_t error;
|
||||
uint16_t algorithm;
|
||||
} mz_crypt_sha;
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void mz_crypt_sha_reset(void *handle)
|
||||
{
|
||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
||||
|
||||
sha->error = 0;
|
||||
sha->initialized = 0;
|
||||
|
||||
mz_crypt_init();
|
||||
}
|
||||
|
||||
int32_t mz_crypt_sha_begin(void *handle)
|
||||
{
|
||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
||||
int32_t result = 0;
|
||||
|
||||
|
||||
if (sha == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
mz_crypt_sha_reset(handle);
|
||||
|
||||
if (sha->algorithm == MZ_HASH_SHA1)
|
||||
result = SHA1_Init(&sha->ctx1);
|
||||
else
|
||||
result = SHA256_Init(&sha->ctx256);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
sha->error = ERR_get_error();
|
||||
return MZ_HASH_ERROR;
|
||||
}
|
||||
|
||||
sha->initialized = 1;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_sha_update(void *handle, const void *buf, int32_t size)
|
||||
{
|
||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
||||
int32_t result = 0;
|
||||
|
||||
if (sha == NULL || buf == NULL || !sha->initialized)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
if (sha->algorithm == MZ_HASH_SHA1)
|
||||
result = SHA1_Update(&sha->ctx1, buf, size);
|
||||
else
|
||||
result = SHA256_Update(&sha->ctx256, buf, size);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
sha->error = ERR_get_error();
|
||||
return MZ_HASH_ERROR;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_sha_end(void *handle, uint8_t *digest, int32_t digest_size)
|
||||
{
|
||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
||||
int32_t result = 0;
|
||||
|
||||
if (sha == NULL || digest == NULL || !sha->initialized)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
if (sha->algorithm == MZ_HASH_SHA1)
|
||||
{
|
||||
if (digest_size < MZ_HASH_SHA1_SIZE)
|
||||
return MZ_BUF_ERROR;
|
||||
result = SHA1_Final(digest, &sha->ctx1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (digest_size < MZ_HASH_SHA256_SIZE)
|
||||
return MZ_BUF_ERROR;
|
||||
result = SHA256_Final(digest, &sha->ctx256);
|
||||
}
|
||||
|
||||
if (!result)
|
||||
{
|
||||
sha->error = ERR_get_error();
|
||||
return MZ_HASH_ERROR;
|
||||
}
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
void mz_crypt_sha_set_algorithm(void *handle, uint16_t algorithm)
|
||||
{
|
||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
||||
sha->algorithm = algorithm;
|
||||
}
|
||||
|
||||
void *mz_crypt_sha_create(void **handle)
|
||||
{
|
||||
mz_crypt_sha *sha = NULL;
|
||||
|
||||
sha = (mz_crypt_sha *)MZ_ALLOC(sizeof(mz_crypt_sha));
|
||||
if (sha != NULL)
|
||||
{
|
||||
memset(sha, 0, sizeof(mz_crypt_sha));
|
||||
sha->algorithm = MZ_HASH_SHA256;
|
||||
}
|
||||
if (handle != NULL)
|
||||
*handle = sha;
|
||||
|
||||
return sha;
|
||||
}
|
||||
|
||||
void mz_crypt_sha_delete(void **handle)
|
||||
{
|
||||
mz_crypt_sha *sha = NULL;
|
||||
if (handle == NULL)
|
||||
return;
|
||||
sha = (mz_crypt_sha *)*handle;
|
||||
if (sha != NULL)
|
||||
{
|
||||
mz_crypt_sha_reset(*handle);
|
||||
MZ_FREE(sha);
|
||||
}
|
||||
*handle = NULL;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
typedef struct mz_crypt_aes_s {
|
||||
AES_KEY key;
|
||||
int32_t mode;
|
||||
int32_t error;
|
||||
uint8_t *key_copy;
|
||||
int32_t key_length;
|
||||
} mz_crypt_aes;
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void mz_crypt_aes_reset(void *handle)
|
||||
{
|
||||
MZ_UNUSED(handle);
|
||||
|
||||
mz_crypt_init();
|
||||
}
|
||||
|
||||
int32_t mz_crypt_aes_encrypt(void *handle, uint8_t *buf, int32_t size)
|
||||
{
|
||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
||||
|
||||
if (aes == NULL || buf == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
if (size != MZ_AES_BLOCK_SIZE)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
AES_encrypt(buf, buf, &aes->key);
|
||||
/* Equivalent to AES_ecb_encrypt with AES_ENCRYPT */
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_aes_decrypt(void *handle, uint8_t *buf, int32_t size)
|
||||
{
|
||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
||||
if (aes == NULL || buf == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
if (size != MZ_AES_BLOCK_SIZE)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
AES_decrypt(buf, buf, &aes->key);
|
||||
/* Equivalent to AES_ecb_encrypt with AES_DECRYPT */
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_aes_set_encrypt_key(void *handle, const void *key, int32_t key_length)
|
||||
{
|
||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
||||
int32_t result = 0;
|
||||
int32_t key_bits = 0;
|
||||
|
||||
|
||||
if (aes == NULL || key == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
mz_crypt_aes_reset(handle);
|
||||
|
||||
key_bits = key_length * 8;
|
||||
result = AES_set_encrypt_key(key, key_bits, &aes->key);
|
||||
if (result)
|
||||
{
|
||||
aes->error = ERR_get_error();
|
||||
return MZ_HASH_ERROR;
|
||||
}
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_aes_set_decrypt_key(void *handle, const void *key, int32_t key_length)
|
||||
{
|
||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
||||
int32_t result = 0;
|
||||
int32_t key_bits = 0;
|
||||
|
||||
|
||||
if (aes == NULL || key == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
mz_crypt_aes_reset(handle);
|
||||
|
||||
key_bits = key_length * 8;
|
||||
result = AES_set_decrypt_key(key, key_bits, &aes->key);
|
||||
if (result)
|
||||
{
|
||||
aes->error = ERR_get_error();
|
||||
return MZ_HASH_ERROR;
|
||||
}
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
void mz_crypt_aes_set_mode(void *handle, int32_t mode)
|
||||
{
|
||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
||||
aes->mode = mode;
|
||||
}
|
||||
|
||||
void *mz_crypt_aes_create(void **handle)
|
||||
{
|
||||
mz_crypt_aes *aes = NULL;
|
||||
|
||||
aes = (mz_crypt_aes *)MZ_ALLOC(sizeof(mz_crypt_aes));
|
||||
if (aes != NULL)
|
||||
memset(aes, 0, sizeof(mz_crypt_aes));
|
||||
if (handle != NULL)
|
||||
*handle = aes;
|
||||
|
||||
return aes;
|
||||
}
|
||||
|
||||
void mz_crypt_aes_delete(void **handle)
|
||||
{
|
||||
mz_crypt_aes *aes = NULL;
|
||||
if (handle == NULL)
|
||||
return;
|
||||
aes = (mz_crypt_aes *)*handle;
|
||||
if (aes != NULL)
|
||||
MZ_FREE(aes);
|
||||
*handle = NULL;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
typedef struct mz_crypt_hmac_s {
|
||||
HMAC_CTX *ctx;
|
||||
int32_t initialized;
|
||||
int32_t error;
|
||||
uint16_t algorithm;
|
||||
} mz_crypt_hmac;
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
|
||||
static HMAC_CTX *HMAC_CTX_new(void)
|
||||
{
|
||||
HMAC_CTX *ctx = OPENSSL_malloc(sizeof(HMAC_CTX));
|
||||
if (ctx != NULL)
|
||||
HMAC_CTX_init(ctx);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static void HMAC_CTX_free(HMAC_CTX *ctx)
|
||||
{
|
||||
if (ctx != NULL)
|
||||
{
|
||||
HMAC_CTX_cleanup(ctx);
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void mz_crypt_hmac_reset(void *handle)
|
||||
{
|
||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
||||
|
||||
HMAC_CTX_free(hmac->ctx);
|
||||
|
||||
hmac->ctx = NULL;
|
||||
hmac->error = 0;
|
||||
|
||||
mz_crypt_init();
|
||||
}
|
||||
|
||||
int32_t mz_crypt_hmac_init(void *handle, const void *key, int32_t key_length)
|
||||
{
|
||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
||||
int32_t result = 0;
|
||||
const EVP_MD *evp_md = NULL;
|
||||
|
||||
if (hmac == NULL || key == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
mz_crypt_hmac_reset(handle);
|
||||
|
||||
hmac->ctx = HMAC_CTX_new();
|
||||
|
||||
if (hmac->algorithm == MZ_HASH_SHA1)
|
||||
evp_md = EVP_sha1();
|
||||
else
|
||||
evp_md = EVP_sha256();
|
||||
|
||||
result = HMAC_Init_ex(hmac->ctx, key, key_length, evp_md, NULL);
|
||||
if (!result)
|
||||
{
|
||||
hmac->error = ERR_get_error();
|
||||
return MZ_HASH_ERROR;
|
||||
}
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_hmac_update(void *handle, const void *buf, int32_t size)
|
||||
{
|
||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
||||
int32_t result = 0;
|
||||
|
||||
if (hmac == NULL || buf == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
result = HMAC_Update(hmac->ctx, buf, size);
|
||||
if (!result)
|
||||
{
|
||||
hmac->error = ERR_get_error();
|
||||
return MZ_HASH_ERROR;
|
||||
}
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_hmac_end(void *handle, uint8_t *digest, int32_t digest_size)
|
||||
{
|
||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
||||
int32_t result = 0;
|
||||
|
||||
if (hmac == NULL || digest == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
if (hmac->algorithm == MZ_HASH_SHA1)
|
||||
{
|
||||
if (digest_size < MZ_HASH_SHA1_SIZE)
|
||||
return MZ_BUF_ERROR;
|
||||
|
||||
result = HMAC_Final(hmac->ctx, digest, (uint32_t *)&digest_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (digest_size < MZ_HASH_SHA256_SIZE)
|
||||
return MZ_BUF_ERROR;
|
||||
result = HMAC_Final(hmac->ctx, digest, (uint32_t *)&digest_size);
|
||||
}
|
||||
|
||||
if (!result)
|
||||
{
|
||||
hmac->error = ERR_get_error();
|
||||
return MZ_HASH_ERROR;
|
||||
}
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
void mz_crypt_hmac_set_algorithm(void *handle, uint16_t algorithm)
|
||||
{
|
||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
||||
hmac->algorithm = algorithm;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_hmac_copy(void *src_handle, void *target_handle)
|
||||
{
|
||||
mz_crypt_hmac *source = (mz_crypt_hmac *)src_handle;
|
||||
mz_crypt_hmac *target = (mz_crypt_hmac *)target_handle;
|
||||
int32_t result = 0;
|
||||
|
||||
if (source == NULL || target == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
mz_crypt_hmac_reset(target_handle);
|
||||
|
||||
if (target->ctx == NULL)
|
||||
target->ctx = HMAC_CTX_new();
|
||||
|
||||
result = HMAC_CTX_copy(target->ctx, source->ctx);
|
||||
if (!result)
|
||||
{
|
||||
target->error = ERR_get_error();
|
||||
return MZ_HASH_ERROR;
|
||||
}
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
void *mz_crypt_hmac_create(void **handle)
|
||||
{
|
||||
mz_crypt_hmac *hmac = NULL;
|
||||
|
||||
hmac = (mz_crypt_hmac *)MZ_ALLOC(sizeof(mz_crypt_hmac));
|
||||
if (hmac != NULL)
|
||||
{
|
||||
memset(hmac, 0, sizeof(mz_crypt_hmac));
|
||||
hmac->algorithm = MZ_HASH_SHA256;
|
||||
}
|
||||
if (handle != NULL)
|
||||
*handle = hmac;
|
||||
|
||||
return hmac;
|
||||
}
|
||||
|
||||
void mz_crypt_hmac_delete(void **handle)
|
||||
{
|
||||
mz_crypt_hmac *hmac = NULL;
|
||||
if (handle == NULL)
|
||||
return;
|
||||
hmac = (mz_crypt_hmac *)*handle;
|
||||
if (hmac != NULL)
|
||||
{
|
||||
mz_crypt_hmac_reset(*handle);
|
||||
MZ_FREE(hmac);
|
||||
}
|
||||
*handle = NULL;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#if defined(MZ_ZIP_SIGNING)
|
||||
int32_t mz_crypt_sign(uint8_t *message, int32_t message_size, uint8_t *cert_data, int32_t cert_data_size,
|
||||
const char *cert_pwd, uint8_t **signature, int32_t *signature_size)
|
||||
{
|
||||
PKCS12 *p12 = NULL;
|
||||
EVP_PKEY *evp_pkey = NULL;
|
||||
BUF_MEM *buf_mem = NULL;
|
||||
BIO *cert_bio = NULL;
|
||||
BIO *message_bio = NULL;
|
||||
BIO *signature_bio = NULL;
|
||||
CMS_ContentInfo *cms = NULL;
|
||||
CMS_SignerInfo *signer_info = NULL;
|
||||
STACK_OF(X509) *ca_stack = NULL;
|
||||
X509 *cert = NULL;
|
||||
int32_t result = 0;
|
||||
int32_t err = MZ_OK;
|
||||
|
||||
|
||||
if (message == NULL || cert_data == NULL || signature == NULL || signature_size == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
mz_crypt_init();
|
||||
|
||||
*signature = NULL;
|
||||
*signature_size = 0;
|
||||
|
||||
cert_bio = BIO_new_mem_buf(cert_data, cert_data_size);
|
||||
|
||||
if (d2i_PKCS12_bio(cert_bio, &p12) == NULL)
|
||||
err = MZ_SIGN_ERROR;
|
||||
if (err == MZ_OK)
|
||||
result = PKCS12_parse(p12, cert_pwd, &evp_pkey, &cert, &ca_stack);
|
||||
if (result)
|
||||
{
|
||||
cms = CMS_sign(NULL, NULL, ca_stack, NULL, CMS_BINARY | CMS_PARTIAL);
|
||||
if (cms)
|
||||
signer_info = CMS_add1_signer(cms, cert, evp_pkey, EVP_sha256(), 0);
|
||||
if (signer_info == NULL)
|
||||
{
|
||||
err = MZ_SIGN_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
message_bio = BIO_new_mem_buf(message, message_size);
|
||||
signature_bio = BIO_new(BIO_s_mem());
|
||||
|
||||
result = CMS_final(cms, message_bio, NULL, CMS_BINARY);
|
||||
if (result)
|
||||
result = i2d_CMS_bio(signature_bio, cms);
|
||||
if (result)
|
||||
{
|
||||
BIO_flush(signature_bio);
|
||||
BIO_get_mem_ptr(signature_bio, &buf_mem);
|
||||
|
||||
*signature_size = buf_mem->length;
|
||||
*signature = MZ_ALLOC(buf_mem->length);
|
||||
|
||||
memcpy(*signature, buf_mem->data, buf_mem->length);
|
||||
}
|
||||
#if 0
|
||||
BIO *yy = BIO_new_file("xyz", "wb");
|
||||
BIO_write(yy, *signature, *signature_size);
|
||||
BIO_flush(yy);
|
||||
BIO_free(yy);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (!result)
|
||||
err = MZ_SIGN_ERROR;
|
||||
|
||||
if (cms)
|
||||
CMS_ContentInfo_free(cms);
|
||||
if (signature_bio)
|
||||
BIO_free(signature_bio);
|
||||
if (cert_bio)
|
||||
BIO_free(cert_bio);
|
||||
if (message_bio)
|
||||
BIO_free(message_bio);
|
||||
if (p12)
|
||||
PKCS12_free(p12);
|
||||
|
||||
if (err != MZ_OK && *signature != NULL)
|
||||
{
|
||||
MZ_FREE(*signature);
|
||||
*signature = NULL;
|
||||
*signature_size = 0;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_sign_verify(uint8_t *message, int32_t message_size, uint8_t *signature, int32_t signature_size)
|
||||
{
|
||||
CMS_ContentInfo *cms = NULL;
|
||||
STACK_OF(X509) *signers = NULL;
|
||||
STACK_OF(X509) *intercerts = NULL;
|
||||
X509_STORE *cert_store = NULL;
|
||||
X509_LOOKUP *lookup = NULL;
|
||||
X509_STORE_CTX *store_ctx = NULL;
|
||||
BIO *message_bio = NULL;
|
||||
BIO *signature_bio = NULL;
|
||||
BUF_MEM *buf_mem = NULL;
|
||||
int32_t signer_count = 0;
|
||||
int32_t result = 0;
|
||||
int32_t i = 0;
|
||||
int32_t err = MZ_SIGN_ERROR;
|
||||
|
||||
|
||||
if (message == NULL || message_size == 0 || signature == NULL || signature_size == 0)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
mz_crypt_init();
|
||||
|
||||
cert_store = X509_STORE_new();
|
||||
|
||||
X509_STORE_load_locations(cert_store, "cacert.pem", NULL);
|
||||
X509_STORE_set_default_paths(cert_store);
|
||||
|
||||
#if 0
|
||||
BIO *yy = BIO_new_file("xyz", "wb");
|
||||
BIO_write(yy, signature, signature_size);
|
||||
BIO_flush(yy);
|
||||
BIO_free(yy);
|
||||
#endif
|
||||
|
||||
lookup = X509_STORE_add_lookup(cert_store, X509_LOOKUP_file());
|
||||
if (lookup != NULL)
|
||||
X509_LOOKUP_load_file(lookup, "cacert.pem", X509_FILETYPE_PEM);
|
||||
lookup = X509_STORE_add_lookup(cert_store, X509_LOOKUP_hash_dir());
|
||||
if (lookup != NULL)
|
||||
X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
|
||||
|
||||
signature_bio = BIO_new_mem_buf(signature, signature_size);
|
||||
message_bio = BIO_new(BIO_s_mem());
|
||||
|
||||
cms = d2i_CMS_bio(signature_bio, NULL);
|
||||
if (cms)
|
||||
{
|
||||
result = CMS_verify(cms, NULL, cert_store, NULL, message_bio, CMS_NO_SIGNER_CERT_VERIFY | CMS_BINARY);
|
||||
if (result)
|
||||
signers = CMS_get0_signers(cms);
|
||||
if (signers)
|
||||
intercerts = CMS_get1_certs(cms);
|
||||
if (intercerts)
|
||||
{
|
||||
/* Verify signer certificates */
|
||||
signer_count = sk_X509_num(signers);
|
||||
if (signer_count > 0)
|
||||
err = MZ_OK;
|
||||
|
||||
for (i = 0; i < signer_count; i++)
|
||||
{
|
||||
store_ctx = X509_STORE_CTX_new();
|
||||
X509_STORE_CTX_init(store_ctx, cert_store, sk_X509_value(signers, i), intercerts);
|
||||
result = X509_verify_cert(store_ctx);
|
||||
if (store_ctx)
|
||||
X509_STORE_CTX_free(store_ctx);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
err = MZ_SIGN_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BIO_get_mem_ptr(message_bio, &buf_mem);
|
||||
|
||||
if (err == MZ_OK)
|
||||
{
|
||||
/* Verify the message */
|
||||
if (((int32_t)buf_mem->length != message_size) ||
|
||||
(memcmp(buf_mem->data, message, message_size) != 0))
|
||||
err = MZ_SIGN_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!result)
|
||||
printf(ERR_error_string(ERR_get_error(), NULL));
|
||||
#endif
|
||||
|
||||
if (cms)
|
||||
CMS_ContentInfo_free(cms);
|
||||
if (message_bio)
|
||||
BIO_free(message_bio);
|
||||
if (signature_bio)
|
||||
BIO_free(signature_bio);
|
||||
if (cert_store)
|
||||
X509_STORE_free(cert_store);
|
||||
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,804 @@
|
||||
/* mz_crypt_win32.c -- Crypto/hash functions for Windows
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
See the accompanying LICENSE file for the full text of the license.
|
||||
*/
|
||||
|
||||
#pragma comment(lib, "crypt32.lib")
|
||||
|
||||
#include "mz.h"
|
||||
#include "mz_os.h"
|
||||
#include "mz_crypt.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t mz_crypt_rand(uint8_t *buf, int32_t size)
|
||||
{
|
||||
HCRYPTPROV provider;
|
||||
int32_t result = 0;
|
||||
|
||||
|
||||
result = CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
|
||||
if (result)
|
||||
{
|
||||
result = CryptGenRandom(provider, size, buf);
|
||||
CryptReleaseContext(provider, 0);
|
||||
if (result)
|
||||
return size;
|
||||
}
|
||||
|
||||
return mz_os_rand(buf, size);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
typedef struct mz_crypt_sha_s {
|
||||
HCRYPTPROV provider;
|
||||
HCRYPTHASH hash;
|
||||
int32_t error;
|
||||
uint16_t algorithm;
|
||||
} mz_crypt_sha;
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void mz_crypt_sha_reset(void *handle)
|
||||
{
|
||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
||||
if (sha->hash)
|
||||
CryptDestroyHash(sha->hash);
|
||||
sha->hash = 0;
|
||||
if (sha->provider)
|
||||
CryptReleaseContext(sha->provider, 0);
|
||||
sha->provider = 0;
|
||||
sha->error = 0;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_sha_begin(void *handle)
|
||||
{
|
||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
||||
ALG_ID alg_id = 0;
|
||||
int32_t result = 0;
|
||||
int32_t err = MZ_OK;
|
||||
|
||||
|
||||
if (sha == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
if (sha->algorithm == MZ_HASH_SHA1)
|
||||
alg_id = CALG_SHA1;
|
||||
else
|
||||
alg_id = CALG_SHA_256;
|
||||
|
||||
result = CryptAcquireContext(&sha->provider, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
|
||||
if (!result)
|
||||
{
|
||||
sha->error = GetLastError();
|
||||
err = MZ_CRYPT_ERROR;
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
result = CryptCreateHash(sha->provider, alg_id, 0, 0, &sha->hash);
|
||||
if (!result)
|
||||
{
|
||||
sha->error = GetLastError();
|
||||
err = MZ_HASH_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_sha_update(void *handle, const void *buf, int32_t size)
|
||||
{
|
||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
||||
int32_t result = 0;
|
||||
|
||||
if (sha == NULL || buf == NULL || sha->hash == 0)
|
||||
return MZ_PARAM_ERROR;
|
||||
result = CryptHashData(sha->hash, buf, size, 0);
|
||||
if (!result)
|
||||
{
|
||||
sha->error = GetLastError();
|
||||
return MZ_HASH_ERROR;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_sha_end(void *handle, uint8_t *digest, int32_t digest_size)
|
||||
{
|
||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
||||
int32_t result = 0;
|
||||
int32_t expected_size = 0;
|
||||
|
||||
if (sha == NULL || digest == NULL || sha->hash == 0)
|
||||
return MZ_PARAM_ERROR;
|
||||
result = CryptGetHashParam(sha->hash, HP_HASHVAL, NULL, &expected_size, 0);
|
||||
if (expected_size > digest_size)
|
||||
return MZ_BUF_ERROR;
|
||||
if (!result)
|
||||
return MZ_HASH_ERROR;
|
||||
result = CryptGetHashParam(sha->hash, HP_HASHVAL, digest, &digest_size, 0);
|
||||
if (!result)
|
||||
{
|
||||
sha->error = GetLastError();
|
||||
return MZ_HASH_ERROR;
|
||||
}
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
void mz_crypt_sha_set_algorithm(void *handle, uint16_t algorithm)
|
||||
{
|
||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
||||
sha->algorithm = algorithm;
|
||||
}
|
||||
|
||||
void *mz_crypt_sha_create(void **handle)
|
||||
{
|
||||
mz_crypt_sha *sha = NULL;
|
||||
|
||||
sha = (mz_crypt_sha *)MZ_ALLOC(sizeof(mz_crypt_sha));
|
||||
if (sha != NULL)
|
||||
{
|
||||
memset(sha, 0, sizeof(mz_crypt_sha));
|
||||
sha->algorithm = MZ_HASH_SHA256;
|
||||
}
|
||||
if (handle != NULL)
|
||||
*handle = sha;
|
||||
|
||||
return sha;
|
||||
}
|
||||
|
||||
void mz_crypt_sha_delete(void **handle)
|
||||
{
|
||||
mz_crypt_sha *sha = NULL;
|
||||
if (handle == NULL)
|
||||
return;
|
||||
sha = (mz_crypt_sha *)*handle;
|
||||
if (sha != NULL)
|
||||
{
|
||||
mz_crypt_sha_reset(*handle);
|
||||
MZ_FREE(sha);
|
||||
}
|
||||
*handle = NULL;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
typedef struct mz_crypt_aes_s {
|
||||
HCRYPTPROV provider;
|
||||
HCRYPTKEY key;
|
||||
int32_t mode;
|
||||
int32_t error;
|
||||
} mz_crypt_aes;
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void mz_crypt_aes_free(void *handle)
|
||||
{
|
||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
||||
if (aes->key)
|
||||
CryptDestroyKey(aes->key);
|
||||
aes->key = 0;
|
||||
if (aes->provider)
|
||||
CryptReleaseContext(aes->provider, 0);
|
||||
aes->provider = 0;
|
||||
}
|
||||
|
||||
void mz_crypt_aes_reset(void *handle)
|
||||
{
|
||||
mz_crypt_aes_free(handle);
|
||||
}
|
||||
|
||||
int32_t mz_crypt_aes_encrypt(void *handle, uint8_t *buf, int32_t size)
|
||||
{
|
||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
||||
int32_t result = 0;
|
||||
|
||||
if (aes == NULL || buf == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
if (size != MZ_AES_BLOCK_SIZE)
|
||||
return MZ_PARAM_ERROR;
|
||||
result = CryptEncrypt(aes->key, 0, 0, 0, buf, &size, size);
|
||||
if (!result)
|
||||
{
|
||||
aes->error = GetLastError();
|
||||
return MZ_CRYPT_ERROR;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_aes_decrypt(void *handle, uint8_t *buf, int32_t size)
|
||||
{
|
||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
||||
int32_t result = 0;
|
||||
if (aes == NULL || buf == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
if (size != MZ_AES_BLOCK_SIZE)
|
||||
return MZ_PARAM_ERROR;
|
||||
result = CryptDecrypt(aes->key, 0, 0, 0, buf, &size);
|
||||
if (!result)
|
||||
{
|
||||
aes->error = GetLastError();
|
||||
return MZ_CRYPT_ERROR;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
static int32_t mz_crypt_aes_set_key(void *handle, const void *key, int32_t key_length)
|
||||
{
|
||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
||||
HCRYPTHASH hash = 0;
|
||||
ALG_ID alg_id = 0;
|
||||
typedef struct key_blob_header_s {
|
||||
BLOBHEADER hdr;
|
||||
uint32_t key_length;
|
||||
} key_blob_header_s;
|
||||
key_blob_header_s *key_blob_s = NULL;
|
||||
uint32_t mode = CRYPT_MODE_ECB;
|
||||
uint8_t *key_blob = NULL;
|
||||
int32_t key_blob_size = 0;
|
||||
int32_t result = 0;
|
||||
int32_t err = MZ_OK;
|
||||
|
||||
|
||||
if (aes == NULL || key == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
mz_crypt_aes_reset(handle);
|
||||
|
||||
if (key_length == MZ_AES_KEY_LENGTH(MZ_AES_ENCRYPTION_MODE_128))
|
||||
alg_id = CALG_AES_128;
|
||||
else if (key_length == MZ_AES_KEY_LENGTH(MZ_AES_ENCRYPTION_MODE_192))
|
||||
alg_id = CALG_AES_192;
|
||||
else if (key_length == MZ_AES_KEY_LENGTH(MZ_AES_ENCRYPTION_MODE_256))
|
||||
alg_id = CALG_AES_256;
|
||||
else
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
result = CryptAcquireContext(&aes->provider, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
|
||||
if (result)
|
||||
{
|
||||
key_blob_size = sizeof(key_blob_header_s) + key_length;
|
||||
key_blob = (uint8_t *)MZ_ALLOC(key_blob_size);
|
||||
if (key_blob)
|
||||
{
|
||||
key_blob_s = (key_blob_header_s *)key_blob;
|
||||
key_blob_s->hdr.bType = PLAINTEXTKEYBLOB;
|
||||
key_blob_s->hdr.bVersion = CUR_BLOB_VERSION;
|
||||
key_blob_s->hdr.aiKeyAlg = alg_id;
|
||||
key_blob_s->hdr.reserved = 0;
|
||||
key_blob_s->key_length = key_length;
|
||||
|
||||
memcpy(key_blob + sizeof(key_blob_header_s), key, key_length);
|
||||
|
||||
result = CryptImportKey(aes->provider, key_blob, key_blob_size, 0, 0, &aes->key);
|
||||
|
||||
MZ_FREE(key_blob);
|
||||
}
|
||||
else
|
||||
{
|
||||
err = MZ_MEM_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (result && err == MZ_OK)
|
||||
result = CryptSetKeyParam(aes->key, KP_MODE, (const uint8_t *)&mode, 0);
|
||||
|
||||
if (!result && err == MZ_OK)
|
||||
{
|
||||
aes->error = GetLastError();
|
||||
err = MZ_CRYPT_ERROR;
|
||||
}
|
||||
|
||||
if (hash)
|
||||
CryptDestroyHash(hash);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_aes_set_encrypt_key(void *handle, const void *key, int32_t key_length)
|
||||
{
|
||||
return mz_crypt_aes_set_key(handle, key, key_length);
|
||||
}
|
||||
|
||||
int32_t mz_crypt_aes_set_decrypt_key(void *handle, const void *key, int32_t key_length)
|
||||
{
|
||||
return mz_crypt_aes_set_key(handle, key, key_length);
|
||||
}
|
||||
|
||||
void mz_crypt_aes_set_mode(void *handle, int32_t mode)
|
||||
{
|
||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
||||
aes->mode = mode;
|
||||
}
|
||||
|
||||
void *mz_crypt_aes_create(void **handle)
|
||||
{
|
||||
mz_crypt_aes *aes = NULL;
|
||||
|
||||
aes = (mz_crypt_aes *)MZ_ALLOC(sizeof(mz_crypt_aes));
|
||||
if (aes != NULL)
|
||||
memset(aes, 0, sizeof(mz_crypt_aes));
|
||||
if (handle != NULL)
|
||||
*handle = aes;
|
||||
|
||||
return aes;
|
||||
}
|
||||
|
||||
void mz_crypt_aes_delete(void **handle)
|
||||
{
|
||||
mz_crypt_aes *aes = NULL;
|
||||
if (handle == NULL)
|
||||
return;
|
||||
aes = (mz_crypt_aes *)*handle;
|
||||
if (aes != NULL)
|
||||
{
|
||||
mz_crypt_aes_free(*handle);
|
||||
MZ_FREE(aes);
|
||||
}
|
||||
*handle = NULL;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
typedef struct mz_crypt_hmac_s {
|
||||
HCRYPTPROV provider;
|
||||
HCRYPTHASH hash;
|
||||
HCRYPTKEY key;
|
||||
HMAC_INFO info;
|
||||
int32_t mode;
|
||||
int32_t error;
|
||||
uint16_t algorithm;
|
||||
} mz_crypt_hmac;
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void mz_crypt_hmac_free(void *handle)
|
||||
{
|
||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
||||
if (hmac->key)
|
||||
CryptDestroyKey(hmac->key);
|
||||
hmac->key = 0;
|
||||
if (hmac->hash)
|
||||
CryptDestroyHash(hmac->hash);
|
||||
hmac->hash = 0;
|
||||
if (hmac->provider)
|
||||
CryptReleaseContext(hmac->provider, 0);
|
||||
hmac->provider = 0;
|
||||
memset(&hmac->info, 0, sizeof(hmac->info));
|
||||
}
|
||||
|
||||
void mz_crypt_hmac_reset(void *handle)
|
||||
{
|
||||
mz_crypt_hmac_free(handle);
|
||||
}
|
||||
|
||||
int32_t mz_crypt_hmac_init(void *handle, const void *key, int32_t key_length)
|
||||
{
|
||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
||||
ALG_ID alg_id = 0;
|
||||
typedef struct key_blob_header_s {
|
||||
BLOBHEADER hdr;
|
||||
uint32_t key_length;
|
||||
} key_blob_header_s;
|
||||
key_blob_header_s *key_blob_s = NULL;
|
||||
uint8_t *key_blob = NULL;
|
||||
int32_t key_blob_size = 0;
|
||||
int32_t result = 0;
|
||||
int32_t err = MZ_OK;
|
||||
|
||||
|
||||
if (hmac == NULL || key == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
mz_crypt_hmac_reset(handle);
|
||||
|
||||
if (hmac->algorithm == MZ_HASH_SHA1)
|
||||
alg_id = CALG_SHA1;
|
||||
else
|
||||
alg_id = CALG_SHA_256;
|
||||
|
||||
hmac->info.HashAlgid = alg_id;
|
||||
|
||||
result = CryptAcquireContext(&hmac->provider, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
hmac->error = GetLastError();
|
||||
err = MZ_CRYPT_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
key_blob_size = sizeof(key_blob_header_s) + key_length;
|
||||
key_blob = (uint8_t *)MZ_ALLOC(key_blob_size);
|
||||
}
|
||||
|
||||
if (key_blob)
|
||||
{
|
||||
key_blob_s = (key_blob_header_s *)key_blob;
|
||||
key_blob_s->hdr.bType = PLAINTEXTKEYBLOB;
|
||||
key_blob_s->hdr.bVersion = CUR_BLOB_VERSION;
|
||||
key_blob_s->hdr.aiKeyAlg = CALG_RC2;
|
||||
key_blob_s->hdr.reserved = 0;
|
||||
key_blob_s->key_length = key_length;
|
||||
|
||||
memcpy(key_blob + sizeof(key_blob_header_s), key, key_length);
|
||||
|
||||
result = CryptImportKey(hmac->provider, key_blob, key_blob_size, 0, CRYPT_IPSEC_HMAC_KEY, &hmac->key);
|
||||
if (result)
|
||||
result = CryptCreateHash(hmac->provider, CALG_HMAC, hmac->key, 0, &hmac->hash);
|
||||
if (result)
|
||||
result = CryptSetHashParam(hmac->hash, HP_HMAC_INFO, (uint8_t *)&hmac->info, 0);
|
||||
|
||||
MZ_FREE(key_blob);
|
||||
}
|
||||
else if (err == MZ_OK)
|
||||
{
|
||||
err = MZ_MEM_ERROR;
|
||||
}
|
||||
|
||||
if (!result)
|
||||
{
|
||||
hmac->error = GetLastError();
|
||||
err = MZ_CRYPT_ERROR;
|
||||
}
|
||||
|
||||
if (err != MZ_OK)
|
||||
mz_crypt_hmac_free(handle);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_hmac_update(void *handle, const void *buf, int32_t size)
|
||||
{
|
||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
||||
int32_t result = 0;
|
||||
|
||||
if (hmac == NULL || buf == NULL || hmac->hash == 0)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
result = CryptHashData(hmac->hash, buf, size, 0);
|
||||
if (!result)
|
||||
{
|
||||
hmac->error = GetLastError();
|
||||
return MZ_HASH_ERROR;
|
||||
}
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_hmac_end(void *handle, uint8_t *digest, int32_t digest_size)
|
||||
{
|
||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
||||
int32_t result = 0;
|
||||
int32_t expected_size = 0;
|
||||
|
||||
if (hmac == NULL || digest == NULL || hmac->hash == 0)
|
||||
return MZ_PARAM_ERROR;
|
||||
result = CryptGetHashParam(hmac->hash, HP_HASHVAL, NULL, &expected_size, 0);
|
||||
if (expected_size > digest_size)
|
||||
return MZ_BUF_ERROR;
|
||||
if (!result)
|
||||
return MZ_HASH_ERROR;
|
||||
result = CryptGetHashParam(hmac->hash, HP_HASHVAL, digest, &digest_size, 0);
|
||||
if (!result)
|
||||
{
|
||||
hmac->error = GetLastError();
|
||||
return MZ_HASH_ERROR;
|
||||
}
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
void mz_crypt_hmac_set_algorithm(void *handle, uint16_t algorithm)
|
||||
{
|
||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
||||
hmac->algorithm = algorithm;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_hmac_copy(void *src_handle, void *target_handle)
|
||||
{
|
||||
mz_crypt_hmac *source = (mz_crypt_hmac *)src_handle;
|
||||
mz_crypt_hmac *target = (mz_crypt_hmac *)target_handle;
|
||||
int32_t result = 0;
|
||||
int32_t err = MZ_OK;
|
||||
|
||||
if (target->hash)
|
||||
{
|
||||
CryptDestroyHash(target->hash);
|
||||
target->hash = 0;
|
||||
}
|
||||
|
||||
result = CryptDuplicateHash(source->hash, NULL, 0, &target->hash);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
target->error = GetLastError();
|
||||
err = MZ_HASH_ERROR;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
void *mz_crypt_hmac_create(void **handle)
|
||||
{
|
||||
mz_crypt_hmac *hmac = NULL;
|
||||
|
||||
hmac = (mz_crypt_hmac *)MZ_ALLOC(sizeof(mz_crypt_hmac));
|
||||
if (hmac != NULL)
|
||||
{
|
||||
memset(hmac, 0, sizeof(mz_crypt_hmac));
|
||||
hmac->algorithm = MZ_HASH_SHA256;
|
||||
}
|
||||
if (handle != NULL)
|
||||
*handle = hmac;
|
||||
|
||||
return hmac;
|
||||
}
|
||||
|
||||
void mz_crypt_hmac_delete(void **handle)
|
||||
{
|
||||
mz_crypt_hmac *hmac = NULL;
|
||||
if (handle == NULL)
|
||||
return;
|
||||
hmac = (mz_crypt_hmac *)*handle;
|
||||
if (hmac != NULL)
|
||||
{
|
||||
mz_crypt_hmac_free(*handle);
|
||||
MZ_FREE(hmac);
|
||||
}
|
||||
*handle = NULL;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#if defined(MZ_ZIP_SIGNING)
|
||||
int32_t mz_crypt_sign(uint8_t *message, int32_t message_size, uint8_t *cert_data, int32_t cert_data_size,
|
||||
const char *cert_pwd, uint8_t **signature, int32_t *signature_size)
|
||||
{
|
||||
CRYPT_SIGN_MESSAGE_PARA sign_params;
|
||||
CRYPT_DATA_BLOB cert_data_blob;
|
||||
PCCERT_CONTEXT cert_context = NULL;
|
||||
HCERTSTORE cert_store = 0;
|
||||
wchar_t *password_wide = NULL;
|
||||
int32_t result = 0;
|
||||
int32_t err = MZ_OK;
|
||||
uint32_t messages_sizes[1];
|
||||
uint8_t *messages[1];
|
||||
|
||||
|
||||
if (message == NULL || cert_data == NULL || signature == NULL || signature_size == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
*signature = NULL;
|
||||
*signature_size = 0;
|
||||
|
||||
cert_data_blob.pbData = cert_data;
|
||||
cert_data_blob.cbData = cert_data_size;
|
||||
|
||||
password_wide = mz_os_unicode_string_create(cert_pwd, MZ_ENCODING_UTF8);
|
||||
if (password_wide)
|
||||
{
|
||||
cert_store = PFXImportCertStore(&cert_data_blob, password_wide, 0);
|
||||
mz_os_unicode_string_delete(&password_wide);
|
||||
}
|
||||
|
||||
if (cert_store == NULL)
|
||||
cert_store = PFXImportCertStore(&cert_data_blob, L"", 0);
|
||||
if (cert_store == NULL)
|
||||
cert_store = PFXImportCertStore(&cert_data_blob, NULL, 0);
|
||||
if (cert_store == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
if (err == MZ_OK)
|
||||
{
|
||||
cert_context = CertFindCertificateInStore(cert_store,
|
||||
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_HAS_PRIVATE_KEY, NULL, NULL);
|
||||
if (cert_context == NULL)
|
||||
err = MZ_PARAM_ERROR;
|
||||
}
|
||||
if (err == MZ_OK)
|
||||
{
|
||||
memset(&sign_params, 0, sizeof(sign_params));
|
||||
|
||||
sign_params.cbSize = sizeof(sign_params);
|
||||
sign_params.dwMsgEncodingType = PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;
|
||||
sign_params.pSigningCert = cert_context;
|
||||
sign_params.HashAlgorithm.pszObjId = szOID_NIST_sha256;
|
||||
sign_params.cMsgCert = 1;
|
||||
sign_params.rgpMsgCert = &cert_context;
|
||||
|
||||
messages[0] = message;
|
||||
messages_sizes[0] = message_size;
|
||||
|
||||
#if 0 /* Timestamp support */
|
||||
CRYPT_ATTR_BLOB crypt_blob;
|
||||
CRYPT_TIMESTAMP_CONTEXT *ts_context = NULL;
|
||||
CRYPT_ATTRIBUTE unauth_attribs[1];
|
||||
wchar_t *timestamp_url_wide = NULL;
|
||||
const char *timestamp_url = NULL;
|
||||
|
||||
if (timestamp_url != NULL)
|
||||
timestamp_url_wide = mz_os_unicode_string_create(timestamp_url);
|
||||
if (timestamp_url_wide != NULL)
|
||||
{
|
||||
result = CryptRetrieveTimeStamp(timestamp_url_wide,
|
||||
TIMESTAMP_NO_AUTH_RETRIEVAL | TIMESTAMP_VERIFY_CONTEXT_SIGNATURE, 0, szOID_NIST_sha256,
|
||||
NULL, message, message_size, &ts_context, NULL, NULL);
|
||||
|
||||
mz_os_unicode_string_delete(×tamp_url_wide);
|
||||
|
||||
if ((result) && (ts_context != NULL))
|
||||
{
|
||||
crypt_blob.cbData = ts_context->cbEncoded;
|
||||
crypt_blob.pbData = ts_context->pbEncoded;
|
||||
|
||||
unauth_attribs[0].pszObjId = "1.2.840.113549.1.9.16.2.14"; //id-smime-aa-timeStampToken
|
||||
unauth_attribs[0].cValue = 1;
|
||||
unauth_attribs[0].rgValue = &crypt_blob;
|
||||
|
||||
sign_params.rgUnauthAttr = &unauth_attribs[0];
|
||||
sign_params.cUnauthAttr = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ts_context != NULL)
|
||||
CryptMemFree(ts_context);
|
||||
|
||||
if (result)
|
||||
#endif
|
||||
|
||||
result = CryptSignMessage(&sign_params, FALSE, 1, messages, messages_sizes,
|
||||
NULL, signature_size);
|
||||
|
||||
if (result && *signature_size > 0)
|
||||
*signature = (uint8_t *)MZ_ALLOC(*signature_size);
|
||||
|
||||
if (result && *signature != NULL)
|
||||
result = CryptSignMessage(&sign_params, FALSE, 1, messages, messages_sizes,
|
||||
*signature, signature_size);
|
||||
|
||||
if (!result)
|
||||
err = MZ_SIGN_ERROR;
|
||||
}
|
||||
|
||||
if (cert_context != NULL)
|
||||
CertFreeCertificateContext(cert_context);
|
||||
if (cert_store != NULL)
|
||||
CertCloseStore(cert_store, 0);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int32_t mz_crypt_sign_verify(uint8_t *message, int32_t message_size, uint8_t *signature, int32_t signature_size)
|
||||
{
|
||||
CRYPT_VERIFY_MESSAGE_PARA verify_params;
|
||||
CERT_CONTEXT *signer_cert = NULL;
|
||||
CERT_CHAIN_PARA chain_para;
|
||||
CERT_CHAIN_CONTEXT *chain_context = NULL;
|
||||
CERT_CHAIN_POLICY_PARA chain_policy;
|
||||
CERT_CHAIN_POLICY_STATUS chain_policy_status;
|
||||
HCRYPTMSG crypt_msg = 0;
|
||||
int32_t result = 0;
|
||||
int32_t err = MZ_SIGN_ERROR;
|
||||
uint8_t *decoded = NULL;
|
||||
int32_t decoded_size = 0;
|
||||
|
||||
|
||||
memset(&verify_params, 0, sizeof(verify_params));
|
||||
|
||||
verify_params.cbSize = sizeof(verify_params);
|
||||
verify_params.dwMsgAndCertEncodingType = PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;
|
||||
|
||||
result = CryptVerifyMessageSignature(&verify_params, 0, signature, signature_size,
|
||||
NULL, &decoded_size, NULL);
|
||||
|
||||
if (result && decoded_size > 0)
|
||||
decoded = (uint8_t *)MZ_ALLOC(decoded_size);
|
||||
|
||||
if (result && decoded != NULL)
|
||||
result = CryptVerifyMessageSignature(&verify_params, 0, signature, signature_size,
|
||||
decoded, &decoded_size, &signer_cert);
|
||||
|
||||
/* Get and validate certificate chain */
|
||||
memset(&chain_para, 0, sizeof(chain_para));
|
||||
|
||||
if (result && signer_cert != NULL)
|
||||
result = CertGetCertificateChain(NULL, signer_cert, NULL, NULL, &chain_para,
|
||||
CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT, NULL, &chain_context);
|
||||
|
||||
memset(&chain_policy, 0, sizeof(chain_policy));
|
||||
chain_policy.cbSize = sizeof(CERT_CHAIN_POLICY_PARA);
|
||||
|
||||
memset(&chain_policy_status, 0, sizeof(chain_policy_status));
|
||||
chain_policy_status.cbSize = sizeof(CERT_CHAIN_POLICY_STATUS);
|
||||
|
||||
if (result && chain_context != NULL)
|
||||
result = CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_BASE, chain_context,
|
||||
&chain_policy, &chain_policy_status);
|
||||
|
||||
if (chain_policy_status.dwError != S_OK)
|
||||
result = 0;
|
||||
|
||||
#if 0
|
||||
crypt_msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, 0, 0, 0, NULL, NULL);
|
||||
if (crypt_msg != NULL)
|
||||
{
|
||||
/* Timestamp support */
|
||||
PCRYPT_ATTRIBUTES unauth_attribs = NULL;
|
||||
HCRYPTMSG ts_msg = 0;
|
||||
uint8_t *ts_content = NULL;
|
||||
int32_t ts_content_size = 0;
|
||||
uint8_t *ts_signature = NULL;
|
||||
int32_t ts_signature_size = 0;
|
||||
|
||||
result = CryptMsgUpdate(crypt_msg, signature, signature_size, 1);
|
||||
|
||||
if (result)
|
||||
CryptMsgGetParam(crypt_msg, CMSG_SIGNER_UNAUTH_ATTR_PARAM, 0, NULL, &ts_signature_size);
|
||||
|
||||
if ((result) && (ts_signature_size > 0))
|
||||
ts_signature = (uint8_t *)MZ_ALLOC(ts_signature_size);
|
||||
|
||||
if ((result) && (ts_signature != NULL))
|
||||
{
|
||||
result = CryptMsgGetParam(crypt_msg, CMSG_SIGNER_UNAUTH_ATTR_PARAM, 0, ts_signature,
|
||||
&ts_signature_size);
|
||||
if (result)
|
||||
{
|
||||
unauth_attribs = (PCRYPT_ATTRIBUTES)ts_signature;
|
||||
|
||||
if ((unauth_attribs->cAttr > 0) && (unauth_attribs->rgAttr[0].cValue > 0))
|
||||
{
|
||||
ts_content = unauth_attribs->rgAttr[0].rgValue->pbData;
|
||||
ts_content_size = unauth_attribs->rgAttr[0].rgValue->cbData;
|
||||
}
|
||||
}
|
||||
|
||||
if ((result) && (ts_content != NULL))
|
||||
result = CryptVerifyTimeStampSignature(ts_content, ts_content_size, decoded,
|
||||
decoded_size, 0, &crypt_context, NULL, NULL);
|
||||
|
||||
if (result)
|
||||
err = MZ_OK;
|
||||
}
|
||||
|
||||
if (ts_signature != NULL)
|
||||
MZ_FREE(ts_signature);
|
||||
|
||||
if (crypt_context != NULL)
|
||||
CryptMemFree(crypt_context);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((result) && (decoded != NULL) && (decoded_size == message_size))
|
||||
{
|
||||
/* Verify cms message with our stored message */
|
||||
if (memcmp(decoded, message, message_size) == 0)
|
||||
err = MZ_OK;
|
||||
}
|
||||
|
||||
if (chain_context != NULL)
|
||||
CertFreeCertificateChain(chain_context);
|
||||
if (signer_cert != NULL)
|
||||
CertFreeCertificateContext(signer_cert);
|
||||
if (crypt_msg != NULL)
|
||||
CryptMsgClose(crypt_msg);
|
||||
|
||||
if (decoded != NULL)
|
||||
MZ_FREE(decoded);
|
||||
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
@@ -1,75 +1,26 @@
|
||||
/* mz_os.c -- System functions
|
||||
Version 2.3.6, July 11, 2018
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2018 Nathan Moinvaziri
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
Copyright (C) 1998-2010 Gilles Vollant
|
||||
http://www.winimage.com/zLibDll/minizip.html
|
||||
https://www.winimage.com/zLibDll/minizip.html
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
See the accompanying LICENSE file for the full text of the license.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mz.h"
|
||||
#include "mz_crypt.h"
|
||||
#include "mz_os.h"
|
||||
#include "mz_strm.h"
|
||||
#include "mz_strm_crc32.h"
|
||||
#include "mz_strm_os.h"
|
||||
|
||||
#include <ctype.h> /* tolower */
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t mz_make_dir(const char *path)
|
||||
{
|
||||
int32_t err = MZ_OK;
|
||||
int16_t len = 0;
|
||||
char *current_dir = NULL;
|
||||
char *match = NULL;
|
||||
char hold = 0;
|
||||
|
||||
|
||||
len = (int16_t)strlen(path);
|
||||
if (len <= 0)
|
||||
return 0;
|
||||
|
||||
current_dir = (char *)MZ_ALLOC(len + 1);
|
||||
if (current_dir == NULL)
|
||||
return MZ_MEM_ERROR;
|
||||
|
||||
strcpy(current_dir, path);
|
||||
|
||||
if (current_dir[len - 1] == '/')
|
||||
current_dir[len - 1] = 0;
|
||||
|
||||
err = mz_os_make_dir(current_dir);
|
||||
if (err != MZ_OK)
|
||||
{
|
||||
match = current_dir + 1;
|
||||
while (1)
|
||||
{
|
||||
while (*match != 0 && *match != '\\' && *match != '/')
|
||||
match += 1;
|
||||
hold = *match;
|
||||
*match = 0;
|
||||
|
||||
err = mz_os_make_dir(current_dir);
|
||||
if (err != MZ_OK)
|
||||
break;
|
||||
if (hold == 0)
|
||||
break;
|
||||
|
||||
*match = hold;
|
||||
match += 1;
|
||||
}
|
||||
}
|
||||
|
||||
MZ_FREE(current_dir);
|
||||
return err;
|
||||
}
|
||||
|
||||
int32_t mz_path_combine(char *path, const char *join, int32_t max_path)
|
||||
{
|
||||
int32_t path_len = 0;
|
||||
@@ -77,28 +28,127 @@ int32_t mz_path_combine(char *path, const char *join, int32_t max_path)
|
||||
if (path == NULL || join == NULL || max_path == 0)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
path_len = strlen(path);
|
||||
path_len = (int32_t)strlen(path);
|
||||
|
||||
if (path_len == 0)
|
||||
{
|
||||
strncpy(path, join, max_path);
|
||||
strncpy(path, join, max_path - 1);
|
||||
path[max_path - 1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (path[path_len - 1] != '\\' && path[path_len - 1] != '/')
|
||||
strncat(path, "/", max_path - path_len - 1);
|
||||
mz_path_append_slash(path, max_path, MZ_PATH_SLASH_PLATFORM);
|
||||
strncat(path, join, max_path - path_len);
|
||||
}
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_path_append_slash(char *path, int32_t max_path, char slash)
|
||||
{
|
||||
int32_t path_len = (int32_t)strlen(path);
|
||||
if ((path_len + 2) >= max_path)
|
||||
return MZ_BUF_ERROR;
|
||||
if (path[path_len - 1] != '\\' && path[path_len - 1] != '/')
|
||||
{
|
||||
path[path_len] = slash;
|
||||
path[path_len + 1] = 0;
|
||||
}
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_path_remove_slash(char *path)
|
||||
{
|
||||
int32_t path_len = (int32_t)strlen(path);
|
||||
while (path_len > 0)
|
||||
{
|
||||
if (path[path_len - 1] == '\\' || path[path_len - 1] == '/')
|
||||
path[path_len - 1] = 0;
|
||||
else
|
||||
break;
|
||||
|
||||
path_len -= 1;
|
||||
}
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_path_has_slash(const char *path)
|
||||
{
|
||||
int32_t path_len = (int32_t)strlen(path);
|
||||
if (path[path_len - 1] != '\\' && path[path_len - 1] != '/')
|
||||
return MZ_EXIST_ERROR;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_path_convert_slashes(char *path, char slash)
|
||||
{
|
||||
int32_t i = 0;
|
||||
|
||||
for (i = 0; i < (int32_t)strlen(path); i += 1)
|
||||
{
|
||||
if (path[i] == '\\' || path[i] == '/')
|
||||
path[i] = slash;
|
||||
}
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_path_compare_wc(const char *path, const char *wildcard, uint8_t ignore_case)
|
||||
{
|
||||
while (*path != 0)
|
||||
{
|
||||
switch (*wildcard)
|
||||
{
|
||||
case '*':
|
||||
|
||||
if (*(wildcard + 1) == 0)
|
||||
return MZ_OK;
|
||||
|
||||
while (*path != 0)
|
||||
{
|
||||
if (mz_path_compare_wc(path, (wildcard + 1), ignore_case) == MZ_OK)
|
||||
return MZ_OK;
|
||||
|
||||
path += 1;
|
||||
}
|
||||
|
||||
return MZ_EXIST_ERROR;
|
||||
|
||||
default:
|
||||
/* Ignore differences in path slashes on platforms */
|
||||
if ((*path == '\\' && *wildcard == '/') || (*path == '/' && *wildcard == '\\'))
|
||||
break;
|
||||
|
||||
if (ignore_case)
|
||||
{
|
||||
if (tolower(*path) != tolower(*wildcard))
|
||||
return MZ_EXIST_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*path != *wildcard)
|
||||
return MZ_EXIST_ERROR;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
path += 1;
|
||||
wildcard += 1;
|
||||
}
|
||||
|
||||
if ((*wildcard != 0) && (*wildcard != '*'))
|
||||
return MZ_EXIST_ERROR;
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_path_resolve(const char *path, char *output, int32_t max_output)
|
||||
{
|
||||
const char *source = path;
|
||||
const char *check = output;
|
||||
char *target = output;
|
||||
|
||||
|
||||
if (max_output <= 0)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
@@ -108,9 +158,9 @@ int32_t mz_path_resolve(const char *path, char *output, int32_t max_output)
|
||||
if ((*check == '\\') || (*check == '/'))
|
||||
check += 1;
|
||||
|
||||
if ((source == path) || (check != source) || (*target == 0))
|
||||
if ((source == path) || (target == output) || (check != source))
|
||||
{
|
||||
// Skip double paths
|
||||
/* Skip double paths */
|
||||
if ((*check == '\\') || (*check == '/'))
|
||||
{
|
||||
source += 1;
|
||||
@@ -120,37 +170,34 @@ int32_t mz_path_resolve(const char *path, char *output, int32_t max_output)
|
||||
{
|
||||
check += 1;
|
||||
|
||||
// Remove current directory . if at end of stirng
|
||||
if ((*check == 0) && (source != path))
|
||||
/* Remove . if at end of string and not at the beginning */
|
||||
if ((*check == 0) && (source != path && target != output))
|
||||
{
|
||||
// Copy last slash
|
||||
/* Copy last slash */
|
||||
*target = *source;
|
||||
target += 1;
|
||||
max_output -= 1;
|
||||
source += (check - source);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove current directory . if not at end of stirng
|
||||
if ((*check == 0) || (*check == '\\' || *check == '/'))
|
||||
{
|
||||
// Only proceed if .\ is not entire string
|
||||
if (check[1] != 0 || (path != source))
|
||||
{
|
||||
source += (check - source);
|
||||
continue;
|
||||
}
|
||||
/* Remove . if not at end of string */
|
||||
else if ((*check == '\\') || (*check == '/'))
|
||||
{
|
||||
source += (check - source);
|
||||
/* Skip slash if at beginning of string */
|
||||
if (target == output && *source != 0)
|
||||
source += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Go to parent directory ..
|
||||
if ((*check != 0) || (*check == '.'))
|
||||
/* Go to parent directory .. */
|
||||
else if (*check == '.')
|
||||
{
|
||||
check += 1;
|
||||
if ((*check == 0) || (*check == '\\' || *check == '/'))
|
||||
{
|
||||
source += (check - source);
|
||||
|
||||
// Search backwards for previous slash
|
||||
/* Search backwards for previous slash */
|
||||
if (target != output)
|
||||
{
|
||||
target -= 1;
|
||||
@@ -164,7 +211,7 @@ int32_t mz_path_resolve(const char *path, char *output, int32_t max_output)
|
||||
}
|
||||
while (target > output);
|
||||
}
|
||||
|
||||
|
||||
if ((target == output) && (*source != 0))
|
||||
source += 1;
|
||||
if ((*target == '\\' || *target == '/') && (*source == 0))
|
||||
@@ -192,14 +239,14 @@ int32_t mz_path_resolve(const char *path, char *output, int32_t max_output)
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_path_remove_filename(const char *path)
|
||||
int32_t mz_path_remove_filename(char *path)
|
||||
{
|
||||
char *path_ptr = NULL;
|
||||
|
||||
if (path == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
path_ptr = (char *)(path + strlen(path) - 1);
|
||||
path_ptr = path + strlen(path) - 1;
|
||||
|
||||
while (path_ptr > path)
|
||||
{
|
||||
@@ -211,6 +258,38 @@ int32_t mz_path_remove_filename(const char *path)
|
||||
|
||||
path_ptr -= 1;
|
||||
}
|
||||
|
||||
if (path_ptr == path)
|
||||
*path_ptr = 0;
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_path_remove_extension(char *path)
|
||||
{
|
||||
char *path_ptr = NULL;
|
||||
|
||||
if (path == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
path_ptr = path + strlen(path) - 1;
|
||||
|
||||
while (path_ptr > path)
|
||||
{
|
||||
if ((*path_ptr == '/') || (*path_ptr == '\\'))
|
||||
break;
|
||||
if (*path_ptr == '.')
|
||||
{
|
||||
*path_ptr = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
path_ptr -= 1;
|
||||
}
|
||||
|
||||
if (path_ptr == path)
|
||||
*path_ptr = 0;
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
@@ -235,45 +314,88 @@ int32_t mz_path_get_filename(const char *path, const char **filename)
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_get_file_crc(const char *path, uint32_t *result_crc)
|
||||
int32_t mz_dir_make(const char *path)
|
||||
{
|
||||
int32_t err = MZ_OK;
|
||||
int16_t len = 0;
|
||||
char *current_dir = NULL;
|
||||
char *match = NULL;
|
||||
char hold = 0;
|
||||
|
||||
|
||||
len = (int16_t)strlen(path);
|
||||
if (len <= 0)
|
||||
return 0;
|
||||
|
||||
current_dir = (char *)MZ_ALLOC((uint16_t)len + 1);
|
||||
if (current_dir == NULL)
|
||||
return MZ_MEM_ERROR;
|
||||
|
||||
strcpy(current_dir, path);
|
||||
mz_path_remove_slash(current_dir);
|
||||
|
||||
err = mz_os_make_dir(current_dir);
|
||||
if (err != MZ_OK)
|
||||
{
|
||||
match = current_dir + 1;
|
||||
while (1)
|
||||
{
|
||||
while (*match != 0 && *match != '\\' && *match != '/')
|
||||
match += 1;
|
||||
hold = *match;
|
||||
*match = 0;
|
||||
|
||||
err = mz_os_make_dir(current_dir);
|
||||
if (err != MZ_OK)
|
||||
break;
|
||||
if (hold == 0)
|
||||
break;
|
||||
|
||||
*match = hold;
|
||||
match += 1;
|
||||
}
|
||||
}
|
||||
|
||||
MZ_FREE(current_dir);
|
||||
return err;
|
||||
}
|
||||
|
||||
int32_t mz_file_get_crc(const char *path, uint32_t *result_crc)
|
||||
{
|
||||
void *stream = NULL;
|
||||
void *crc32_stream = NULL;
|
||||
uint32_t crc32 = 0;
|
||||
int32_t read = 0;
|
||||
int32_t err = MZ_OK;
|
||||
uint8_t buf[INT16_MAX];
|
||||
uint8_t buf[16384];
|
||||
|
||||
mz_stream_os_create(&stream);
|
||||
|
||||
err = mz_stream_os_open(stream, path, MZ_OPEN_MODE_READ);
|
||||
|
||||
mz_stream_crc32_create(&crc32_stream);
|
||||
mz_stream_crc32_open(crc32_stream, NULL, MZ_OPEN_MODE_READ);
|
||||
|
||||
mz_stream_set_base(crc32_stream, stream);
|
||||
|
||||
if (err == MZ_OK)
|
||||
{
|
||||
do
|
||||
{
|
||||
read = mz_stream_crc32_read(crc32_stream, buf, sizeof(buf));
|
||||
read = mz_stream_os_read(stream, buf, sizeof(buf));
|
||||
|
||||
if (read < 0)
|
||||
{
|
||||
err = read;
|
||||
break;
|
||||
}
|
||||
|
||||
crc32 = mz_crypt_crc32_update(crc32, buf, read);
|
||||
}
|
||||
while ((err == MZ_OK) && (read > 0));
|
||||
|
||||
mz_stream_os_close(stream);
|
||||
}
|
||||
|
||||
mz_stream_crc32_close(crc32_stream);
|
||||
*result_crc = mz_stream_crc32_get_value(crc32_stream);
|
||||
mz_stream_crc32_delete(&crc32_stream);
|
||||
*result_crc = crc32;
|
||||
|
||||
mz_stream_os_delete(&stream);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/* mz_os.h -- System functions
|
||||
Version 2.3.6, July 11, 2018
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2018 Nathan Moinvaziri
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
@@ -12,56 +12,160 @@
|
||||
#ifndef MZ_OS_H
|
||||
#define MZ_OS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#if !defined(_WIN32) && !defined(MZ_USE_WIN32_API)
|
||||
#include "mz_os_posix.h"
|
||||
#include "mz_strm_posix.h"
|
||||
#if defined(__APPLE__)
|
||||
# define MZ_VERSION_MADEBY_HOST_SYSTEM (MZ_HOST_SYSTEM_OSX_DARWIN)
|
||||
#elif defined(__riscos__)
|
||||
# define MZ_VERSION_MADEBY_HOST_SYSTEM (MZ_HOST_SYSTEM_RISCOS)
|
||||
#elif defined(__unix__)
|
||||
# define MZ_VERSION_MADEBY_HOST_SYSTEM (MZ_HOST_SYSTEM_UNIX)
|
||||
#elif defined(_WIN32)
|
||||
# define MZ_VERSION_MADEBY_HOST_SYSTEM (MZ_HOST_SYSTEM_WINDOWS_NTFS)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LZMA)
|
||||
# define MZ_VERSION_MADEBY_ZIP_VERSION (63)
|
||||
#elif defined(HAVE_WZAES)
|
||||
# define MZ_VERSION_MADEBY_ZIP_VERSION (51)
|
||||
#elif defined(HAVE_BZIP2)
|
||||
# define MZ_VERSION_MADEBY_ZIP_VERSION (46)
|
||||
#else
|
||||
#include "mz_os_win32.h"
|
||||
#include "mz_strm_win32.h"
|
||||
# define MZ_VERSION_MADEBY_ZIP_VERSION (45)
|
||||
#endif
|
||||
|
||||
#define MZ_VERSION_MADEBY ((MZ_VERSION_MADEBY_HOST_SYSTEM << 8) | \
|
||||
(MZ_VERSION_MADEBY_ZIP_VERSION))
|
||||
|
||||
#define MZ_PATH_SLASH_UNIX ('/')
|
||||
#if defined(_WIN32)
|
||||
# define MZ_PATH_SLASH_PLATFORM ('\\')
|
||||
#else
|
||||
# define MZ_PATH_SLASH_PLATFORM (MZ_PATH_SLASH_UNIX)
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#ifdef HAVE_LZMA
|
||||
#define MZ_VERSION_MADEBY_ZIP_VERSION (63)
|
||||
#elif HAVE_AES
|
||||
#define MZ_VERSION_MADEBY_ZIP_VERSION (51)
|
||||
#elif HAVE_BZIP2
|
||||
#define MZ_VERSION_MADEBY_ZIP_VERSION (46)
|
||||
#if defined(_WIN32)
|
||||
struct dirent {
|
||||
char d_name[256];
|
||||
};
|
||||
typedef void* DIR;
|
||||
#else
|
||||
#define MZ_VERSION_MADEBY_ZIP_VERSION (45)
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
#define MZ_VERSION_MADEBY ((MZ_VERSION_MADEBY_HOST_SYSTEM << 8) | \
|
||||
(MZ_VERSION_MADEBY_ZIP_VERSION))
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t mz_make_dir(const char *path);
|
||||
// Creates a directory recursively
|
||||
/* Shared functions */
|
||||
|
||||
int32_t mz_path_combine(char *path, const char *join, int32_t max_path);
|
||||
// Combines two paths
|
||||
/* Combines two paths */
|
||||
|
||||
int32_t mz_path_append_slash(char *path, int32_t max_path, char slash);
|
||||
/* Appends a path slash on to the end of the path */
|
||||
|
||||
int32_t mz_path_remove_slash(char *path);
|
||||
/* Removes a path slash from the end of the path */
|
||||
|
||||
int32_t mz_path_has_slash(const char *path);
|
||||
/* Returns whether or not the path ends with slash */
|
||||
|
||||
int32_t mz_path_convert_slashes(char *path, char slash);
|
||||
/* Converts the slashes in a path */
|
||||
|
||||
int32_t mz_path_compare_wc(const char *path, const char *wildcard, uint8_t ignore_case);
|
||||
/* Compare two paths with wildcard */
|
||||
|
||||
int32_t mz_path_resolve(const char *path, char *target, int32_t max_target);
|
||||
// Resolves path
|
||||
/* Resolves path */
|
||||
|
||||
int32_t mz_path_remove_filename(const char *path);
|
||||
// Remove the filename from a path
|
||||
int32_t mz_path_remove_filename(char *path);
|
||||
/* Remove the filename from a path */
|
||||
|
||||
int32_t mz_path_remove_extension(char *path);
|
||||
/* Remove the extension from a path */
|
||||
|
||||
int32_t mz_path_get_filename(const char *path, const char **filename);
|
||||
// Get the filename from a path
|
||||
/* Get the filename from a path */
|
||||
|
||||
int32_t mz_get_file_crc(const char *path, uint32_t *result_crc);
|
||||
// Gets the crc32 hash of a file
|
||||
int32_t mz_dir_make(const char *path);
|
||||
/* Creates a directory recursively */
|
||||
|
||||
int32_t mz_file_get_crc(const char *path, uint32_t *result_crc);
|
||||
/* Gets the crc32 hash of a file */
|
||||
|
||||
/***************************************************************************/
|
||||
/* Platform specific functions */
|
||||
|
||||
wchar_t *mz_os_unicode_string_create(const char *string, int32_t encoding);
|
||||
/* Create unicode string from a utf8 string */
|
||||
|
||||
void mz_os_unicode_string_delete(wchar_t **string);
|
||||
/* Delete a unicode string that was created */
|
||||
|
||||
uint8_t *mz_os_utf8_string_create(const char *string, int32_t encoding);
|
||||
/* Create a utf8 string from a string with another encoding */
|
||||
|
||||
void mz_os_utf8_string_delete(uint8_t **string);
|
||||
/* Delete a utf8 string that was created */
|
||||
|
||||
int32_t mz_os_rand(uint8_t *buf, int32_t size);
|
||||
/* Random number generator (not cryptographically secure) */
|
||||
|
||||
int32_t mz_os_rename(const char *source_path, const char *target_path);
|
||||
/* Rename a file */
|
||||
|
||||
int32_t mz_os_unlink(const char *path);
|
||||
/* Delete an existing file */
|
||||
|
||||
int32_t mz_os_file_exists(const char *path);
|
||||
/* Check to see if a file exists */
|
||||
|
||||
int64_t mz_os_get_file_size(const char *path);
|
||||
/* Gets the length of a file */
|
||||
|
||||
int32_t mz_os_get_file_date(const char *path, time_t *modified_date, time_t *accessed_date, time_t *creation_date);
|
||||
/* Gets a file's modified, access, and creation dates if supported */
|
||||
|
||||
int32_t mz_os_set_file_date(const char *path, time_t modified_date, time_t accessed_date, time_t creation_date);
|
||||
/* Sets a file's modified, access, and creation dates if supported */
|
||||
|
||||
int32_t mz_os_get_file_attribs(const char *path, uint32_t *attributes);
|
||||
/* Gets a file's attributes */
|
||||
|
||||
int32_t mz_os_set_file_attribs(const char *path, uint32_t attributes);
|
||||
/* Sets a file's attributes */
|
||||
|
||||
int32_t mz_os_make_dir(const char *path);
|
||||
/* Recursively creates a directory */
|
||||
|
||||
DIR* mz_os_open_dir(const char *path);
|
||||
/* Opens a directory for listing */
|
||||
struct
|
||||
dirent* mz_os_read_dir(DIR *dir);
|
||||
/* Reads a directory listing entry */
|
||||
|
||||
int32_t mz_os_close_dir(DIR *dir);
|
||||
/* Closes a directory that has been opened for listing */
|
||||
|
||||
int32_t mz_os_is_dir(const char *path);
|
||||
/* Checks to see if path is a directory */
|
||||
|
||||
int32_t mz_os_is_symlink(const char *path);
|
||||
/* Checks to see if path is a symbolic link */
|
||||
|
||||
int32_t mz_os_make_symlink(const char *path, const char *target_path);
|
||||
/* Creates a symbolic link pointing to a target */
|
||||
|
||||
int32_t mz_os_read_symlink(const char *path, char *target_path, int32_t max_target_path);
|
||||
/* Gets the target path for a symbolic link */
|
||||
|
||||
uint64_t mz_os_ms_time(void);
|
||||
/* Gets the time in milliseconds */
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
+202
-55
@@ -1,95 +1,186 @@
|
||||
/* mz_os_posix.c -- System functions for posix
|
||||
Version 2.3.6, July 11, 2018
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2018 Nathan Moinvaziri
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
See the accompanying LICENSE file for the full text of the license.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "mz.h"
|
||||
#include "mz_strm.h"
|
||||
#include "mz_os.h"
|
||||
|
||||
#include <stdio.h> /* rename */
|
||||
#include <errno.h>
|
||||
#include <iconv.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if defined unix || defined __APPLE__
|
||||
# include <unistd.h>
|
||||
#if defined(__APPLE__) || defined(__unix__) || defined(__riscos__)
|
||||
# include <utime.h>
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#if defined __linux__
|
||||
# include <bsd/stdlib.h>
|
||||
#else
|
||||
# include <stdlib.h>
|
||||
#if defined(__APPLE__)
|
||||
# include <mach/clock.h>
|
||||
# include <mach/mach.h>
|
||||
#endif
|
||||
|
||||
#include "mz.h"
|
||||
#include "mz_strm.h"
|
||||
#include "mz_os.h"
|
||||
#include "mz_os_posix.h"
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#if defined(HAVE_PKCRYPT) || defined(HAVE_AES)
|
||||
int32_t mz_posix_rand(uint8_t *buf, int32_t size)
|
||||
uint8_t *mz_os_utf8_string_create(const char *string, int32_t encoding)
|
||||
{
|
||||
arc4random_buf(buf, size);
|
||||
iconv_t cd;
|
||||
const char *from_encoding = NULL;
|
||||
size_t result = 0;
|
||||
size_t string_length = 0;
|
||||
size_t string_utf8_size = 0;
|
||||
uint8_t *string_utf8 = NULL;
|
||||
uint8_t *string_utf8_ptr = NULL;
|
||||
|
||||
if (string == NULL)
|
||||
return NULL;
|
||||
|
||||
if (encoding == MZ_ENCODING_CODEPAGE_437)
|
||||
from_encoding = "CP437";
|
||||
else if (encoding == MZ_ENCODING_CODEPAGE_932)
|
||||
from_encoding = "CP932";
|
||||
else if (encoding == MZ_ENCODING_CODEPAGE_936)
|
||||
from_encoding = "CP936";
|
||||
else if (encoding == MZ_ENCODING_CODEPAGE_950)
|
||||
from_encoding = "CP950";
|
||||
else if (encoding == MZ_ENCODING_UTF8)
|
||||
from_encoding = "UTF-8";
|
||||
else
|
||||
return NULL;
|
||||
|
||||
cd = iconv_open("UTF-8", from_encoding);
|
||||
if (cd == (iconv_t)-1)
|
||||
return NULL;
|
||||
|
||||
string_length = strlen(string);
|
||||
string_utf8_size = string_length * 2;
|
||||
string_utf8 = (uint8_t *)MZ_ALLOC((int32_t)(string_utf8_size + 1));
|
||||
string_utf8_ptr = string_utf8;
|
||||
|
||||
if (string_utf8)
|
||||
{
|
||||
memset(string_utf8, 0, string_utf8_size + 1);
|
||||
|
||||
result = iconv(cd, (char **)&string, &string_length,
|
||||
(char **)&string_utf8_ptr, &string_utf8_size);
|
||||
}
|
||||
|
||||
iconv_close(cd);
|
||||
|
||||
if (result == (size_t)-1)
|
||||
{
|
||||
MZ_FREE(string_utf8);
|
||||
string_utf8 = NULL;
|
||||
}
|
||||
|
||||
return string_utf8;
|
||||
}
|
||||
|
||||
void mz_os_utf8_string_delete(uint8_t **string)
|
||||
{
|
||||
if (string != NULL)
|
||||
{
|
||||
MZ_FREE(*string);
|
||||
*string = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t mz_os_rand(uint8_t *buf, int32_t size)
|
||||
{
|
||||
static unsigned calls = 0;
|
||||
int32_t i = 0;
|
||||
|
||||
/* Ensure different random header each time */
|
||||
if (++calls == 1)
|
||||
{
|
||||
#define PI_SEED 3141592654UL
|
||||
srand((unsigned)(time(NULL) ^ PI_SEED));
|
||||
}
|
||||
|
||||
while (i < size)
|
||||
buf[i++] = (rand() >> 7) & 0xff;
|
||||
|
||||
return size;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t mz_posix_file_exists(const char *path)
|
||||
int32_t mz_os_rename(const char *source_path, const char *target_path)
|
||||
{
|
||||
struct stat stat_info;
|
||||
if (rename(source_path, target_path) == -1)
|
||||
return MZ_EXIST_ERROR;
|
||||
|
||||
memset(&stat_info, 0, sizeof(stat_info));
|
||||
if (stat(path, &stat_info) == 0)
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_os_unlink(const char *path)
|
||||
{
|
||||
if (unlink(path) == -1)
|
||||
return MZ_EXIST_ERROR;
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_os_file_exists(const char *path)
|
||||
{
|
||||
struct stat path_stat;
|
||||
|
||||
memset(&path_stat, 0, sizeof(path_stat));
|
||||
if (stat(path, &path_stat) == 0)
|
||||
return MZ_OK;
|
||||
|
||||
return MZ_EXIST_ERROR;
|
||||
}
|
||||
|
||||
int64_t mz_posix_get_file_size(const char *path)
|
||||
int64_t mz_os_get_file_size(const char *path)
|
||||
{
|
||||
struct stat stat_info;
|
||||
struct stat path_stat;
|
||||
|
||||
memset(&stat_info, 0, sizeof(stat_info));
|
||||
if (stat(path, &stat_info) == 0)
|
||||
return stat_info.st_size;
|
||||
memset(&path_stat, 0, sizeof(path_stat));
|
||||
if (stat(path, &path_stat) == 0)
|
||||
{
|
||||
/* Stat returns size taken up by directory entry, so return 0 */
|
||||
if (S_ISDIR(path_stat.st_mode))
|
||||
return 0;
|
||||
|
||||
return path_stat.st_size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t mz_posix_get_file_date(const char *path, time_t *modified_date, time_t *accessed_date, time_t *creation_date)
|
||||
int32_t mz_os_get_file_date(const char *path, time_t *modified_date, time_t *accessed_date, time_t *creation_date)
|
||||
{
|
||||
struct stat stat_info;
|
||||
struct stat path_stat;
|
||||
char *name = NULL;
|
||||
size_t len = 0;
|
||||
int32_t err = MZ_INTERNAL_ERROR;
|
||||
|
||||
memset(&stat_info, 0, sizeof(stat_info));
|
||||
memset(&path_stat, 0, sizeof(path_stat));
|
||||
|
||||
if (strcmp(path, "-") != 0)
|
||||
{
|
||||
// Not all systems allow stat'ing a file with / appended
|
||||
/* Not all systems allow stat'ing a file with / appended */
|
||||
len = strlen(path);
|
||||
name = (char *)malloc(len + 1);
|
||||
strncpy(name, path, len + 1);
|
||||
name[len] = 0;
|
||||
if (name[len - 1] == '/')
|
||||
name[len - 1] = 0;
|
||||
mz_path_remove_slash(name);
|
||||
|
||||
if (stat(name, &stat_info) == 0)
|
||||
if (stat(name, &path_stat) == 0)
|
||||
{
|
||||
if (modified_date != NULL)
|
||||
*modified_date = stat_info.st_mtime;
|
||||
*modified_date = path_stat.st_mtime;
|
||||
if (accessed_date != NULL)
|
||||
*accessed_date = stat_info.st_atime;
|
||||
// Creation date not supported
|
||||
*accessed_date = path_stat.st_atime;
|
||||
/* Creation date not supported */
|
||||
if (creation_date != NULL)
|
||||
*creation_date = 0;
|
||||
|
||||
@@ -102,14 +193,15 @@ int32_t mz_posix_get_file_date(const char *path, time_t *modified_date, time_t *
|
||||
return err;
|
||||
}
|
||||
|
||||
int32_t mz_posix_set_file_date(const char *path, time_t modified_date, time_t accessed_date, time_t creation_date)
|
||||
int32_t mz_os_set_file_date(const char *path, time_t modified_date, time_t accessed_date, time_t creation_date)
|
||||
{
|
||||
struct utimbuf ut;
|
||||
|
||||
ut.actime = accessed_date;
|
||||
ut.modtime = modified_date;
|
||||
// Creation date not supported
|
||||
(void)creation_date;
|
||||
|
||||
/* Creation date not supported */
|
||||
MZ_UNUSED(creation_date);
|
||||
|
||||
if (utime(path, &ut) != 0)
|
||||
return MZ_INTERNAL_ERROR;
|
||||
@@ -117,19 +209,19 @@ int32_t mz_posix_set_file_date(const char *path, time_t modified_date, time_t ac
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_posix_get_file_attribs(const char *path, uint32_t *attributes)
|
||||
int32_t mz_os_get_file_attribs(const char *path, uint32_t *attributes)
|
||||
{
|
||||
struct stat stat_info;
|
||||
struct stat path_stat;
|
||||
int32_t err = MZ_OK;
|
||||
|
||||
memset(&stat_info, 0, sizeof(stat_info));
|
||||
if (stat(path, &stat_info) == -1)
|
||||
memset(&path_stat, 0, sizeof(path_stat));
|
||||
if (lstat(path, &path_stat) == -1)
|
||||
err = MZ_INTERNAL_ERROR;
|
||||
*attributes = stat_info.st_mode;
|
||||
*attributes = path_stat.st_mode;
|
||||
return err;
|
||||
}
|
||||
|
||||
int32_t mz_posix_set_file_attribs(const char *path, uint32_t attributes)
|
||||
int32_t mz_os_set_file_attribs(const char *path, uint32_t attributes)
|
||||
{
|
||||
int32_t err = MZ_OK;
|
||||
|
||||
@@ -139,7 +231,7 @@ int32_t mz_posix_set_file_attribs(const char *path, uint32_t attributes)
|
||||
return err;
|
||||
}
|
||||
|
||||
int32_t mz_posix_make_dir(const char *path)
|
||||
int32_t mz_os_make_dir(const char *path)
|
||||
{
|
||||
int32_t err = 0;
|
||||
|
||||
@@ -151,19 +243,19 @@ int32_t mz_posix_make_dir(const char *path)
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
DIR* mz_posix_open_dir(const char *path)
|
||||
DIR* mz_os_open_dir(const char *path)
|
||||
{
|
||||
return opendir(path);
|
||||
}
|
||||
|
||||
struct dirent* mz_posix_read_dir(DIR *dir)
|
||||
struct dirent* mz_os_read_dir(DIR *dir)
|
||||
{
|
||||
if (dir == NULL)
|
||||
return NULL;
|
||||
return readdir(dir);
|
||||
}
|
||||
|
||||
int32_t mz_posix_close_dir(DIR *dir)
|
||||
int32_t mz_os_close_dir(DIR *dir)
|
||||
{
|
||||
if (dir == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
@@ -172,11 +264,66 @@ int32_t mz_posix_close_dir(DIR *dir)
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_posix_is_dir(const char *path)
|
||||
int32_t mz_os_is_dir(const char *path)
|
||||
{
|
||||
struct stat path_stat;
|
||||
|
||||
memset(&path_stat, 0, sizeof(path_stat));
|
||||
stat(path, &path_stat);
|
||||
if (S_ISDIR(path_stat.st_mode))
|
||||
return MZ_OK;
|
||||
|
||||
return MZ_EXIST_ERROR;
|
||||
}
|
||||
|
||||
int32_t mz_os_is_symlink(const char *path)
|
||||
{
|
||||
struct stat path_stat;
|
||||
|
||||
memset(&path_stat, 0, sizeof(path_stat));
|
||||
lstat(path, &path_stat);
|
||||
if (S_ISLNK(path_stat.st_mode))
|
||||
return MZ_OK;
|
||||
|
||||
return MZ_EXIST_ERROR;
|
||||
}
|
||||
|
||||
int32_t mz_os_make_symlink(const char *path, const char *target_path)
|
||||
{
|
||||
if (symlink(target_path, path) != 0)
|
||||
return MZ_INTERNAL_ERROR;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_os_read_symlink(const char *path, char *target_path, int32_t max_target_path)
|
||||
{
|
||||
size_t length = 0;
|
||||
|
||||
length = (size_t)readlink(path, target_path, max_target_path - 1);
|
||||
if (length == (size_t)-1)
|
||||
return MZ_EXIST_ERROR;
|
||||
|
||||
target_path[length] = 0;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
uint64_t mz_os_ms_time(void)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
#if defined(__APPLE__)
|
||||
clock_serv_t cclock;
|
||||
mach_timespec_t mts;
|
||||
|
||||
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
|
||||
clock_get_time(cclock, &mts);
|
||||
mach_port_deallocate(mach_task_self(), cclock);
|
||||
|
||||
ts.tv_sec = mts.tv_sec;
|
||||
ts.tv_nsec = mts.tv_nsec;
|
||||
#else
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
#endif
|
||||
|
||||
return ((uint64_t)ts.tv_sec * 1000) + ((uint64_t)ts.tv_nsec / 1000000);
|
||||
}
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
/* mz_os_posix.h -- System functions for posix
|
||||
Version 2.3.6, July 11, 2018
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2018 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
See the accompanying LICENSE file for the full text of the license.
|
||||
*/
|
||||
|
||||
#ifndef MZ_OS_POSIX_H
|
||||
#define MZ_OS_POSIX_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#define MZ_VERSION_MADEBY_HOST_SYSTEM (MZ_HOST_SYSTEM_OSX_DARWIN)
|
||||
#elif defined(unix)
|
||||
#define MZ_VERSION_MADEBY_HOST_SYSTEM (MZ_HOST_SYSTEM_UNIX)
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t mz_posix_rand(uint8_t *buf, int32_t size);
|
||||
int32_t mz_posix_file_exists(const char *path);
|
||||
int64_t mz_posix_get_file_size(const char *path);
|
||||
int32_t mz_posix_get_file_date(const char *path, time_t *modified_date, time_t *accessed_date, time_t *creation_date);
|
||||
int32_t mz_posix_set_file_date(const char *path, time_t modified_date, time_t accessed_date, time_t creation_date);
|
||||
int32_t mz_posix_get_file_attribs(const char *path, uint32_t *attributes);
|
||||
int32_t mz_posix_set_file_attribs(const char *path, uint32_t attributes);
|
||||
int32_t mz_posix_make_dir(const char *path);
|
||||
DIR* mz_posix_open_dir(const char *path);
|
||||
struct
|
||||
dirent* mz_posix_read_dir(DIR *dir);
|
||||
int32_t mz_posix_close_dir(DIR *dir);
|
||||
int32_t mz_posix_is_dir(const char *path);
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#define mz_os_rand mz_posix_rand
|
||||
#define mz_os_file_exists mz_posix_file_exists
|
||||
#define mz_os_get_file_size mz_posix_get_file_size
|
||||
#define mz_os_get_file_date mz_posix_get_file_date
|
||||
#define mz_os_set_file_date mz_posix_set_file_date
|
||||
#define mz_os_get_file_attribs mz_posix_get_file_attribs
|
||||
#define mz_os_set_file_attribs mz_posix_set_file_attribs
|
||||
#define mz_os_make_dir mz_posix_make_dir
|
||||
#define mz_os_open_dir mz_posix_open_dir
|
||||
#define mz_os_read_dir mz_posix_read_dir
|
||||
#define mz_os_close_dir mz_posix_close_dir
|
||||
#define mz_os_is_dir mz_posix_is_dir
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+435
-87
@@ -1,28 +1,20 @@
|
||||
/* mz_os_win32.c -- System functions for Windows
|
||||
Version 2.3.6, July 11, 2018
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2018 Nathan Moinvaziri
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
See the accompanying LICENSE file for the full text of the license.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <direct.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
|
||||
#include "mz.h"
|
||||
|
||||
#include "mz_os.h"
|
||||
#include "mz_os_win32.h"
|
||||
#include "mz_strm_os.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
@@ -32,6 +24,10 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef SYMBOLIC_LINK_FLAG_DIRECTORY
|
||||
# define SYMBOLIC_LINK_FLAG_DIRECTORY 0x1
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
typedef struct DIR_int_s {
|
||||
@@ -43,22 +39,89 @@ typedef struct DIR_int_s {
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#if defined(HAVE_PKCRYPT) || defined(HAVE_AES)
|
||||
int32_t mz_win32_rand(uint8_t *buf, int32_t size)
|
||||
wchar_t *mz_os_unicode_string_create(const char *string, int32_t encoding)
|
||||
{
|
||||
wchar_t *string_wide = NULL;
|
||||
uint32_t string_wide_size = 0;
|
||||
|
||||
string_wide_size = MultiByteToWideChar(encoding, 0, string, -1, NULL, 0);
|
||||
if (string_wide_size == 0)
|
||||
return NULL;
|
||||
string_wide = (wchar_t *)MZ_ALLOC((string_wide_size + 1) * sizeof(wchar_t));
|
||||
if (string_wide == NULL)
|
||||
return NULL;
|
||||
|
||||
memset(string_wide, 0, sizeof(wchar_t) * (string_wide_size + 1));
|
||||
MultiByteToWideChar(encoding, 0, string, -1, string_wide, string_wide_size);
|
||||
|
||||
return string_wide;
|
||||
}
|
||||
|
||||
void mz_os_unicode_string_delete(wchar_t **string)
|
||||
{
|
||||
if (string != NULL)
|
||||
{
|
||||
MZ_FREE(*string);
|
||||
*string = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t *mz_os_utf8_string_create(const char *string, int32_t encoding)
|
||||
{
|
||||
wchar_t *string_wide = NULL;
|
||||
uint8_t *string_utf8 = NULL;
|
||||
uint32_t string_utf8_size = 0;
|
||||
|
||||
string_wide = mz_os_unicode_string_create(string, encoding);
|
||||
if (string_wide)
|
||||
{
|
||||
string_utf8_size = WideCharToMultiByte(CP_UTF8, 0, string_wide, -1, NULL, 0, NULL, NULL);
|
||||
string_utf8 = (uint8_t *)MZ_ALLOC((string_utf8_size + 1) * sizeof(wchar_t));
|
||||
|
||||
if (string_utf8)
|
||||
{
|
||||
memset(string_utf8, 0, string_utf8_size + 1);
|
||||
WideCharToMultiByte(CP_UTF8, 0, string_wide, -1, (char *)string_utf8, string_utf8_size, NULL, NULL);
|
||||
}
|
||||
|
||||
mz_os_unicode_string_delete(&string_wide);
|
||||
}
|
||||
|
||||
return string_utf8;
|
||||
}
|
||||
|
||||
uint8_t *mz_os_utf8_string_create_from_unicode(const wchar_t *string, int32_t encoding)
|
||||
{
|
||||
uint8_t *string_utf8 = NULL;
|
||||
uint32_t string_utf8_size = 0;
|
||||
|
||||
string_utf8_size = WideCharToMultiByte(CP_UTF8, 0, string, -1, NULL, 0, NULL, NULL);
|
||||
string_utf8 = (uint8_t *)MZ_ALLOC((string_utf8_size + 1) * sizeof(wchar_t));
|
||||
|
||||
if (string_utf8)
|
||||
{
|
||||
memset(string_utf8, 0, string_utf8_size + 1);
|
||||
WideCharToMultiByte(CP_UTF8, 0, string, -1, (char *)string_utf8, string_utf8_size, NULL, NULL);
|
||||
}
|
||||
|
||||
return string_utf8;
|
||||
}
|
||||
|
||||
void mz_os_utf8_string_delete(uint8_t **string)
|
||||
{
|
||||
if (string != NULL)
|
||||
{
|
||||
MZ_FREE(*string);
|
||||
*string = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t mz_os_rand(uint8_t *buf, int32_t size)
|
||||
{
|
||||
HCRYPTPROV provider;
|
||||
unsigned __int64 pentium_tsc[1];
|
||||
int32_t len = 0;
|
||||
int32_t result = 0;
|
||||
|
||||
|
||||
if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
|
||||
{
|
||||
result = CryptGenRandom(provider, size, buf);
|
||||
CryptReleaseContext(provider, 0);
|
||||
if (result)
|
||||
return size;
|
||||
}
|
||||
|
||||
for (len = 0; len < (int)size; len += 1)
|
||||
{
|
||||
@@ -69,40 +132,81 @@ int32_t mz_win32_rand(uint8_t *buf, int32_t size)
|
||||
|
||||
return len;
|
||||
}
|
||||
#endif
|
||||
|
||||
wchar_t *mz_win32_unicode_path_create(const char *path)
|
||||
int32_t mz_os_rename(const char *source_path, const char *target_path)
|
||||
{
|
||||
wchar_t *source_path_wide = NULL;
|
||||
wchar_t *target_path_wide = NULL;
|
||||
int32_t result = 0;
|
||||
int32_t err = MZ_OK;
|
||||
|
||||
if (source_path == NULL || target_path == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
source_path_wide = mz_os_unicode_string_create(source_path, MZ_ENCODING_UTF8);
|
||||
if (source_path_wide == NULL)
|
||||
{
|
||||
err = MZ_PARAM_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
target_path_wide = mz_os_unicode_string_create(target_path, MZ_ENCODING_UTF8);
|
||||
if (target_path_wide == NULL)
|
||||
err = MZ_PARAM_ERROR;
|
||||
}
|
||||
|
||||
if (err == MZ_OK)
|
||||
{
|
||||
result = MoveFileW(source_path_wide, target_path_wide);
|
||||
if (result == 0)
|
||||
err = MZ_EXIST_ERROR;
|
||||
}
|
||||
|
||||
if (target_path_wide)
|
||||
mz_os_unicode_string_delete(&target_path_wide);
|
||||
if (source_path_wide)
|
||||
mz_os_unicode_string_delete(&source_path_wide);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int32_t mz_os_unlink(const char *path)
|
||||
{
|
||||
wchar_t *path_wide = NULL;
|
||||
uint32_t path_wide_size = 0;
|
||||
int32_t result = 0;
|
||||
|
||||
path_wide_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
|
||||
path_wide = (wchar_t *)MZ_ALLOC((path_wide_size + 1) * sizeof(wchar_t));
|
||||
memset(path_wide, 0, sizeof(wchar_t) * (path_wide_size + 1));
|
||||
if (path == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
|
||||
if (path_wide == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
MultiByteToWideChar(CP_UTF8, 0, path, -1, path_wide, path_wide_size);
|
||||
if (mz_os_is_dir(path) == MZ_OK)
|
||||
result = RemoveDirectoryW(path_wide);
|
||||
else
|
||||
result = DeleteFileW(path_wide);
|
||||
|
||||
return path_wide;
|
||||
mz_os_unicode_string_delete(&path_wide);
|
||||
|
||||
if (result == 0)
|
||||
return MZ_EXIST_ERROR;
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
void mz_win32_unicode_path_delete(wchar_t **path)
|
||||
{
|
||||
if (path != NULL)
|
||||
{
|
||||
MZ_FREE(*path);
|
||||
*path = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t mz_win32_file_exists(const char *path)
|
||||
int32_t mz_os_file_exists(const char *path)
|
||||
{
|
||||
wchar_t *path_wide = NULL;
|
||||
DWORD attribs = 0;
|
||||
|
||||
if (path == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
|
||||
if (path_wide == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
path_wide = mz_win32_unicode_path_create(path);
|
||||
attribs = GetFileAttributesW(path_wide);
|
||||
mz_win32_unicode_path_delete(&path_wide);
|
||||
mz_os_unicode_string_delete(&path_wide);
|
||||
|
||||
if (attribs == 0xFFFFFFFF)
|
||||
return MZ_EXIST_ERROR;
|
||||
@@ -110,20 +214,23 @@ int32_t mz_win32_file_exists(const char *path)
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int64_t mz_win32_get_file_size(const char *path)
|
||||
int64_t mz_os_get_file_size(const char *path)
|
||||
{
|
||||
HANDLE handle = NULL;
|
||||
LARGE_INTEGER large_size;
|
||||
wchar_t *path_wide = NULL;
|
||||
|
||||
|
||||
path_wide = mz_win32_unicode_path_create(path);
|
||||
if (path == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
|
||||
if (path_wide == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
#ifdef MZ_WINRT_API
|
||||
handle = CreateFile2W(path_wide, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
#else
|
||||
handle = CreateFileW(path_wide, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
#endif
|
||||
mz_win32_unicode_path_delete(&path_wide);
|
||||
mz_os_unicode_string_delete(&path_wide);
|
||||
|
||||
large_size.QuadPart = 0;
|
||||
|
||||
@@ -136,7 +243,7 @@ int64_t mz_win32_get_file_size(const char *path)
|
||||
return large_size.QuadPart;
|
||||
}
|
||||
|
||||
static void mz_win32_file_to_unix_time(FILETIME file_time, time_t *unix_time)
|
||||
static void mz_os_file_to_unix_time(FILETIME file_time, time_t *unix_time)
|
||||
{
|
||||
uint64_t quad_file_time = 0;
|
||||
quad_file_time = file_time.dwLowDateTime;
|
||||
@@ -144,7 +251,7 @@ static void mz_win32_file_to_unix_time(FILETIME file_time, time_t *unix_time)
|
||||
*unix_time = (time_t)((quad_file_time - 116444736000000000LL) / 10000000);
|
||||
}
|
||||
|
||||
static void mz_win32_unix_to_file_time(time_t unix_time, FILETIME *file_time)
|
||||
static void mz_os_unix_to_file_time(time_t unix_time, FILETIME *file_time)
|
||||
{
|
||||
uint64_t quad_file_time = 0;
|
||||
quad_file_time = ((uint64_t)unix_time * 10000000) + 116444736000000000LL;
|
||||
@@ -152,25 +259,30 @@ static void mz_win32_unix_to_file_time(time_t unix_time, FILETIME *file_time)
|
||||
file_time->dwLowDateTime = (uint32_t)(quad_file_time);
|
||||
}
|
||||
|
||||
int32_t mz_win32_get_file_date(const char *path, time_t *modified_date, time_t *accessed_date, time_t *creation_date)
|
||||
int32_t mz_os_get_file_date(const char *path, time_t *modified_date, time_t *accessed_date, time_t *creation_date)
|
||||
{
|
||||
WIN32_FIND_DATAW ff32;
|
||||
HANDLE handle = NULL;
|
||||
wchar_t *path_wide = NULL;
|
||||
int32_t err = MZ_INTERNAL_ERROR;
|
||||
|
||||
path_wide = mz_win32_unicode_path_create(path);
|
||||
if (path == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
|
||||
if (path_wide == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
handle = FindFirstFileW(path_wide, &ff32);
|
||||
MZ_FREE(path_wide);
|
||||
|
||||
if (handle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (modified_date != NULL)
|
||||
mz_win32_file_to_unix_time(ff32.ftLastWriteTime, modified_date);
|
||||
mz_os_file_to_unix_time(ff32.ftLastWriteTime, modified_date);
|
||||
if (accessed_date != NULL)
|
||||
mz_win32_file_to_unix_time(ff32.ftLastAccessTime, accessed_date);
|
||||
mz_os_file_to_unix_time(ff32.ftLastAccessTime, accessed_date);
|
||||
if (creation_date != NULL)
|
||||
mz_win32_file_to_unix_time(ff32.ftCreationTime, creation_date);
|
||||
mz_os_file_to_unix_time(ff32.ftCreationTime, creation_date);
|
||||
|
||||
FindClose(handle);
|
||||
err = MZ_OK;
|
||||
@@ -179,32 +291,36 @@ int32_t mz_win32_get_file_date(const char *path, time_t *modified_date, time_t *
|
||||
return err;
|
||||
}
|
||||
|
||||
int32_t mz_win32_set_file_date(const char *path, time_t modified_date, time_t accessed_date, time_t creation_date)
|
||||
int32_t mz_os_set_file_date(const char *path, time_t modified_date, time_t accessed_date, time_t creation_date)
|
||||
{
|
||||
HANDLE handle = NULL;
|
||||
FILETIME ftm_creation, ftm_accessed, ftm_modified;
|
||||
wchar_t *path_wide = NULL;
|
||||
int32_t err = MZ_OK;
|
||||
|
||||
if (path == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
|
||||
if (path_wide == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
path_wide = mz_win32_unicode_path_create(path);
|
||||
#ifdef MZ_WINRT_API
|
||||
handle = CreateFile2W(path_wide, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
#else
|
||||
handle = CreateFileW(path_wide, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
#endif
|
||||
mz_win32_unicode_path_delete(&path_wide);
|
||||
mz_os_unicode_string_delete(&path_wide);
|
||||
|
||||
if (handle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
GetFileTime(handle, &ftm_creation, &ftm_accessed, &ftm_modified);
|
||||
|
||||
if (modified_date != 0)
|
||||
mz_win32_unix_to_file_time(modified_date, &ftm_modified);
|
||||
mz_os_unix_to_file_time(modified_date, &ftm_modified);
|
||||
if (accessed_date != 0)
|
||||
mz_win32_unix_to_file_time(accessed_date, &ftm_accessed);
|
||||
mz_os_unix_to_file_time(accessed_date, &ftm_accessed);
|
||||
if (creation_date != 0)
|
||||
mz_win32_unix_to_file_time(creation_date, &ftm_creation);
|
||||
mz_os_unix_to_file_time(creation_date, &ftm_creation);
|
||||
|
||||
if (SetFileTime(handle, &ftm_creation, &ftm_accessed, &ftm_modified) == 0)
|
||||
err = MZ_INTERNAL_ERROR;
|
||||
@@ -215,14 +331,19 @@ int32_t mz_win32_set_file_date(const char *path, time_t modified_date, time_t ac
|
||||
return err;
|
||||
}
|
||||
|
||||
int32_t mz_win32_get_file_attribs(const char *path, uint32_t *attributes)
|
||||
int32_t mz_os_get_file_attribs(const char *path, uint32_t *attributes)
|
||||
{
|
||||
wchar_t *path_wide = NULL;
|
||||
int32_t err = MZ_OK;
|
||||
|
||||
path_wide = mz_win32_unicode_path_create(path);
|
||||
if (path == NULL || attributes == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
|
||||
if (path_wide == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
*attributes = GetFileAttributesW(path_wide);
|
||||
MZ_FREE(path_wide);
|
||||
mz_os_unicode_string_delete(&path_wide);
|
||||
|
||||
if (*attributes == INVALID_FILE_ATTRIBUTES)
|
||||
err = MZ_INTERNAL_ERROR;
|
||||
@@ -230,36 +351,52 @@ int32_t mz_win32_get_file_attribs(const char *path, uint32_t *attributes)
|
||||
return err;
|
||||
}
|
||||
|
||||
int32_t mz_win32_set_file_attribs(const char *path, uint32_t attributes)
|
||||
int32_t mz_os_set_file_attribs(const char *path, uint32_t attributes)
|
||||
{
|
||||
wchar_t *path_wide = NULL;
|
||||
int32_t err = MZ_OK;
|
||||
|
||||
path_wide = mz_win32_unicode_path_create(path);
|
||||
if (path == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
|
||||
if (path_wide == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
if (SetFileAttributesW(path_wide, attributes) == 0)
|
||||
err = MZ_INTERNAL_ERROR;
|
||||
MZ_FREE(path_wide);
|
||||
mz_os_unicode_string_delete(&path_wide);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int32_t mz_win32_make_dir(const char *path)
|
||||
int32_t mz_os_make_dir(const char *path)
|
||||
{
|
||||
wchar_t *path_wide = NULL;
|
||||
int32_t err = 0;
|
||||
int32_t err = MZ_OK;
|
||||
|
||||
if (path == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
path_wide = mz_win32_unicode_path_create(path);
|
||||
err = _wmkdir(path_wide);
|
||||
mz_win32_unicode_path_delete(&path_wide);
|
||||
/* Don't try to create a drive letter */
|
||||
if ((path[0] != 0) && (strlen(path) <= 3) && (path[1] == ':'))
|
||||
return mz_os_is_dir(path);
|
||||
|
||||
if (err != 0 && errno != EEXIST)
|
||||
return MZ_INTERNAL_ERROR;
|
||||
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
|
||||
if (path_wide == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
return MZ_OK;
|
||||
if (CreateDirectoryW(path_wide, NULL) == 0)
|
||||
{
|
||||
if (GetLastError() != ERROR_ALREADY_EXISTS)
|
||||
err = MZ_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
mz_os_unicode_string_delete(&path_wide);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
DIR *mz_win32_open_dir(const char *path)
|
||||
DIR *mz_os_open_dir(const char *path)
|
||||
{
|
||||
WIN32_FIND_DATAW find_data;
|
||||
DIR_int *dir_int = NULL;
|
||||
@@ -268,18 +405,28 @@ DIR *mz_win32_open_dir(const char *path)
|
||||
void *handle = NULL;
|
||||
|
||||
|
||||
fixed_path[0] = 0;
|
||||
mz_path_combine(fixed_path, path, sizeof(fixed_path));
|
||||
if (path == NULL)
|
||||
return NULL;
|
||||
|
||||
strncpy(fixed_path, path, sizeof(fixed_path) - 1);
|
||||
fixed_path[sizeof(fixed_path) - 1] = 0;
|
||||
|
||||
mz_path_append_slash(fixed_path, sizeof(fixed_path), MZ_PATH_SLASH_PLATFORM);
|
||||
mz_path_combine(fixed_path, "*", sizeof(fixed_path));
|
||||
|
||||
path_wide = mz_win32_unicode_path_create(fixed_path);
|
||||
path_wide = mz_os_unicode_string_create(fixed_path, MZ_ENCODING_UTF8);
|
||||
if (path_wide == NULL)
|
||||
return NULL;
|
||||
|
||||
handle = FindFirstFileW(path_wide, &find_data);
|
||||
mz_win32_unicode_path_delete(&path_wide);
|
||||
mz_os_unicode_string_delete(&path_wide);
|
||||
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
return NULL;
|
||||
|
||||
dir_int = (DIR_int *)MZ_ALLOC(sizeof(DIR_int));
|
||||
if (dir_int == NULL)
|
||||
return NULL;
|
||||
dir_int->find_handle = handle;
|
||||
dir_int->end = 0;
|
||||
|
||||
@@ -288,7 +435,7 @@ DIR *mz_win32_open_dir(const char *path)
|
||||
return (DIR *)dir_int;
|
||||
}
|
||||
|
||||
struct dirent* mz_win32_read_dir(DIR *dir)
|
||||
struct dirent* mz_os_read_dir(DIR *dir)
|
||||
{
|
||||
DIR_int *dir_int;
|
||||
|
||||
@@ -313,7 +460,7 @@ struct dirent* mz_win32_read_dir(DIR *dir)
|
||||
return &dir_int->entry;
|
||||
}
|
||||
|
||||
int32_t mz_win32_close_dir(DIR *dir)
|
||||
int32_t mz_os_close_dir(DIR *dir)
|
||||
{
|
||||
DIR_int *dir_int;
|
||||
|
||||
@@ -327,14 +474,19 @@ int32_t mz_win32_close_dir(DIR *dir)
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_win32_is_dir(const char *path)
|
||||
int32_t mz_os_is_dir(const char *path)
|
||||
{
|
||||
wchar_t *path_wide = NULL;
|
||||
uint32_t attribs = 0;
|
||||
|
||||
path_wide = mz_win32_unicode_path_create(path);
|
||||
if (path == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
|
||||
if (path_wide == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
attribs = GetFileAttributesW(path_wide);
|
||||
mz_win32_unicode_path_delete(&path_wide);
|
||||
mz_os_unicode_string_delete(&path_wide);
|
||||
|
||||
if (attribs != 0xFFFFFFFF)
|
||||
{
|
||||
@@ -344,3 +496,199 @@ int32_t mz_win32_is_dir(const char *path)
|
||||
|
||||
return MZ_EXIST_ERROR;
|
||||
}
|
||||
|
||||
int32_t mz_os_is_symlink(const char *path)
|
||||
{
|
||||
wchar_t *path_wide = NULL;
|
||||
uint32_t attribs = 0;
|
||||
|
||||
if (path == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
|
||||
if (path_wide == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
attribs = GetFileAttributesW(path_wide);
|
||||
mz_os_unicode_string_delete(&path_wide);
|
||||
|
||||
if (attribs != 0xFFFFFFFF)
|
||||
{
|
||||
if (attribs & FILE_ATTRIBUTE_REPARSE_POINT)
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
return MZ_EXIST_ERROR;
|
||||
}
|
||||
|
||||
int32_t mz_os_make_symlink(const char *path, const char *target_path)
|
||||
{
|
||||
typedef BOOLEAN (WINAPI *LPCREATESYMBOLICLINKW)(LPCWSTR, LPCWSTR, DWORD);
|
||||
LPCREATESYMBOLICLINKW create_symbolic_link_w = NULL;
|
||||
HMODULE kernel32_mod = NULL;
|
||||
wchar_t *path_wide = NULL;
|
||||
wchar_t *target_path_wide = NULL;
|
||||
uint32_t attribs = 0;
|
||||
int32_t target_path_len = 0;
|
||||
int32_t err = MZ_OK;
|
||||
int32_t flags = 0;
|
||||
|
||||
if (path == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
kernel32_mod = GetModuleHandleW(L"kernel32.dll");
|
||||
if (kernel32_mod == NULL)
|
||||
return MZ_SUPPORT_ERROR;
|
||||
|
||||
create_symbolic_link_w = (LPCREATESYMBOLICLINKW)GetProcAddress(kernel32_mod, "CreateSymbolicLinkW");
|
||||
if (create_symbolic_link_w == NULL)
|
||||
{
|
||||
return MZ_SUPPORT_ERROR;
|
||||
}
|
||||
|
||||
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
|
||||
if (path_wide == NULL)
|
||||
{
|
||||
return MZ_PARAM_ERROR;
|
||||
}
|
||||
|
||||
target_path_wide = mz_os_unicode_string_create(target_path, MZ_ENCODING_UTF8);
|
||||
if (target_path_wide != NULL)
|
||||
{
|
||||
if (mz_path_has_slash(target_path) == MZ_OK)
|
||||
flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
|
||||
|
||||
if (create_symbolic_link_w(path_wide, target_path_wide, flags) == FALSE)
|
||||
err = MZ_SYMLINK_ERROR;
|
||||
|
||||
mz_os_unicode_string_delete(&target_path_wide);
|
||||
}
|
||||
else
|
||||
{
|
||||
err = MZ_PARAM_ERROR;
|
||||
}
|
||||
|
||||
mz_os_unicode_string_delete(&path_wide);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int32_t mz_os_read_symlink(const char *path, char *target_path, int32_t max_target_path)
|
||||
{
|
||||
typedef struct _REPARSE_DATA_BUFFER {
|
||||
ULONG ReparseTag;
|
||||
USHORT ReparseDataLength;
|
||||
USHORT Reserved;
|
||||
union {
|
||||
struct {
|
||||
USHORT SubstituteNameOffset;
|
||||
USHORT SubstituteNameLength;
|
||||
USHORT PrintNameOffset;
|
||||
USHORT PrintNameLength;
|
||||
ULONG Flags;
|
||||
WCHAR PathBuffer[1];
|
||||
} SymbolicLinkReparseBuffer;
|
||||
struct {
|
||||
USHORT SubstituteNameOffset;
|
||||
USHORT SubstituteNameLength;
|
||||
USHORT PrintNameOffset;
|
||||
USHORT PrintNameLength;
|
||||
WCHAR PathBuffer[1];
|
||||
} MountPointReparseBuffer;
|
||||
struct {
|
||||
UCHAR DataBuffer[1];
|
||||
} GenericReparseBuffer;
|
||||
};
|
||||
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
|
||||
REPARSE_DATA_BUFFER *reparse_data = NULL;
|
||||
DWORD length = 0;
|
||||
HANDLE handle = NULL;
|
||||
wchar_t *path_wide = NULL;
|
||||
wchar_t *target_path_wide = NULL;
|
||||
uint32_t attribs = 0;
|
||||
uint8_t buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
|
||||
int32_t target_path_len = 0;
|
||||
int32_t target_path_idx = 0;
|
||||
int32_t err = MZ_OK;
|
||||
uint8_t *target_path_utf8 = NULL;
|
||||
|
||||
if (path == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
|
||||
if (path_wide == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
handle = CreateFileW(path_wide, FILE_READ_EA, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
|
||||
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
mz_os_unicode_string_delete(&path_wide);
|
||||
return MZ_OPEN_ERROR;
|
||||
}
|
||||
|
||||
if (DeviceIoControl(handle, FSCTL_GET_REPARSE_POINT, NULL, 0, buffer, sizeof(buffer), &length, NULL) == TRUE)
|
||||
{
|
||||
reparse_data = (REPARSE_DATA_BUFFER *)buffer;
|
||||
if ((IsReparseTagMicrosoft(reparse_data->ReparseTag)) &&
|
||||
(reparse_data->ReparseTag == IO_REPARSE_TAG_SYMLINK))
|
||||
{
|
||||
target_path_len = max_target_path * sizeof(wchar_t);
|
||||
if (target_path_len > reparse_data->SymbolicLinkReparseBuffer.PrintNameLength)
|
||||
target_path_len = reparse_data->SymbolicLinkReparseBuffer.PrintNameLength;
|
||||
|
||||
target_path_wide = (wchar_t *)MZ_ALLOC(target_path_len + sizeof(wchar_t));
|
||||
if (target_path_wide)
|
||||
{
|
||||
target_path_idx = reparse_data->SymbolicLinkReparseBuffer.PrintNameOffset / sizeof(wchar_t);
|
||||
memcpy(target_path_wide, &reparse_data->SymbolicLinkReparseBuffer.PathBuffer[target_path_idx],
|
||||
target_path_len);
|
||||
|
||||
target_path_wide[target_path_len / sizeof(wchar_t)] = 0;
|
||||
target_path_utf8 = mz_os_utf8_string_create_from_unicode(target_path_wide, MZ_ENCODING_UTF8);
|
||||
|
||||
if (target_path_utf8)
|
||||
{
|
||||
strncpy(target_path, (const char *)target_path_utf8, max_target_path - 1);
|
||||
target_path[max_target_path - 1] = 0;
|
||||
/* Ensure directories have slash at the end so we can recreate them later */
|
||||
if (mz_os_is_dir((const char *)target_path_utf8) == MZ_OK)
|
||||
mz_path_append_slash(target_path, max_target_path, MZ_PATH_SLASH_PLATFORM);
|
||||
mz_os_utf8_string_delete(&target_path_utf8);
|
||||
}
|
||||
else
|
||||
{
|
||||
err = MZ_MEM_ERROR;
|
||||
}
|
||||
|
||||
MZ_FREE(target_path_wide);
|
||||
}
|
||||
else
|
||||
{
|
||||
err = MZ_MEM_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
err = MZ_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
CloseHandle(handle);
|
||||
mz_os_unicode_string_delete(&path_wide);
|
||||
return err;
|
||||
}
|
||||
|
||||
uint64_t mz_os_ms_time(void)
|
||||
{
|
||||
SYSTEMTIME system_time;
|
||||
FILETIME file_time;
|
||||
uint64_t quad_file_time = 0;
|
||||
|
||||
GetSystemTime(&system_time);
|
||||
SystemTimeToFileTime(&system_time, &file_time);
|
||||
|
||||
quad_file_time = file_time.dwLowDateTime;
|
||||
quad_file_time |= ((uint64_t)file_time.dwHighDateTime << 32);
|
||||
|
||||
return quad_file_time / 10000 - 11644473600000LL;
|
||||
}
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
/* mz_os_win32.h -- System functions for Windows
|
||||
Version 2.3.6, July 11, 2018
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2018 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
See the accompanying LICENSE file for the full text of the license.
|
||||
*/
|
||||
|
||||
#ifndef MZ_OS_WIN32_H
|
||||
#define MZ_OS_WIN32_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#define MZ_VERSION_MADEBY_HOST_SYSTEM (MZ_HOST_SYSTEM_WINDOWS_NTFS)
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
struct dirent {
|
||||
char d_name[256];
|
||||
};
|
||||
typedef void* DIR;
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t mz_win32_rand(uint8_t *buf, int32_t size);
|
||||
int32_t mz_win32_file_exists(const char *path);
|
||||
int64_t mz_win32_get_file_size(const char *path);
|
||||
int32_t mz_win32_get_file_date(const char *path, time_t *modified_date, time_t *accessed_date, time_t *creation_date);
|
||||
int32_t mz_win32_set_file_date(const char *path, time_t modified_date, time_t accessed_date, time_t creation_date);
|
||||
int32_t mz_win32_get_file_attribs(const char *path, uint32_t *attributes);
|
||||
int32_t mz_win32_set_file_attribs(const char *path, uint32_t attributes);
|
||||
int32_t mz_win32_make_dir(const char *path);
|
||||
DIR* mz_win32_open_dir(const char *path);
|
||||
struct
|
||||
dirent* mz_win32_read_dir(DIR *dir);
|
||||
int32_t mz_win32_close_dir(DIR *dir);
|
||||
int32_t mz_win32_is_dir(const char *path);
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#define mz_os_rand mz_win32_rand
|
||||
#define mz_os_file_exists mz_win32_file_exists
|
||||
#define mz_os_get_file_size mz_win32_get_file_size
|
||||
#define mz_os_get_file_date mz_win32_get_file_date
|
||||
#define mz_os_set_file_date mz_win32_set_file_date
|
||||
#define mz_os_get_file_attribs mz_win32_get_file_attribs
|
||||
#define mz_os_set_file_attribs mz_win32_set_file_attribs
|
||||
#define mz_os_make_dir mz_win32_make_dir
|
||||
#define mz_os_open_dir mz_win32_open_dir
|
||||
#define mz_os_read_dir mz_win32_read_dir
|
||||
#define mz_os_close_dir mz_win32_close_dir
|
||||
#define mz_os_is_dir mz_win32_is_dir
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,23 +1,23 @@
|
||||
/* mz_strm.c -- Stream interface
|
||||
Version 2.3.6, July 11, 2018
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2018 Nathan Moinvaziri
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
See the accompanying LICENSE file for the full text of the license.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mz.h"
|
||||
#include "mz_strm.h"
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#define MZ_STREAM_FIND_SIZE (1024)
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t mz_stream_open(void *stream, const char *path, int32_t mode)
|
||||
{
|
||||
mz_stream *strm = (mz_stream *)stream;
|
||||
@@ -100,6 +100,11 @@ int32_t mz_stream_read_uint32(void *stream, uint32_t *value)
|
||||
return err;
|
||||
}
|
||||
|
||||
int32_t mz_stream_read_int64(void *stream, int64_t *value)
|
||||
{
|
||||
return mz_stream_read_value(stream, (uint64_t *)value, sizeof(uint64_t));
|
||||
}
|
||||
|
||||
int32_t mz_stream_read_uint64(void *stream, uint64_t *value)
|
||||
{
|
||||
return mz_stream_read_value(stream, value, sizeof(uint64_t));
|
||||
@@ -130,7 +135,7 @@ static int32_t mz_stream_write_value(void *stream, uint64_t value, int32_t len)
|
||||
|
||||
if (value != 0)
|
||||
{
|
||||
// Data overflow - hack for ZIP64 (X Roche)
|
||||
/* Data overflow - hack for ZIP64 (X Roche) */
|
||||
for (n = 0; n < len; n += 1)
|
||||
buf[n] = 0xff;
|
||||
}
|
||||
@@ -156,6 +161,11 @@ int32_t mz_stream_write_uint32(void *stream, uint32_t value)
|
||||
return mz_stream_write_value(stream, value, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
int32_t mz_stream_write_int64(void *stream, int64_t value)
|
||||
{
|
||||
return mz_stream_write_value(stream, (uint64_t)value, sizeof(uint64_t));
|
||||
}
|
||||
|
||||
int32_t mz_stream_write_uint64(void *stream, uint64_t value)
|
||||
{
|
||||
return mz_stream_write_value(stream, value, sizeof(uint64_t));
|
||||
@@ -163,20 +173,36 @@ int32_t mz_stream_write_uint64(void *stream, uint64_t value)
|
||||
|
||||
int32_t mz_stream_copy(void *target, void *source, int32_t len)
|
||||
{
|
||||
uint8_t buf[INT16_MAX];
|
||||
return mz_stream_copy_stream(target, NULL, source, NULL, len);
|
||||
}
|
||||
|
||||
int32_t mz_stream_copy_to_end(void *target, void *source)
|
||||
{
|
||||
return mz_stream_copy_stream_to_end(target, NULL, source, NULL);
|
||||
}
|
||||
|
||||
int32_t mz_stream_copy_stream(void *target, mz_stream_write_cb write_cb, void *source,
|
||||
mz_stream_read_cb read_cb, int32_t len)
|
||||
{
|
||||
uint8_t buf[16384];
|
||||
int32_t bytes_to_copy = 0;
|
||||
int32_t read = 0;
|
||||
int32_t written = 0;
|
||||
|
||||
if (write_cb == NULL)
|
||||
write_cb = mz_stream_write;
|
||||
if (read_cb == NULL)
|
||||
read_cb = mz_stream_read;
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
bytes_to_copy = len;
|
||||
if (bytes_to_copy > (int32_t)sizeof(buf))
|
||||
bytes_to_copy = sizeof(buf);
|
||||
read = mz_stream_read(source, buf, bytes_to_copy);
|
||||
if (read < 0)
|
||||
read = read_cb(source, buf, bytes_to_copy);
|
||||
if (read <= 0)
|
||||
return MZ_STREAM_ERROR;
|
||||
written = mz_stream_write(target, buf, read);
|
||||
written = write_cb(target, buf, read);
|
||||
if (written != read)
|
||||
return MZ_STREAM_ERROR;
|
||||
len -= read;
|
||||
@@ -185,6 +211,33 @@ int32_t mz_stream_copy(void *target, void *source, int32_t len)
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_stream_copy_stream_to_end(void *target, mz_stream_write_cb write_cb, void *source,
|
||||
mz_stream_read_cb read_cb)
|
||||
{
|
||||
uint8_t buf[16384];
|
||||
int32_t read = 0;
|
||||
int32_t written = 0;
|
||||
|
||||
if (write_cb == NULL)
|
||||
write_cb = mz_stream_write;
|
||||
if (read_cb == NULL)
|
||||
read_cb = mz_stream_read;
|
||||
|
||||
read = read_cb(source, buf, sizeof(buf));
|
||||
while (read > 0)
|
||||
{
|
||||
written = write_cb(target, buf, read);
|
||||
if (written != read)
|
||||
return MZ_STREAM_ERROR;
|
||||
read = read_cb(source, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
if (read < 0)
|
||||
return MZ_STREAM_ERROR;
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int64_t mz_stream_tell(void *stream)
|
||||
{
|
||||
mz_stream *strm = (mz_stream *)stream;
|
||||
@@ -202,9 +255,142 @@ int32_t mz_stream_seek(void *stream, int64_t offset, int32_t origin)
|
||||
return MZ_PARAM_ERROR;
|
||||
if (mz_stream_is_open(stream) != MZ_OK)
|
||||
return MZ_STREAM_ERROR;
|
||||
if (origin == MZ_SEEK_SET && offset < 0)
|
||||
return MZ_SEEK_ERROR;
|
||||
return strm->vtbl->seek(strm, offset, origin);
|
||||
}
|
||||
|
||||
int32_t mz_stream_find(void *stream, const void *find, int32_t find_size, int64_t max_seek, int64_t *position)
|
||||
{
|
||||
uint8_t buf[MZ_STREAM_FIND_SIZE];
|
||||
int32_t buf_pos = 0;
|
||||
int32_t read_size = sizeof(buf);
|
||||
int32_t read = 0;
|
||||
int64_t read_pos = 0;
|
||||
int64_t start_pos = 0;
|
||||
int64_t disk_pos = 0;
|
||||
int32_t i = 0;
|
||||
uint8_t first = 1;
|
||||
int32_t err = MZ_OK;
|
||||
|
||||
if (stream == NULL || find == NULL || position == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
if (find_size < 0 || find_size >= (int32_t)sizeof(buf))
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
*position = -1;
|
||||
|
||||
start_pos = mz_stream_tell(stream);
|
||||
|
||||
while (read_pos < max_seek)
|
||||
{
|
||||
if (read_size > (int32_t)(max_seek - read_pos - buf_pos) && (max_seek - read_pos - buf_pos) < (int64_t)sizeof(buf))
|
||||
read_size = (int32_t)(max_seek - read_pos - buf_pos);
|
||||
|
||||
read = mz_stream_read(stream, buf + buf_pos, read_size);
|
||||
if ((read <= 0) || (read + buf_pos < find_size))
|
||||
break;
|
||||
|
||||
for (i = 0; i <= read + buf_pos - find_size; i += 1)
|
||||
{
|
||||
if (memcmp(&buf[i], find, find_size) != 0)
|
||||
continue;
|
||||
|
||||
disk_pos = mz_stream_tell(stream);
|
||||
|
||||
/* Seek to position on disk where the data was found */
|
||||
err = mz_stream_seek(stream, disk_pos - ((int64_t)read + buf_pos - i), MZ_SEEK_SET);
|
||||
if (err != MZ_OK)
|
||||
return MZ_EXIST_ERROR;
|
||||
|
||||
*position = start_pos + read_pos + i;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
if (first)
|
||||
{
|
||||
read -= find_size;
|
||||
read_size -= find_size;
|
||||
buf_pos = find_size;
|
||||
first = 0;
|
||||
}
|
||||
|
||||
memmove(buf, buf + read, find_size);
|
||||
read_pos += read;
|
||||
}
|
||||
|
||||
return MZ_EXIST_ERROR;
|
||||
}
|
||||
|
||||
int32_t mz_stream_find_reverse(void *stream, const void *find, int32_t find_size, int64_t max_seek, int64_t *position)
|
||||
{
|
||||
uint8_t buf[MZ_STREAM_FIND_SIZE];
|
||||
int32_t buf_pos = 0;
|
||||
int32_t read_size = MZ_STREAM_FIND_SIZE;
|
||||
int64_t read_pos = 0;
|
||||
int32_t read = 0;
|
||||
int64_t start_pos = 0;
|
||||
int64_t disk_pos = 0;
|
||||
uint8_t first = 1;
|
||||
int32_t i = 0;
|
||||
int32_t err = MZ_OK;
|
||||
|
||||
if (stream == NULL || find == NULL || position == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
if (find_size < 0 || find_size >= (int32_t)sizeof(buf))
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
*position = -1;
|
||||
|
||||
start_pos = mz_stream_tell(stream);
|
||||
|
||||
while (read_pos < max_seek)
|
||||
{
|
||||
if (read_size > (int32_t)(max_seek - read_pos) && (max_seek - read_pos) < (int64_t)sizeof(buf))
|
||||
read_size = (int32_t)(max_seek - read_pos);
|
||||
|
||||
if (mz_stream_seek(stream, start_pos - (read_pos + read_size), MZ_SEEK_SET) != MZ_OK)
|
||||
break;
|
||||
read = mz_stream_read(stream, buf, read_size);
|
||||
if ((read <= 0) || (read + buf_pos < find_size))
|
||||
break;
|
||||
if (read + buf_pos < MZ_STREAM_FIND_SIZE)
|
||||
memmove(buf + MZ_STREAM_FIND_SIZE - (read + buf_pos), buf, read);
|
||||
|
||||
for (i = find_size; i <= (read + buf_pos); i += 1)
|
||||
{
|
||||
if (memcmp(&buf[MZ_STREAM_FIND_SIZE - i], find, find_size) != 0)
|
||||
continue;
|
||||
|
||||
disk_pos = mz_stream_tell(stream);
|
||||
|
||||
/* Seek to position on disk where the data was found */
|
||||
err = mz_stream_seek(stream, disk_pos + buf_pos - i, MZ_SEEK_SET);
|
||||
if (err != MZ_OK)
|
||||
return MZ_EXIST_ERROR;
|
||||
|
||||
*position = start_pos - (read_pos - buf_pos + i);
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
if (first)
|
||||
{
|
||||
read -= find_size;
|
||||
read_size -= find_size;
|
||||
buf_pos = find_size;
|
||||
first = 0;
|
||||
}
|
||||
|
||||
if (read == 0)
|
||||
break;
|
||||
|
||||
memmove(buf + read_size, buf, find_size);
|
||||
read_pos += read;
|
||||
}
|
||||
|
||||
return MZ_EXIST_ERROR;
|
||||
}
|
||||
|
||||
int32_t mz_stream_close(void *stream)
|
||||
{
|
||||
mz_stream *strm = (mz_stream *)stream;
|
||||
@@ -230,6 +416,14 @@ int32_t mz_stream_set_base(void *stream, void *base)
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
void* mz_stream_get_interface(void *stream)
|
||||
{
|
||||
mz_stream *strm = (mz_stream *)stream;
|
||||
if (strm == NULL || strm->vtbl == NULL)
|
||||
return NULL;
|
||||
return (void *)strm->vtbl;
|
||||
}
|
||||
|
||||
int32_t mz_stream_get_prop_int64(void *stream, int32_t prop, int64_t *value)
|
||||
{
|
||||
mz_stream *strm = (mz_stream *)stream;
|
||||
@@ -300,14 +494,17 @@ int32_t mz_stream_raw_read(void *stream, void *buf, int32_t size)
|
||||
|
||||
if (raw->max_total_in > 0)
|
||||
{
|
||||
if ((raw->max_total_in - raw->total_in) < size)
|
||||
if ((int64_t)bytes_to_read > (raw->max_total_in - raw->total_in))
|
||||
bytes_to_read = (int32_t)(raw->max_total_in - raw->total_in);
|
||||
}
|
||||
|
||||
read = mz_stream_read(raw->stream.base, buf, bytes_to_read);
|
||||
|
||||
if (read > 0)
|
||||
{
|
||||
raw->total_in += read;
|
||||
raw->total_out += read;
|
||||
}
|
||||
|
||||
return read;
|
||||
}
|
||||
@@ -315,9 +512,16 @@ int32_t mz_stream_raw_read(void *stream, void *buf, int32_t size)
|
||||
int32_t mz_stream_raw_write(void *stream, const void *buf, int32_t size)
|
||||
{
|
||||
mz_stream_raw *raw = (mz_stream_raw *)stream;
|
||||
int32_t written = mz_stream_write(raw->stream.base, buf, size);
|
||||
int32_t written = 0;
|
||||
|
||||
written = mz_stream_write(raw->stream.base, buf, size);
|
||||
|
||||
if (written > 0)
|
||||
{
|
||||
raw->total_out += written;
|
||||
raw->total_in += written;
|
||||
}
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
@@ -336,7 +540,6 @@ int32_t mz_stream_raw_seek(void *stream, int64_t offset, int32_t origin)
|
||||
int32_t mz_stream_raw_close(void *stream)
|
||||
{
|
||||
MZ_UNUSED(stream);
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/* mz_strm.h -- Stream interface
|
||||
Version 2.3.6, July 11, 2018
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2018 Nathan Moinvaziri
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
@@ -12,8 +12,6 @@
|
||||
#ifndef MZ_STREAM_H
|
||||
#define MZ_STREAM_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -29,6 +27,8 @@ extern "C" {
|
||||
#define MZ_STREAM_PROP_DISK_SIZE (7)
|
||||
#define MZ_STREAM_PROP_DISK_NUMBER (8)
|
||||
#define MZ_STREAM_PROP_COMPRESS_LEVEL (9)
|
||||
#define MZ_STREAM_PROP_COMPRESS_ALGORITHM (10)
|
||||
#define MZ_STREAM_PROP_COMPRESS_WINDOW (11)
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
@@ -46,6 +46,9 @@ typedef void (*mz_stream_destroy_cb) (void **stream);
|
||||
typedef int32_t (*mz_stream_get_prop_int64_cb) (void *stream, int32_t prop, int64_t *value);
|
||||
typedef int32_t (*mz_stream_set_prop_int64_cb) (void *stream, int32_t prop, int64_t value);
|
||||
|
||||
typedef int32_t (*mz_stream_find_cb) (void *stream, const void *find, int32_t find_size,
|
||||
int64_t max_seek, int64_t *position);
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
typedef struct mz_stream_vtbl_s
|
||||
@@ -78,19 +81,27 @@ int32_t mz_stream_read(void *stream, void *buf, int32_t size);
|
||||
int32_t mz_stream_read_uint8(void *stream, uint8_t *value);
|
||||
int32_t mz_stream_read_uint16(void *stream, uint16_t *value);
|
||||
int32_t mz_stream_read_uint32(void *stream, uint32_t *value);
|
||||
int32_t mz_stream_read_int64(void *stream, int64_t *value);
|
||||
int32_t mz_stream_read_uint64(void *stream, uint64_t *value);
|
||||
int32_t mz_stream_write(void *stream, const void *buf, int32_t size);
|
||||
int32_t mz_stream_write_uint8(void *stream, uint8_t value);
|
||||
int32_t mz_stream_write_uint16(void *stream, uint16_t value);
|
||||
int32_t mz_stream_write_uint32(void *stream, uint32_t value);
|
||||
int32_t mz_stream_write_int64(void *stream, int64_t value);
|
||||
int32_t mz_stream_write_uint64(void *stream, uint64_t value);
|
||||
int32_t mz_stream_copy(void *target, void *source, int32_t len);
|
||||
int32_t mz_stream_copy_to_end(void *target, void *source);
|
||||
int32_t mz_stream_copy_stream(void *target, mz_stream_write_cb write_cb, void *source, mz_stream_read_cb read_cb, int32_t len);
|
||||
int32_t mz_stream_copy_stream_to_end(void *target, mz_stream_write_cb write_cb, void *source, mz_stream_read_cb read_cb);
|
||||
int64_t mz_stream_tell(void *stream);
|
||||
int32_t mz_stream_seek(void *stream, int64_t offset, int32_t origin);
|
||||
int32_t mz_stream_find(void *stream, const void *find, int32_t find_size, int64_t max_seek, int64_t *position);
|
||||
int32_t mz_stream_find_reverse(void *stream, const void *find, int32_t find_size, int64_t max_seek, int64_t *position);
|
||||
int32_t mz_stream_close(void *stream);
|
||||
int32_t mz_stream_error(void *stream);
|
||||
|
||||
int32_t mz_stream_set_base(void *stream, void *base);
|
||||
void* mz_stream_get_interface(void *stream);
|
||||
int32_t mz_stream_get_prop_int64(void *stream, int32_t prop, int64_t *value);
|
||||
int32_t mz_stream_set_prop_int64(void *stream, int32_t prop, int64_t value);
|
||||
|
||||
|
||||
-371
@@ -1,371 +0,0 @@
|
||||
/* mz_strm_aes.c -- Stream for WinZip AES encryption
|
||||
Version 2.3.6, July 11, 2018
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2018 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
Copyright (C) 1998-2010 Brian Gladman, Worcester, UK
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
See the accompanying LICENSE file for the full text of the license.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "aes.h"
|
||||
#include "hmac.h"
|
||||
#include "pwd2key.h"
|
||||
|
||||
#include "mz.h"
|
||||
#include "mz_os.h"
|
||||
#include "mz_strm.h"
|
||||
#include "mz_strm_aes.h"
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#define MZ_AES_KEY_LENGTH(mode) (8 * (mode & 3) + 8)
|
||||
#define MZ_AES_KEY_LENGTH_MAX (32)
|
||||
#define MZ_AES_KEYING_ITERATIONS (1000)
|
||||
#define MZ_AES_SALT_LENGTH(mode) (4 * (mode & 3) + 4)
|
||||
#define MZ_AES_SALT_LENGTH_MAX (16)
|
||||
#define MZ_AES_MAC_LENGTH(mode) (10)
|
||||
#define MZ_AES_PW_LENGTH_MAX (128)
|
||||
#define MZ_AES_PW_VERIFY_SIZE (2)
|
||||
#define MZ_AES_AUTHCODE_SIZE (10)
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static mz_stream_vtbl mz_stream_aes_vtbl = {
|
||||
mz_stream_aes_open,
|
||||
mz_stream_aes_is_open,
|
||||
mz_stream_aes_read,
|
||||
mz_stream_aes_write,
|
||||
mz_stream_aes_tell,
|
||||
mz_stream_aes_seek,
|
||||
mz_stream_aes_close,
|
||||
mz_stream_aes_error,
|
||||
mz_stream_aes_create,
|
||||
mz_stream_aes_delete,
|
||||
mz_stream_aes_get_prop_int64,
|
||||
mz_stream_aes_set_prop_int64
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
typedef struct mz_stream_aes_s {
|
||||
mz_stream stream;
|
||||
int32_t mode;
|
||||
int32_t error;
|
||||
int16_t initialized;
|
||||
uint8_t buffer[INT16_MAX];
|
||||
int64_t total_in;
|
||||
int64_t max_total_in;
|
||||
int64_t total_out;
|
||||
int16_t encryption_mode;
|
||||
const char *password;
|
||||
aes_encrypt_ctx encr_ctx[1];
|
||||
hmac_ctx auth_ctx[1];
|
||||
uint8_t nonce[AES_BLOCK_SIZE];
|
||||
uint8_t encr_bfr[AES_BLOCK_SIZE];
|
||||
uint32_t encr_pos;
|
||||
} mz_stream_aes;
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t mz_stream_aes_open(void *stream, const char *path, int32_t mode)
|
||||
{
|
||||
mz_stream_aes *aes = (mz_stream_aes *)stream;
|
||||
uint8_t kbuf[2 * MZ_AES_KEY_LENGTH_MAX + MZ_AES_PW_VERIFY_SIZE];
|
||||
uint8_t verify[MZ_AES_PW_VERIFY_SIZE];
|
||||
uint8_t verify_expected[MZ_AES_PW_VERIFY_SIZE];
|
||||
uint8_t salt_value[MZ_AES_SALT_LENGTH_MAX];
|
||||
int32_t salt_length = 0;
|
||||
const char *password = path;
|
||||
int32_t password_length = 0;
|
||||
int32_t key_length = 0;
|
||||
|
||||
aes->total_in = 0;
|
||||
aes->total_out = 0;
|
||||
aes->initialized = 0;
|
||||
|
||||
if (mz_stream_is_open(aes->stream.base) != MZ_OK)
|
||||
return MZ_STREAM_ERROR;
|
||||
|
||||
if (password == NULL)
|
||||
password = aes->password;
|
||||
if (password == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
password_length = (int32_t)strlen(password);
|
||||
if (password_length > MZ_AES_PW_LENGTH_MAX)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
if (aes->encryption_mode < 1 || aes->encryption_mode > 3)
|
||||
return MZ_PARAM_ERROR;
|
||||
salt_length = MZ_AES_SALT_LENGTH(aes->encryption_mode);
|
||||
|
||||
if (mode & MZ_OPEN_MODE_WRITE)
|
||||
{
|
||||
mz_os_rand(salt_value, salt_length);
|
||||
}
|
||||
else if (mode & MZ_OPEN_MODE_READ)
|
||||
{
|
||||
if (mz_stream_read(aes->stream.base, salt_value, salt_length) != salt_length)
|
||||
return MZ_STREAM_ERROR;
|
||||
}
|
||||
|
||||
key_length = MZ_AES_KEY_LENGTH(aes->encryption_mode);
|
||||
// Derive the encryption and authentication keys and the password verifier
|
||||
derive_key((const uint8_t *)password, password_length, salt_value, salt_length,
|
||||
MZ_AES_KEYING_ITERATIONS, kbuf, 2 * key_length + MZ_AES_PW_VERIFY_SIZE);
|
||||
|
||||
// Initialize the encryption nonce and buffer pos
|
||||
aes->encr_pos = AES_BLOCK_SIZE;
|
||||
memset(aes->nonce, 0, AES_BLOCK_SIZE * sizeof(uint8_t));
|
||||
|
||||
// Initialize for encryption using key 1
|
||||
aes_encrypt_key(kbuf, key_length, aes->encr_ctx);
|
||||
|
||||
// Initialize for authentication using key 2
|
||||
hmac_sha_begin(HMAC_SHA1, aes->auth_ctx);
|
||||
hmac_sha_key(kbuf + key_length, key_length, aes->auth_ctx);
|
||||
|
||||
memcpy(verify, kbuf + 2 * key_length, MZ_AES_PW_VERIFY_SIZE);
|
||||
|
||||
if (mode & MZ_OPEN_MODE_WRITE)
|
||||
{
|
||||
if (mz_stream_write(aes->stream.base, salt_value, salt_length) != salt_length)
|
||||
return MZ_STREAM_ERROR;
|
||||
|
||||
aes->total_out += salt_length;
|
||||
|
||||
if (mz_stream_write(aes->stream.base, verify, MZ_AES_PW_VERIFY_SIZE) != MZ_AES_PW_VERIFY_SIZE)
|
||||
return MZ_STREAM_ERROR;
|
||||
|
||||
aes->total_out += MZ_AES_PW_VERIFY_SIZE;
|
||||
}
|
||||
else if (mode & MZ_OPEN_MODE_READ)
|
||||
{
|
||||
aes->total_in += salt_length;
|
||||
|
||||
if (mz_stream_read(aes->stream.base, verify_expected, MZ_AES_PW_VERIFY_SIZE) != MZ_AES_PW_VERIFY_SIZE)
|
||||
return MZ_STREAM_ERROR;
|
||||
|
||||
aes->total_in += MZ_AES_PW_VERIFY_SIZE;
|
||||
|
||||
if (memcmp(verify_expected, verify, MZ_AES_PW_VERIFY_SIZE) != 0)
|
||||
return MZ_PASSWORD_ERROR;
|
||||
}
|
||||
|
||||
aes->mode = mode;
|
||||
aes->initialized = 1;
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_stream_aes_is_open(void *stream)
|
||||
{
|
||||
mz_stream_aes *aes = (mz_stream_aes *)stream;
|
||||
if (aes->initialized == 0)
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
static int32_t mz_stream_aes_encrypt_data(void *stream, uint8_t *buf, int32_t size)
|
||||
{
|
||||
mz_stream_aes *aes = (mz_stream_aes *)stream;
|
||||
uint32_t pos = aes->encr_pos;
|
||||
uint32_t i = 0;
|
||||
|
||||
while (i < (uint32_t)size)
|
||||
{
|
||||
if (pos == AES_BLOCK_SIZE)
|
||||
{
|
||||
uint32_t j = 0;
|
||||
|
||||
// Increment encryption nonce
|
||||
while (j < 8 && !++aes->nonce[j])
|
||||
j += 1;
|
||||
|
||||
// Encrypt the nonce to form next xor buffer
|
||||
aes_encrypt(aes->nonce, aes->encr_bfr, aes->encr_ctx);
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
buf[i++] ^= aes->encr_bfr[pos++];
|
||||
}
|
||||
|
||||
aes->encr_pos = pos;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_stream_aes_read(void *stream, void *buf, int32_t size)
|
||||
{
|
||||
mz_stream_aes *aes = (mz_stream_aes *)stream;
|
||||
int32_t read = 0;
|
||||
read = mz_stream_read(aes->stream.base, buf, size);
|
||||
if (read > 0)
|
||||
{
|
||||
hmac_sha_data((uint8_t *)buf, read, aes->auth_ctx);
|
||||
mz_stream_aes_encrypt_data(stream, (uint8_t *)buf, read);
|
||||
}
|
||||
|
||||
aes->total_in += read;
|
||||
return read;
|
||||
}
|
||||
|
||||
int32_t mz_stream_aes_write(void *stream, const void *buf, int32_t size)
|
||||
{
|
||||
mz_stream_aes *aes = (mz_stream_aes *)stream;
|
||||
int32_t written = 0;
|
||||
|
||||
if (size > (int32_t)sizeof(aes->buffer))
|
||||
return MZ_STREAM_ERROR;
|
||||
|
||||
memcpy(aes->buffer, buf, size);
|
||||
mz_stream_aes_encrypt_data(stream, (uint8_t *)aes->buffer, size);
|
||||
hmac_sha_data((uint8_t *)aes->buffer, size, aes->auth_ctx);
|
||||
|
||||
written = mz_stream_write(aes->stream.base, aes->buffer, size);
|
||||
if (written > 0)
|
||||
aes->total_out += written;
|
||||
return written;
|
||||
}
|
||||
|
||||
int64_t mz_stream_aes_tell(void *stream)
|
||||
{
|
||||
mz_stream_aes *aes = (mz_stream_aes *)stream;
|
||||
return mz_stream_tell(aes->stream.base);
|
||||
}
|
||||
|
||||
int32_t mz_stream_aes_seek(void *stream, int64_t offset, int32_t origin)
|
||||
{
|
||||
mz_stream_aes *aes = (mz_stream_aes *)stream;
|
||||
return mz_stream_seek(aes->stream.base, offset, origin);
|
||||
}
|
||||
|
||||
int32_t mz_stream_aes_close(void *stream)
|
||||
{
|
||||
mz_stream_aes *aes = (mz_stream_aes *)stream;
|
||||
uint8_t authcode[MZ_AES_AUTHCODE_SIZE];
|
||||
uint8_t verify_authcode[MZ_AES_AUTHCODE_SIZE];
|
||||
|
||||
if (MZ_AES_MAC_LENGTH(aes->encryption_mode) != MZ_AES_AUTHCODE_SIZE)
|
||||
return MZ_STREAM_ERROR;
|
||||
hmac_sha_end(authcode, MZ_AES_MAC_LENGTH(aes->encryption_mode), aes->auth_ctx);
|
||||
|
||||
if (aes->mode & MZ_OPEN_MODE_WRITE)
|
||||
{
|
||||
if (mz_stream_write(aes->stream.base, authcode, MZ_AES_AUTHCODE_SIZE) != MZ_AES_AUTHCODE_SIZE)
|
||||
return MZ_STREAM_ERROR;
|
||||
|
||||
aes->total_out += MZ_AES_AUTHCODE_SIZE;
|
||||
}
|
||||
else if (aes->mode & MZ_OPEN_MODE_READ)
|
||||
{
|
||||
if (mz_stream_read(aes->stream.base, verify_authcode, MZ_AES_AUTHCODE_SIZE) != MZ_AES_AUTHCODE_SIZE)
|
||||
return MZ_STREAM_ERROR;
|
||||
|
||||
aes->total_in += MZ_AES_AUTHCODE_SIZE;
|
||||
|
||||
// If entire entry was not read this will fail
|
||||
if (memcmp(authcode, verify_authcode, MZ_AES_AUTHCODE_SIZE) != 0)
|
||||
return MZ_CRC_ERROR;
|
||||
}
|
||||
|
||||
aes->initialized = 0;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_stream_aes_error(void *stream)
|
||||
{
|
||||
mz_stream_aes *aes = (mz_stream_aes *)stream;
|
||||
return aes->error;
|
||||
}
|
||||
|
||||
void mz_stream_aes_set_password(void *stream, const char *password)
|
||||
{
|
||||
mz_stream_aes *aes = (mz_stream_aes *)stream;
|
||||
aes->password = password;
|
||||
}
|
||||
|
||||
void mz_stream_aes_set_encryption_mode(void *stream, int16_t encryption_mode)
|
||||
{
|
||||
mz_stream_aes *aes = (mz_stream_aes *)stream;
|
||||
aes->encryption_mode = encryption_mode;
|
||||
}
|
||||
|
||||
int32_t mz_stream_aes_get_prop_int64(void *stream, int32_t prop, int64_t *value)
|
||||
{
|
||||
mz_stream_aes *aes = (mz_stream_aes *)stream;
|
||||
switch (prop)
|
||||
{
|
||||
case MZ_STREAM_PROP_TOTAL_IN:
|
||||
*value = aes->total_in;
|
||||
break;
|
||||
case MZ_STREAM_PROP_TOTAL_OUT:
|
||||
*value = aes->total_out;
|
||||
break;
|
||||
case MZ_STREAM_PROP_TOTAL_IN_MAX:
|
||||
*value = aes->max_total_in;
|
||||
break;
|
||||
case MZ_STREAM_PROP_HEADER_SIZE:
|
||||
*value = MZ_AES_SALT_LENGTH(aes->encryption_mode) + MZ_AES_PW_VERIFY_SIZE;
|
||||
break;
|
||||
case MZ_STREAM_PROP_FOOTER_SIZE:
|
||||
*value = MZ_AES_AUTHCODE_SIZE;
|
||||
break;
|
||||
default:
|
||||
return MZ_EXIST_ERROR;
|
||||
}
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_stream_aes_set_prop_int64(void *stream, int32_t prop, int64_t value)
|
||||
{
|
||||
mz_stream_aes *aes = (mz_stream_aes *)stream;
|
||||
switch (prop)
|
||||
{
|
||||
case MZ_STREAM_PROP_TOTAL_IN_MAX:
|
||||
aes->max_total_in = value;
|
||||
break;
|
||||
default:
|
||||
return MZ_EXIST_ERROR;
|
||||
}
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
void *mz_stream_aes_create(void **stream)
|
||||
{
|
||||
mz_stream_aes *aes = NULL;
|
||||
|
||||
aes = (mz_stream_aes *)MZ_ALLOC(sizeof(mz_stream_aes));
|
||||
if (aes != NULL)
|
||||
{
|
||||
memset(aes, 0, sizeof(mz_stream_aes));
|
||||
aes->stream.vtbl = &mz_stream_aes_vtbl;
|
||||
aes->encryption_mode = MZ_AES_ENCRYPTION_MODE_256;
|
||||
}
|
||||
if (stream != NULL)
|
||||
*stream = aes;
|
||||
|
||||
return aes;
|
||||
}
|
||||
|
||||
void mz_stream_aes_delete(void **stream)
|
||||
{
|
||||
mz_stream_aes *aes = NULL;
|
||||
if (stream == NULL)
|
||||
return;
|
||||
aes = (mz_stream_aes *)*stream;
|
||||
if (aes != NULL)
|
||||
MZ_FREE(aes);
|
||||
*stream = NULL;
|
||||
}
|
||||
|
||||
void *mz_stream_aes_get_interface(void)
|
||||
{
|
||||
return (void *)&mz_stream_aes_vtbl;
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/* mz_strm_aes.h -- Stream for WinZIP AES encryption
|
||||
Version 2.3.6, July 11, 2018
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2018 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
See the accompanying LICENSE file for the full text of the license.
|
||||
*/
|
||||
|
||||
#ifndef MZ_STREAM_AES_H
|
||||
#define MZ_STREAM_AES_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t mz_stream_aes_open(void *stream, const char *filename, int32_t mode);
|
||||
int32_t mz_stream_aes_is_open(void *stream);
|
||||
int32_t mz_stream_aes_read(void *stream, void *buf, int32_t size);
|
||||
int32_t mz_stream_aes_write(void *stream, const void *buf, int32_t size);
|
||||
int64_t mz_stream_aes_tell(void *stream);
|
||||
int32_t mz_stream_aes_seek(void *stream, int64_t offset, int32_t origin);
|
||||
int32_t mz_stream_aes_close(void *stream);
|
||||
int32_t mz_stream_aes_error(void *stream);
|
||||
|
||||
void mz_stream_aes_set_password(void *stream, const char *password);
|
||||
void mz_stream_aes_set_encryption_mode(void *stream, int16_t encryption_mode);
|
||||
|
||||
int32_t mz_stream_aes_get_prop_int64(void *stream, int32_t prop, int64_t *value);
|
||||
int32_t mz_stream_aes_set_prop_int64(void *stream, int32_t prop, int64_t value);
|
||||
|
||||
void* mz_stream_aes_create(void **stream);
|
||||
void mz_stream_aes_delete(void **stream);
|
||||
|
||||
void* mz_stream_aes_get_interface(void);
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+74
-55
@@ -1,36 +1,22 @@
|
||||
/* mz_strm_buf.c -- Stream for buffering reads/writes
|
||||
Version 2.3.6, July 11, 2018
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
This version of ioapi is designed to buffer IO.
|
||||
|
||||
Copyright (C) 2010-2018 Nathan Moinvaziri
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
See the accompanying LICENSE file for the full text of the license.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "mz.h"
|
||||
#include "mz_strm.h"
|
||||
#include "mz_strm_buf.h"
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#if 0
|
||||
# define mz_stream_buffered_print(s,f,...) printf(f,__VA_ARGS__);
|
||||
#else
|
||||
# define mz_stream_buffered_print(s,f,...)
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static mz_stream_vtbl mz_stream_buffered_vtbl = {
|
||||
mz_stream_buffered_open,
|
||||
mz_stream_buffered_is_open,
|
||||
@@ -66,10 +52,32 @@ typedef struct mz_stream_buffered_s {
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#if 0
|
||||
# define mz_stream_buffered_print printf
|
||||
#else
|
||||
# define mz_stream_buffered_print(fmt,...)
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static int32_t mz_stream_buffered_reset(void *stream)
|
||||
{
|
||||
mz_stream_buffered *buffered = (mz_stream_buffered *)stream;
|
||||
|
||||
buffered->readbuf_len = 0;
|
||||
buffered->readbuf_pos = 0;
|
||||
buffered->writebuf_len = 0;
|
||||
buffered->writebuf_pos = 0;
|
||||
buffered->position = 0;
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_stream_buffered_open(void *stream, const char *path, int32_t mode)
|
||||
{
|
||||
mz_stream_buffered *buffered = (mz_stream_buffered *)stream;
|
||||
mz_stream_buffered_print(buffered, "open [mode %d]\n", mode);
|
||||
mz_stream_buffered_print("Buffered - Open (mode %" PRId32 ")\n", mode);
|
||||
mz_stream_buffered_reset(buffered);
|
||||
return mz_stream_open(buffered->stream.base, path, mode);
|
||||
}
|
||||
|
||||
@@ -95,11 +103,11 @@ static int32_t mz_stream_buffered_flush(void *stream, int32_t *written)
|
||||
buffered->writebuf + (bytes_to_write - bytes_left_to_write), bytes_left_to_write);
|
||||
|
||||
if (bytes_written != bytes_left_to_write)
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_WRITE_ERROR;
|
||||
|
||||
buffered->writebuf_misses += 1;
|
||||
|
||||
mz_stream_buffered_print(stream, "write flush [%d:%d len %d]\n",
|
||||
mz_stream_buffered_print("Buffered - Write flush (%" PRId32 ":%" PRId32 " len %" PRId32 ")\n",
|
||||
bytes_to_write, bytes_left_to_write, buffered->writebuf_len);
|
||||
|
||||
total_bytes_written += bytes_written;
|
||||
@@ -123,11 +131,13 @@ int32_t mz_stream_buffered_read(void *stream, void *buf, int32_t size)
|
||||
int32_t bytes_left_to_read = size;
|
||||
int32_t bytes_read = 0;
|
||||
|
||||
mz_stream_buffered_print(stream, "read [size %ld pos %lld]\n", size, buffered->position);
|
||||
mz_stream_buffered_print("Buffered - Read (size %" PRId32 " pos %" PRId64 ")\n", size, buffered->position);
|
||||
|
||||
if (buffered->writebuf_len > 0)
|
||||
mz_stream_buffered_print(stream, "switch from write to read, not yet supported [%lld]\n",
|
||||
{
|
||||
mz_stream_buffered_print("Buffered - Switch from write to read, not yet supported (pos %" PRId64 ")\n",
|
||||
buffered->position);
|
||||
}
|
||||
|
||||
while (bytes_left_to_read > 0)
|
||||
{
|
||||
@@ -139,7 +149,7 @@ int32_t mz_stream_buffered_read(void *stream, void *buf, int32_t size)
|
||||
buffered->readbuf_len = 0;
|
||||
}
|
||||
|
||||
bytes_to_read = sizeof(buffered->readbuf) - (buffered->readbuf_len - buffered->readbuf_pos);
|
||||
bytes_to_read = (int32_t)sizeof(buffered->readbuf) - (buffered->readbuf_len - buffered->readbuf_pos);
|
||||
bytes_read = mz_stream_read(buffered->stream.base, buffered->readbuf + buffered->readbuf_pos, bytes_to_read);
|
||||
if (bytes_read < 0)
|
||||
return bytes_read;
|
||||
@@ -148,7 +158,7 @@ int32_t mz_stream_buffered_read(void *stream, void *buf, int32_t size)
|
||||
buffered->readbuf_len += bytes_read;
|
||||
buffered->position += bytes_read;
|
||||
|
||||
mz_stream_buffered_print(stream, "filled [read %d/%d buf %d:%d pos %lld]\n",
|
||||
mz_stream_buffered_print("Buffered - Filled (read %" PRId32 "/%" PRId32 " buf %" PRId32 ":%" PRId32 " pos %" PRId64 ")\n",
|
||||
bytes_read, bytes_to_read, buffered->readbuf_pos, buffered->readbuf_len, buffered->position);
|
||||
|
||||
if (bytes_read == 0)
|
||||
@@ -157,7 +167,7 @@ int32_t mz_stream_buffered_read(void *stream, void *buf, int32_t size)
|
||||
|
||||
if ((buffered->readbuf_len - buffered->readbuf_pos) > 0)
|
||||
{
|
||||
bytes_to_copy = (uint32_t)(buffered->readbuf_len - buffered->readbuf_pos);
|
||||
bytes_to_copy = buffered->readbuf_len - buffered->readbuf_pos;
|
||||
if (bytes_to_copy > bytes_left_to_read)
|
||||
bytes_to_copy = bytes_left_to_read;
|
||||
|
||||
@@ -169,7 +179,7 @@ int32_t mz_stream_buffered_read(void *stream, void *buf, int32_t size)
|
||||
buffered->readbuf_hits += 1;
|
||||
buffered->readbuf_pos += bytes_to_copy;
|
||||
|
||||
mz_stream_buffered_print(stream, "emptied [copied %d remaining %d buf %d:%d pos %lld]\n",
|
||||
mz_stream_buffered_print("Buffered - Emptied (copied %" PRId32 " remaining %" PRId32 " buf %" PRId32 ":%" PRId32 " pos %" PRId64 ")\n",
|
||||
bytes_to_copy, bytes_left_to_read, buffered->readbuf_pos, buffered->readbuf_len, buffered->position);
|
||||
}
|
||||
}
|
||||
@@ -185,9 +195,10 @@ int32_t mz_stream_buffered_write(void *stream, const void *buf, int32_t size)
|
||||
int32_t bytes_to_copy = 0;
|
||||
int32_t bytes_used = 0;
|
||||
int32_t bytes_flushed = 0;
|
||||
int32_t err = MZ_OK;
|
||||
|
||||
|
||||
mz_stream_buffered_print(stream, "write [size %ld len %d pos %lld]\n",
|
||||
mz_stream_buffered_print("Buffered - Write (size %" PRId32 " len %" PRId32 " pos %" PRId64 ")\n",
|
||||
size, buffered->writebuf_len, buffered->position);
|
||||
|
||||
if (buffered->readbuf_len > 0)
|
||||
@@ -198,10 +209,11 @@ int32_t mz_stream_buffered_write(void *stream, const void *buf, int32_t size)
|
||||
buffered->readbuf_len = 0;
|
||||
buffered->readbuf_pos = 0;
|
||||
|
||||
mz_stream_buffered_print(stream, "switch from read to write [%lld]\n", buffered->position);
|
||||
mz_stream_buffered_print("Buffered - Switch from read to write (pos %" PRId64 ")\n", buffered->position);
|
||||
|
||||
if (mz_stream_seek(buffered->stream.base, buffered->position, MZ_SEEK_SET) != MZ_OK)
|
||||
return MZ_STREAM_ERROR;
|
||||
err = mz_stream_seek(buffered->stream.base, buffered->position, MZ_SEEK_SET);
|
||||
if (err != MZ_OK)
|
||||
return err;
|
||||
}
|
||||
|
||||
while (bytes_left_to_write > 0)
|
||||
@@ -209,23 +221,25 @@ int32_t mz_stream_buffered_write(void *stream, const void *buf, int32_t size)
|
||||
bytes_used = buffered->writebuf_len;
|
||||
if (bytes_used > buffered->writebuf_pos)
|
||||
bytes_used = buffered->writebuf_pos;
|
||||
bytes_to_copy = (uint32_t)(sizeof(buffered->writebuf) - bytes_used);
|
||||
bytes_to_copy = (int32_t)sizeof(buffered->writebuf) - bytes_used;
|
||||
if (bytes_to_copy > bytes_left_to_write)
|
||||
bytes_to_copy = bytes_left_to_write;
|
||||
|
||||
if (bytes_to_copy == 0)
|
||||
{
|
||||
if (mz_stream_buffered_flush(stream, &bytes_flushed) != MZ_OK)
|
||||
return MZ_STREAM_ERROR;
|
||||
err = mz_stream_buffered_flush(stream, &bytes_flushed);
|
||||
if (err != MZ_OK)
|
||||
return err;
|
||||
if (bytes_flushed == 0)
|
||||
return 0;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy(buffered->writebuf + buffered->writebuf_pos, (const char *)buf + (bytes_to_write - bytes_left_to_write), bytes_to_copy);
|
||||
memcpy(buffered->writebuf + buffered->writebuf_pos,
|
||||
(const char *)buf + (bytes_to_write - bytes_left_to_write), bytes_to_copy);
|
||||
|
||||
mz_stream_buffered_print(stream, "write copy [remaining %d write %d:%d len %d]\n",
|
||||
mz_stream_buffered_print("Buffered - Write copy (remaining %" PRId32 " write %" PRId32 ":%" PRId32 " len %" PRId32 ")\n",
|
||||
bytes_to_copy, bytes_to_write, bytes_left_to_write, buffered->writebuf_len);
|
||||
|
||||
bytes_left_to_write -= bytes_to_copy;
|
||||
@@ -246,11 +260,11 @@ int64_t mz_stream_buffered_tell(void *stream)
|
||||
|
||||
buffered->position = position;
|
||||
|
||||
mz_stream_buffered_print(stream, "tell [pos %llu readpos %d writepos %d err %d]\n",
|
||||
buffered->position, buffered->readbuf_pos, buffered->writebuf_pos, errno);
|
||||
mz_stream_buffered_print("Buffered - Tell (pos %" PRId64 " readpos %" PRId32 " writepos %" PRId32 ")\n",
|
||||
buffered->position, buffered->readbuf_pos, buffered->writebuf_pos);
|
||||
|
||||
if (buffered->readbuf_len > 0)
|
||||
position -= (buffered->readbuf_len - buffered->readbuf_pos);
|
||||
position -= ((int64_t)buffered->readbuf_len - buffered->readbuf_pos);
|
||||
if (buffered->writebuf_len > 0)
|
||||
position += buffered->writebuf_pos;
|
||||
return position;
|
||||
@@ -260,8 +274,10 @@ int32_t mz_stream_buffered_seek(void *stream, int64_t offset, int32_t origin)
|
||||
{
|
||||
mz_stream_buffered *buffered = (mz_stream_buffered *)stream;
|
||||
int32_t bytes_flushed = 0;
|
||||
int32_t err = MZ_OK;
|
||||
|
||||
mz_stream_buffered_print(stream, "seek [origin %d offset %llu pos %lld]\n", origin, offset, buffered->position);
|
||||
mz_stream_buffered_print("Buffered - Seek (origin %" PRId32 " offset %" PRId64 " pos %" PRId64 ")\n",
|
||||
origin, offset, buffered->position);
|
||||
|
||||
switch (origin)
|
||||
{
|
||||
@@ -271,7 +287,7 @@ int32_t mz_stream_buffered_seek(void *stream, int64_t offset, int32_t origin)
|
||||
{
|
||||
if ((offset >= buffered->position) && (offset <= buffered->position + buffered->writebuf_len))
|
||||
{
|
||||
buffered->writebuf_pos = (uint32_t)(offset - buffered->position);
|
||||
buffered->writebuf_pos = (int32_t)(offset - buffered->position);
|
||||
return MZ_OK;
|
||||
}
|
||||
}
|
||||
@@ -279,12 +295,13 @@ int32_t mz_stream_buffered_seek(void *stream, int64_t offset, int32_t origin)
|
||||
if ((buffered->readbuf_len > 0) && (offset < buffered->position) &&
|
||||
(offset >= buffered->position - buffered->readbuf_len))
|
||||
{
|
||||
buffered->readbuf_pos = (uint32_t)(offset - (buffered->position - buffered->readbuf_len));
|
||||
buffered->readbuf_pos = (int32_t)(offset - (buffered->position - buffered->readbuf_len));
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
if (mz_stream_buffered_flush(stream, &bytes_flushed) != MZ_OK)
|
||||
return MZ_STREAM_ERROR;
|
||||
err = mz_stream_buffered_flush(stream, &bytes_flushed);
|
||||
if (err != MZ_OK)
|
||||
return err;
|
||||
|
||||
buffered->position = offset;
|
||||
break;
|
||||
@@ -293,26 +310,27 @@ int32_t mz_stream_buffered_seek(void *stream, int64_t offset, int32_t origin)
|
||||
|
||||
if (buffered->readbuf_len > 0)
|
||||
{
|
||||
if (offset <= (buffered->readbuf_len - buffered->readbuf_pos))
|
||||
if (offset <= ((int64_t)buffered->readbuf_len - buffered->readbuf_pos))
|
||||
{
|
||||
buffered->readbuf_pos += (uint32_t)offset;
|
||||
return MZ_OK;
|
||||
}
|
||||
offset -= (buffered->readbuf_len - buffered->readbuf_pos);
|
||||
offset -= ((int64_t)buffered->readbuf_len - buffered->readbuf_pos);
|
||||
buffered->position += offset;
|
||||
}
|
||||
if (buffered->writebuf_len > 0)
|
||||
{
|
||||
if (offset <= (buffered->writebuf_len - buffered->writebuf_pos))
|
||||
if (offset <= ((int64_t)buffered->writebuf_len - buffered->writebuf_pos))
|
||||
{
|
||||
buffered->writebuf_pos += (uint32_t)offset;
|
||||
return MZ_OK;
|
||||
}
|
||||
//offset -= (buffered->writebuf_len - buffered->writebuf_pos);
|
||||
/* offset -= (buffered->writebuf_len - buffered->writebuf_pos); */
|
||||
}
|
||||
|
||||
if (mz_stream_buffered_flush(stream, &bytes_flushed) != MZ_OK)
|
||||
return MZ_STREAM_ERROR;
|
||||
err = mz_stream_buffered_flush(stream, &bytes_flushed);
|
||||
if (err != MZ_OK)
|
||||
return err;
|
||||
|
||||
break;
|
||||
|
||||
@@ -340,20 +358,21 @@ int32_t mz_stream_buffered_close(void *stream)
|
||||
int32_t bytes_flushed = 0;
|
||||
|
||||
mz_stream_buffered_flush(stream, &bytes_flushed);
|
||||
mz_stream_buffered_print(stream, "close [flushed %d]\n", bytes_flushed);
|
||||
mz_stream_buffered_print("Buffered - Close (flushed %" PRId32 ")\n", bytes_flushed);
|
||||
|
||||
if (buffered->readbuf_hits + buffered->readbuf_misses > 0)
|
||||
mz_stream_buffered_print(stream, "read efficency %.02f%%\n",
|
||||
{
|
||||
mz_stream_buffered_print("Buffered - Read efficiency %.02f%%\n",
|
||||
(buffered->readbuf_hits / ((float)buffered->readbuf_hits + buffered->readbuf_misses)) * 100);
|
||||
}
|
||||
|
||||
if (buffered->writebuf_hits + buffered->writebuf_misses > 0)
|
||||
mz_stream_buffered_print(stream, "write efficency %.02f%%\n",
|
||||
{
|
||||
mz_stream_buffered_print("Buffered - Write efficiency %.02f%%\n",
|
||||
(buffered->writebuf_hits / ((float)buffered->writebuf_hits + buffered->writebuf_misses)) * 100);
|
||||
}
|
||||
|
||||
buffered->readbuf_len = 0;
|
||||
buffered->readbuf_pos = 0;
|
||||
buffered->writebuf_len = 0;
|
||||
buffered->writebuf_pos = 0;
|
||||
mz_stream_buffered_reset(buffered);
|
||||
|
||||
return mz_stream_close(buffered->stream.base);
|
||||
}
|
||||
|
||||
+2
-4
@@ -1,10 +1,10 @@
|
||||
/* mz_strm_buf.h -- Stream for buffering reads/writes
|
||||
Version 2.3.6, July 11, 2018
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
This version of ioapi is designed to buffer IO.
|
||||
|
||||
Copyright (C) 2010-2018 Nathan Moinvaziri
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
@@ -14,8 +14,6 @@
|
||||
#ifndef MZ_STREAM_BUFFERED_H
|
||||
#define MZ_STREAM_BUFFERED_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
+37
-44
@@ -1,8 +1,8 @@
|
||||
/* mz_strm_bzip.c -- Stream for bzip inflate/deflate
|
||||
Version 2.3.6, July 11, 2018
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2018 Nathan Moinvaziri
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as bzip.
|
||||
@@ -10,17 +10,12 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bzlib.h"
|
||||
|
||||
#include "mz.h"
|
||||
#include "mz_strm.h"
|
||||
#include "mz_strm_bzip.h"
|
||||
|
||||
#include "bzlib.h"
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static mz_stream_vtbl mz_stream_bzip_vtbl = {
|
||||
@@ -76,7 +71,7 @@ int32_t mz_stream_bzip_open(void *stream, const char *path, int32_t mode)
|
||||
|
||||
if (mode & MZ_OPEN_MODE_WRITE)
|
||||
{
|
||||
#ifdef MZ_ZIP_DECOMPRESS_ONLY
|
||||
#ifdef MZ_ZIP_NO_COMPRESSION
|
||||
return MZ_SUPPORT_ERROR;
|
||||
#else
|
||||
bzip->bzstream.next_out = (char *)bzip->buffer;
|
||||
@@ -87,7 +82,7 @@ int32_t mz_stream_bzip_open(void *stream, const char *path, int32_t mode)
|
||||
}
|
||||
else if (mode & MZ_OPEN_MODE_READ)
|
||||
{
|
||||
#ifdef MZ_ZIP_COMPRESS_ONLY
|
||||
#ifdef MZ_ZIP_NO_DECOMPRESSION
|
||||
return MZ_SUPPORT_ERROR;
|
||||
#else
|
||||
bzip->bzstream.next_in = (char *)bzip->buffer;
|
||||
@@ -98,7 +93,7 @@ int32_t mz_stream_bzip_open(void *stream, const char *path, int32_t mode)
|
||||
}
|
||||
|
||||
if (bzip->error != BZ_OK)
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_OPEN_ERROR;
|
||||
|
||||
bzip->initialized = 1;
|
||||
bzip->stream_end = 0;
|
||||
@@ -110,13 +105,16 @@ int32_t mz_stream_bzip_is_open(void *stream)
|
||||
{
|
||||
mz_stream_bzip *bzip = (mz_stream_bzip *)stream;
|
||||
if (bzip->initialized != 1)
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_OPEN_ERROR;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_stream_bzip_read(void *stream, void *buf, int32_t size)
|
||||
{
|
||||
#ifdef MZ_ZIP_COMPRESS_ONLY
|
||||
#ifdef MZ_ZIP_NO_DECOMPRESSION
|
||||
MZ_UNUSED(stream);
|
||||
MZ_UNUSED(buf);
|
||||
MZ_UNUSED(size);
|
||||
return MZ_SUPPORT_ERROR;
|
||||
#else
|
||||
mz_stream_bzip *bzip = (mz_stream_bzip *)stream;
|
||||
@@ -124,11 +122,11 @@ int32_t mz_stream_bzip_read(void *stream, void *buf, int32_t size)
|
||||
uint64_t total_out_before = 0;
|
||||
uint64_t total_in_after = 0;
|
||||
uint64_t total_out_after = 0;
|
||||
uint32_t total_in = 0;
|
||||
uint32_t total_out = 0;
|
||||
uint32_t in_bytes = 0;
|
||||
uint32_t out_bytes = 0;
|
||||
int32_t bytes_to_read = 0;
|
||||
int32_t total_in = 0;
|
||||
int32_t total_out = 0;
|
||||
int32_t in_bytes = 0;
|
||||
int32_t out_bytes = 0;
|
||||
int32_t bytes_to_read = sizeof(bzip->buffer);
|
||||
int32_t read = 0;
|
||||
int32_t err = BZ_OK;
|
||||
|
||||
@@ -143,25 +141,19 @@ int32_t mz_stream_bzip_read(void *stream, void *buf, int32_t size)
|
||||
{
|
||||
if (bzip->bzstream.avail_in == 0)
|
||||
{
|
||||
bytes_to_read = sizeof(bzip->buffer);
|
||||
if (bzip->max_total_in > 0)
|
||||
{
|
||||
if ((bzip->max_total_in - bzip->total_in) < (int64_t)sizeof(bzip->buffer))
|
||||
if ((int64_t)bytes_to_read > (bzip->max_total_in - bzip->total_in))
|
||||
bytes_to_read = (int32_t)(bzip->max_total_in - bzip->total_in);
|
||||
}
|
||||
|
||||
read = mz_stream_read(bzip->stream.base, bzip->buffer, bytes_to_read);
|
||||
|
||||
if (read < 0)
|
||||
{
|
||||
bzip->error = BZ_IO_ERROR;
|
||||
break;
|
||||
}
|
||||
if (read == 0)
|
||||
break;
|
||||
return read;
|
||||
|
||||
bzip->bzstream.next_in = (char *)bzip->buffer;
|
||||
bzip->bzstream.avail_in = read;
|
||||
bzip->bzstream.avail_in = (uint32_t)read;
|
||||
}
|
||||
|
||||
total_in_before = bzip->bzstream.avail_in;
|
||||
@@ -174,8 +166,8 @@ int32_t mz_stream_bzip_read(void *stream, void *buf, int32_t size)
|
||||
total_out_after = bzip->bzstream.total_out_lo32 +
|
||||
(((uint64_t)bzip->bzstream.total_out_hi32) << 32);
|
||||
|
||||
in_bytes = (uint32_t)(total_in_before - total_in_after);
|
||||
out_bytes = (uint32_t)(total_out_after - total_out_before);
|
||||
in_bytes = (int32_t)(total_in_before - total_in_after);
|
||||
out_bytes = (int32_t)(total_out_after - total_out_before);
|
||||
|
||||
total_in += in_bytes;
|
||||
total_out += out_bytes;
|
||||
@@ -197,17 +189,18 @@ int32_t mz_stream_bzip_read(void *stream, void *buf, int32_t size)
|
||||
while (bzip->bzstream.avail_out > 0);
|
||||
|
||||
if (bzip->error != 0)
|
||||
return bzip->error;
|
||||
return MZ_DATA_ERROR;
|
||||
|
||||
return total_out;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef MZ_ZIP_NO_COMPRESSION
|
||||
static int32_t mz_stream_bzip_flush(void *stream)
|
||||
{
|
||||
mz_stream_bzip *bzip = (mz_stream_bzip *)stream;
|
||||
if (mz_stream_write(bzip->stream.base, bzip->buffer, bzip->buffer_len) != bzip->buffer_len)
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_WRITE_ERROR;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
@@ -223,11 +216,9 @@ static int32_t mz_stream_bzip_compress(void *stream, int flush)
|
||||
{
|
||||
if (bzip->bzstream.avail_out == 0)
|
||||
{
|
||||
if (mz_stream_bzip_flush(bzip) != MZ_OK)
|
||||
{
|
||||
bzip->error = BZ_DATA_ERROR;
|
||||
return MZ_STREAM_ERROR;
|
||||
}
|
||||
err = mz_stream_bzip_flush(bzip);
|
||||
if (err != MZ_OK)
|
||||
return err;
|
||||
|
||||
bzip->bzstream.avail_out = sizeof(bzip->buffer);
|
||||
bzip->bzstream.next_out = (char *)bzip->buffer;
|
||||
@@ -253,21 +244,23 @@ static int32_t mz_stream_bzip_compress(void *stream, int flush)
|
||||
if (err < 0)
|
||||
{
|
||||
bzip->error = err;
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_DATA_ERROR;
|
||||
}
|
||||
}
|
||||
while ((bzip->bzstream.avail_in > 0) || (flush == BZ_FINISH && err == BZ_FINISH_OK));
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t mz_stream_bzip_write(void *stream, const void *buf, int32_t size)
|
||||
{
|
||||
mz_stream_bzip *bzip = (mz_stream_bzip *)stream;
|
||||
int32_t err = size;
|
||||
|
||||
#ifdef MZ_ZIP_DECOMPRESS_ONLY
|
||||
#ifdef MZ_ZIP_NO_COMPRESSION
|
||||
MZ_UNUSED(bzip);
|
||||
MZ_UNUSED(buf);
|
||||
err = MZ_SUPPORT_ERROR;
|
||||
#else
|
||||
bzip->bzstream.next_in = (char *)(intptr_t)buf;
|
||||
@@ -284,7 +277,7 @@ int64_t mz_stream_bzip_tell(void *stream)
|
||||
{
|
||||
MZ_UNUSED(stream);
|
||||
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_TELL_ERROR;
|
||||
}
|
||||
|
||||
int32_t mz_stream_bzip_seek(void *stream, int64_t offset, int32_t origin)
|
||||
@@ -293,7 +286,7 @@ int32_t mz_stream_bzip_seek(void *stream, int64_t offset, int32_t origin)
|
||||
MZ_UNUSED(offset);
|
||||
MZ_UNUSED(origin);
|
||||
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_SEEK_ERROR;
|
||||
}
|
||||
|
||||
int32_t mz_stream_bzip_close(void *stream)
|
||||
@@ -302,7 +295,7 @@ int32_t mz_stream_bzip_close(void *stream)
|
||||
|
||||
if (bzip->mode & MZ_OPEN_MODE_WRITE)
|
||||
{
|
||||
#ifdef MZ_ZIP_DECOMPRESS_ONLY
|
||||
#ifdef MZ_ZIP_NO_COMPRESSION
|
||||
return MZ_SUPPORT_ERROR;
|
||||
#else
|
||||
mz_stream_bzip_compress(stream, BZ_FINISH);
|
||||
@@ -313,7 +306,7 @@ int32_t mz_stream_bzip_close(void *stream)
|
||||
}
|
||||
else if (bzip->mode & MZ_OPEN_MODE_READ)
|
||||
{
|
||||
#ifdef MZ_ZIP_COMPRESS_ONLY
|
||||
#ifdef MZ_ZIP_NO_DECOMPRESSION
|
||||
return MZ_SUPPORT_ERROR;
|
||||
#else
|
||||
BZ2_bzDecompressEnd(&bzip->bzstream);
|
||||
@@ -323,7 +316,7 @@ int32_t mz_stream_bzip_close(void *stream)
|
||||
bzip->initialized = 0;
|
||||
|
||||
if (bzip->error != BZ_OK)
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_CLOSE_ERROR;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
|
||||
+2
-4
@@ -1,8 +1,8 @@
|
||||
/* mz_strm_bzip.h -- Stream for bzip inflate/deflate
|
||||
Version 2.3.6, July 11, 2018
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2018 Nathan Moinvaziri
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
@@ -12,8 +12,6 @@
|
||||
#ifndef MZ_STREAM_BZIP_H
|
||||
#define MZ_STREAM_BZIP_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
-210
@@ -1,210 +0,0 @@
|
||||
/* mz_strm_crc32.c -- Stream for CRC32 hashing
|
||||
Version 2.3.6, July 11, 2018
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2018 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
See the accompanying LICENSE file for the full text of the license.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
#include "zlib.h"
|
||||
#endif
|
||||
|
||||
#include "mz.h"
|
||||
#include "mz_strm.h"
|
||||
#include "mz_strm_crc32.h"
|
||||
#ifdef HAVE_LZMA
|
||||
#include "mz_strm_lzma.h"
|
||||
#endif
|
||||
#ifdef HAVE_ZLIB
|
||||
#include "mz_strm_zlib.h"
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static mz_stream_vtbl mz_stream_crc32_vtbl = {
|
||||
mz_stream_crc32_open,
|
||||
mz_stream_crc32_is_open,
|
||||
mz_stream_crc32_read,
|
||||
mz_stream_crc32_write,
|
||||
mz_stream_crc32_tell,
|
||||
mz_stream_crc32_seek,
|
||||
mz_stream_crc32_close,
|
||||
mz_stream_crc32_error,
|
||||
mz_stream_crc32_create,
|
||||
mz_stream_crc32_delete,
|
||||
mz_stream_crc32_get_prop_int64,
|
||||
NULL
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
typedef struct mz_stream_crc32_s {
|
||||
mz_stream stream;
|
||||
int8_t initialized;
|
||||
int64_t value;
|
||||
int64_t total_in;
|
||||
int64_t total_out;
|
||||
|
||||
mz_stream_crc32_update update;
|
||||
} mz_stream_crc32;
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t mz_stream_crc32_open(void *stream, const char *path, int32_t mode)
|
||||
{
|
||||
mz_stream_crc32 *crc32 = (mz_stream_crc32 *)stream;
|
||||
|
||||
MZ_UNUSED(path);
|
||||
MZ_UNUSED(mode);
|
||||
|
||||
crc32->initialized = 1;
|
||||
crc32->value = 0;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_stream_crc32_is_open(void *stream)
|
||||
{
|
||||
mz_stream_crc32 *crc32 = (mz_stream_crc32 *)stream;
|
||||
if (crc32->initialized != 1)
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_stream_crc32_read(void *stream, void *buf, int32_t size)
|
||||
{
|
||||
mz_stream_crc32 *crc32x = (mz_stream_crc32 *)stream;
|
||||
int32_t read = 0;
|
||||
read = mz_stream_read(crc32x->stream.base, buf, size);
|
||||
if (read > 0)
|
||||
{
|
||||
crc32x->value = crc32x->update(crc32x->value, buf, read);
|
||||
crc32x->total_in += read;
|
||||
}
|
||||
return read;
|
||||
}
|
||||
|
||||
int32_t mz_stream_crc32_write(void *stream, const void *buf, int32_t size)
|
||||
{
|
||||
mz_stream_crc32 *crc32x = (mz_stream_crc32 *)stream;
|
||||
int32_t written = 0;
|
||||
crc32x->value = crc32x->update(crc32x->value, buf, size);
|
||||
written = mz_stream_write(crc32x->stream.base, buf, size);
|
||||
crc32x->total_out += written;
|
||||
return written;
|
||||
}
|
||||
|
||||
int64_t mz_stream_crc32_tell(void *stream)
|
||||
{
|
||||
mz_stream_crc32 *crc32 = (mz_stream_crc32 *)stream;
|
||||
return mz_stream_tell(crc32->stream.base);
|
||||
}
|
||||
|
||||
int32_t mz_stream_crc32_seek(void *stream, int64_t offset, int32_t origin)
|
||||
{
|
||||
mz_stream_crc32 *crc32 = (mz_stream_crc32 *)stream;
|
||||
crc32->value = 0;
|
||||
return mz_stream_seek(crc32->stream.base, offset, origin);
|
||||
}
|
||||
|
||||
int32_t mz_stream_crc32_close(void *stream)
|
||||
{
|
||||
mz_stream_crc32 *crc32 = (mz_stream_crc32 *)stream;
|
||||
crc32->initialized = 0;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_stream_crc32_error(void *stream)
|
||||
{
|
||||
mz_stream_crc32 *crc32 = (mz_stream_crc32 *)stream;
|
||||
return mz_stream_error(crc32->stream.base);
|
||||
}
|
||||
|
||||
int32_t mz_stream_crc32_get_value(void *stream)
|
||||
{
|
||||
mz_stream_crc32 *crc32 = (mz_stream_crc32 *)stream;
|
||||
return (int32_t)crc32->value;
|
||||
}
|
||||
|
||||
int32_t mz_stream_crc32_get_prop_int64(void *stream, int32_t prop, int64_t *value)
|
||||
{
|
||||
mz_stream_crc32 *crc32 = (mz_stream_crc32 *)stream;
|
||||
switch (prop)
|
||||
{
|
||||
case MZ_STREAM_PROP_TOTAL_IN:
|
||||
*value = crc32->total_in;
|
||||
break;
|
||||
case MZ_STREAM_PROP_TOTAL_OUT:
|
||||
*value = crc32->total_out;
|
||||
break;
|
||||
default:
|
||||
return MZ_EXIST_ERROR;
|
||||
}
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
void *mz_stream_crc32_create(void **stream)
|
||||
{
|
||||
mz_stream_crc32 *crc32 = NULL;
|
||||
|
||||
crc32 = (mz_stream_crc32 *)MZ_ALLOC(sizeof(mz_stream_crc32));
|
||||
if (crc32 != NULL)
|
||||
{
|
||||
memset(crc32, 0, sizeof(mz_stream_crc32));
|
||||
crc32->stream.vtbl = &mz_stream_crc32_vtbl;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
crc32->update =
|
||||
(mz_stream_crc32_update)mz_stream_zlib_get_crc32_update();
|
||||
#elif defined(HAVE_LZMA)
|
||||
crc32->update =
|
||||
(mz_stream_crc32_update)mz_stream_lzma_get_crc32_update();
|
||||
#else
|
||||
#error ZLIB or LZMA required for CRC32
|
||||
#endif
|
||||
|
||||
if (stream != NULL)
|
||||
*stream = crc32;
|
||||
|
||||
return crc32;
|
||||
}
|
||||
|
||||
void mz_stream_crc32_delete(void **stream)
|
||||
{
|
||||
mz_stream_crc32 *crc32 = NULL;
|
||||
if (stream == NULL)
|
||||
return;
|
||||
crc32 = (mz_stream_crc32 *)*stream;
|
||||
if (crc32 != NULL)
|
||||
MZ_FREE(crc32);
|
||||
*stream = NULL;
|
||||
}
|
||||
|
||||
void *mz_stream_crc32_get_interface(void)
|
||||
{
|
||||
return (void *)&mz_stream_crc32_vtbl;
|
||||
}
|
||||
|
||||
int32_t mz_stream_crc32_get_update_func(mz_stream_crc32_update *update)
|
||||
{
|
||||
if (update == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
#ifdef HAVE_ZLIB
|
||||
*update =
|
||||
(mz_stream_crc32_update)mz_stream_zlib_get_crc32_update();
|
||||
#elif defined(HAVE_LZMA)
|
||||
*update =
|
||||
(mz_stream_crc32_update)mz_stream_lzma_get_crc32_update();
|
||||
#else
|
||||
#error ZLIB or LZMA required for CRC32
|
||||
#endif
|
||||
return MZ_OK;
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/* mz_strm_crc32.h -- Stream for CRC32 hashing
|
||||
Version 2.3.6, July 11, 2018
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2018 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
See the accompanying LICENSE file for the full text of the license.
|
||||
*/
|
||||
|
||||
#ifndef MZ_STREAM_CRC32_H
|
||||
#define MZ_STREAM_CRC32_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
typedef int64_t (*mz_stream_crc32_update)(int64_t value, const void *buf, int32_t size);
|
||||
|
||||
int32_t mz_stream_crc32_open(void *stream, const char *filename, int32_t mode);
|
||||
int32_t mz_stream_crc32_is_open(void *stream);
|
||||
int32_t mz_stream_crc32_read(void *stream, void *buf, int32_t size);
|
||||
int32_t mz_stream_crc32_write(void *stream, const void *buf, int32_t size);
|
||||
int64_t mz_stream_crc32_tell(void *stream);
|
||||
int32_t mz_stream_crc32_seek(void *stream, int64_t offset, int32_t origin);
|
||||
int32_t mz_stream_crc32_close(void *stream);
|
||||
int32_t mz_stream_crc32_error(void *stream);
|
||||
|
||||
int32_t mz_stream_crc32_get_value(void *stream);
|
||||
|
||||
int32_t mz_stream_crc32_get_prop_int64(void *stream, int32_t prop, int64_t *value);
|
||||
|
||||
void* mz_stream_crc32_create(void **stream);
|
||||
void mz_stream_crc32_delete(void **stream);
|
||||
|
||||
void* mz_stream_crc32_get_interface(void);
|
||||
int32_t mz_stream_crc32_get_update_func(mz_stream_crc32_update *update);
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,423 @@
|
||||
/* mz_strm_libcomp.c -- Stream for apple compression
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
See the accompanying LICENSE file for the full text of the license.
|
||||
*/
|
||||
|
||||
|
||||
#include "mz.h"
|
||||
#include "mz_strm.h"
|
||||
#include "mz_strm_libcomp.h"
|
||||
|
||||
#include <compression.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static mz_stream_vtbl mz_stream_libcomp_vtbl = {
|
||||
mz_stream_libcomp_open,
|
||||
mz_stream_libcomp_is_open,
|
||||
mz_stream_libcomp_read,
|
||||
mz_stream_libcomp_write,
|
||||
mz_stream_libcomp_tell,
|
||||
mz_stream_libcomp_seek,
|
||||
mz_stream_libcomp_close,
|
||||
mz_stream_libcomp_error,
|
||||
mz_stream_libcomp_create,
|
||||
mz_stream_libcomp_delete,
|
||||
mz_stream_libcomp_get_prop_int64,
|
||||
mz_stream_libcomp_set_prop_int64
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
typedef struct mz_stream_libcomp_s {
|
||||
mz_stream stream;
|
||||
compression_stream
|
||||
cstream;
|
||||
uint8_t buffer[INT16_MAX];
|
||||
int32_t buffer_len;
|
||||
int64_t total_in;
|
||||
int64_t total_out;
|
||||
int64_t max_total_in;
|
||||
int8_t initialized;
|
||||
int32_t mode;
|
||||
int32_t error;
|
||||
int16_t algorithm;
|
||||
} mz_stream_libcomp;
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t mz_stream_libcomp_open(void *stream, const char *path, int32_t mode)
|
||||
{
|
||||
mz_stream_libcomp *libcomp = (mz_stream_libcomp *)stream;
|
||||
int32_t err = 0;
|
||||
int16_t operation = 0;
|
||||
|
||||
MZ_UNUSED(path);
|
||||
|
||||
if (libcomp->algorithm == 0)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
libcomp->total_in = 0;
|
||||
libcomp->total_out = 0;
|
||||
|
||||
if (mode & MZ_OPEN_MODE_WRITE)
|
||||
{
|
||||
#ifdef MZ_ZIP_NO_COMPRESSION
|
||||
return MZ_SUPPORT_ERROR;
|
||||
#else
|
||||
operation = COMPRESSION_STREAM_ENCODE;
|
||||
#endif
|
||||
}
|
||||
else if (mode & MZ_OPEN_MODE_READ)
|
||||
{
|
||||
#ifdef MZ_ZIP_NO_DECOMPRESSION
|
||||
return MZ_SUPPORT_ERROR;
|
||||
#else
|
||||
operation = COMPRESSION_STREAM_DECODE;
|
||||
#endif
|
||||
}
|
||||
|
||||
err = compression_stream_init(&libcomp->cstream, (compression_stream_operation)operation,
|
||||
(compression_algorithm)libcomp->algorithm);
|
||||
|
||||
if (err == COMPRESSION_STATUS_ERROR)
|
||||
{
|
||||
libcomp->error = err;
|
||||
return MZ_OPEN_ERROR;
|
||||
}
|
||||
|
||||
libcomp->initialized = 1;
|
||||
libcomp->mode = mode;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_stream_libcomp_is_open(void *stream)
|
||||
{
|
||||
mz_stream_libcomp *libcomp = (mz_stream_libcomp *)stream;
|
||||
if (libcomp->initialized != 1)
|
||||
return MZ_OPEN_ERROR;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_stream_libcomp_read(void *stream, void *buf, int32_t size)
|
||||
{
|
||||
#ifdef MZ_ZIP_NO_DECOMPRESSION
|
||||
MZ_UNUSED(stream);
|
||||
MZ_UNUSED(buf);
|
||||
MZ_UNUSED(size);
|
||||
return MZ_SUPPORT_ERROR;
|
||||
#else
|
||||
mz_stream_libcomp *libcomp = (mz_stream_libcomp *)stream;
|
||||
uint64_t total_in_before = 0;
|
||||
uint64_t total_in_after = 0;
|
||||
uint64_t total_out_before = 0;
|
||||
uint64_t total_out_after = 0;
|
||||
int32_t total_in = 0;
|
||||
int32_t total_out = 0;
|
||||
int32_t in_bytes = 0;
|
||||
int32_t out_bytes = 0;
|
||||
int32_t bytes_to_read = sizeof(libcomp->buffer);
|
||||
int32_t read = 0;
|
||||
int32_t err = MZ_OK;
|
||||
int16_t flags = 0;
|
||||
|
||||
libcomp->cstream.dst_ptr = buf;
|
||||
libcomp->cstream.dst_size = (size_t)size;
|
||||
|
||||
do
|
||||
{
|
||||
if (libcomp->cstream.src_size == 0)
|
||||
{
|
||||
if (libcomp->max_total_in > 0)
|
||||
{
|
||||
if ((int64_t)bytes_to_read > (libcomp->max_total_in - libcomp->total_in))
|
||||
bytes_to_read = (int32_t)(libcomp->max_total_in - libcomp->total_in);
|
||||
}
|
||||
|
||||
read = mz_stream_read(libcomp->stream.base, libcomp->buffer, bytes_to_read);
|
||||
|
||||
if (read < 0)
|
||||
return read;
|
||||
if (read == 0)
|
||||
flags = COMPRESSION_STREAM_FINALIZE;
|
||||
|
||||
libcomp->cstream.src_ptr = libcomp->buffer;
|
||||
libcomp->cstream.src_size = (size_t)read;
|
||||
}
|
||||
|
||||
total_in_before = libcomp->cstream.src_size;
|
||||
total_out_before = libcomp->cstream.dst_size;
|
||||
|
||||
err = compression_stream_process(&libcomp->cstream, flags);
|
||||
if (err == COMPRESSION_STATUS_ERROR)
|
||||
{
|
||||
libcomp->error = err;
|
||||
break;
|
||||
}
|
||||
|
||||
total_in_after = libcomp->cstream.src_size;
|
||||
total_out_after = libcomp->cstream.dst_size;
|
||||
|
||||
in_bytes = (int32_t)(total_in_before - total_in_after);
|
||||
out_bytes = (int32_t)(total_out_before - total_out_after);
|
||||
|
||||
total_in += in_bytes;
|
||||
total_out += out_bytes;
|
||||
|
||||
libcomp->total_in += in_bytes;
|
||||
libcomp->total_out += out_bytes;
|
||||
|
||||
if (err == COMPRESSION_STATUS_END)
|
||||
break;
|
||||
if (err != COMPRESSION_STATUS_OK)
|
||||
{
|
||||
libcomp->error = err;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (libcomp->cstream.dst_size > 0);
|
||||
|
||||
if (libcomp->error != 0)
|
||||
return MZ_DATA_ERROR;
|
||||
|
||||
return total_out;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int32_t mz_stream_libcomp_flush(void *stream)
|
||||
{
|
||||
mz_stream_libcomp *libcomp = (mz_stream_libcomp *)stream;
|
||||
if (mz_stream_write(libcomp->stream.base, libcomp->buffer, libcomp->buffer_len) != libcomp->buffer_len)
|
||||
return MZ_WRITE_ERROR;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
static int32_t mz_stream_libcomp_deflate(void *stream, int flush)
|
||||
{
|
||||
mz_stream_libcomp *libcomp = (mz_stream_libcomp *)stream;
|
||||
uint64_t total_out_before = 0;
|
||||
uint64_t total_out_after = 0;
|
||||
uint32_t out_bytes = 0;
|
||||
int32_t err = MZ_OK;
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
if (libcomp->cstream.dst_size == 0)
|
||||
{
|
||||
err = mz_stream_libcomp_flush(libcomp);
|
||||
if (err != MZ_OK)
|
||||
{
|
||||
libcomp->error = err;
|
||||
return err;
|
||||
}
|
||||
|
||||
libcomp->cstream.dst_size = sizeof(libcomp->buffer);
|
||||
libcomp->cstream.dst_ptr = libcomp->buffer;
|
||||
|
||||
libcomp->buffer_len = 0;
|
||||
}
|
||||
|
||||
total_out_before = libcomp->cstream.dst_size;
|
||||
err = compression_stream_process(&libcomp->cstream, flush);
|
||||
total_out_after = libcomp->cstream.dst_size;
|
||||
|
||||
out_bytes = (uint32_t)(total_out_before - total_out_after);
|
||||
|
||||
libcomp->buffer_len += out_bytes;
|
||||
libcomp->total_out += out_bytes;
|
||||
|
||||
if (err == COMPRESSION_STATUS_END)
|
||||
break;
|
||||
if (err != COMPRESSION_STATUS_OK)
|
||||
{
|
||||
libcomp->error = err;
|
||||
return MZ_DATA_ERROR;
|
||||
}
|
||||
}
|
||||
while ((libcomp->cstream.src_size > 0) || (flush == COMPRESSION_STREAM_FINALIZE && err == COMPRESSION_STATUS_OK));
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_stream_libcomp_write(void *stream, const void *buf, int32_t size)
|
||||
{
|
||||
mz_stream_libcomp *libcomp = (mz_stream_libcomp *)stream;
|
||||
int32_t err = size;
|
||||
|
||||
#ifdef MZ_ZIP_NO_COMPRESSION
|
||||
MZ_UNUSED(libcomp);
|
||||
err = MZ_SUPPORT_ERROR;
|
||||
#else
|
||||
libcomp->cstream.src_ptr = buf;
|
||||
libcomp->cstream.src_size = (size_t)size;
|
||||
|
||||
mz_stream_libcomp_deflate(stream, 0);
|
||||
|
||||
libcomp->total_in += size;
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
int64_t mz_stream_libcomp_tell(void *stream)
|
||||
{
|
||||
MZ_UNUSED(stream);
|
||||
|
||||
return MZ_TELL_ERROR;
|
||||
}
|
||||
|
||||
int32_t mz_stream_libcomp_seek(void *stream, int64_t offset, int32_t origin)
|
||||
{
|
||||
MZ_UNUSED(stream);
|
||||
MZ_UNUSED(offset);
|
||||
MZ_UNUSED(origin);
|
||||
|
||||
return MZ_SEEK_ERROR;
|
||||
}
|
||||
|
||||
int32_t mz_stream_libcomp_close(void *stream)
|
||||
{
|
||||
mz_stream_libcomp *libcomp = (mz_stream_libcomp *)stream;
|
||||
|
||||
|
||||
if (libcomp->mode & MZ_OPEN_MODE_WRITE)
|
||||
{
|
||||
#ifdef MZ_ZIP_NO_COMPRESSION
|
||||
return MZ_SUPPORT_ERROR;
|
||||
#else
|
||||
mz_stream_libcomp_deflate(stream, COMPRESSION_STREAM_FINALIZE);
|
||||
mz_stream_libcomp_flush(stream);
|
||||
#endif
|
||||
}
|
||||
else if (libcomp->mode & MZ_OPEN_MODE_READ)
|
||||
{
|
||||
#ifdef MZ_ZIP_NO_DECOMPRESSION
|
||||
return MZ_SUPPORT_ERROR;
|
||||
#endif
|
||||
}
|
||||
|
||||
compression_stream_destroy(&libcomp->cstream);
|
||||
|
||||
libcomp->initialized = 0;
|
||||
|
||||
if (libcomp->error != MZ_OK)
|
||||
return MZ_CLOSE_ERROR;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_stream_libcomp_error(void *stream)
|
||||
{
|
||||
mz_stream_libcomp *libcomp = (mz_stream_libcomp *)stream;
|
||||
return libcomp->error;
|
||||
}
|
||||
|
||||
int32_t mz_stream_libcomp_get_prop_int64(void *stream, int32_t prop, int64_t *value)
|
||||
{
|
||||
mz_stream_libcomp *libcomp = (mz_stream_libcomp *)stream;
|
||||
switch (prop)
|
||||
{
|
||||
case MZ_STREAM_PROP_TOTAL_IN:
|
||||
*value = libcomp->total_in;
|
||||
break;
|
||||
case MZ_STREAM_PROP_TOTAL_IN_MAX:
|
||||
*value = libcomp->max_total_in;
|
||||
break;
|
||||
case MZ_STREAM_PROP_TOTAL_OUT:
|
||||
*value = libcomp->total_out;
|
||||
break;
|
||||
case MZ_STREAM_PROP_HEADER_SIZE:
|
||||
*value = 0;
|
||||
break;
|
||||
default:
|
||||
return MZ_EXIST_ERROR;
|
||||
}
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_stream_libcomp_set_prop_int64(void *stream, int32_t prop, int64_t value)
|
||||
{
|
||||
mz_stream_libcomp *libcomp = (mz_stream_libcomp *)stream;
|
||||
switch (prop)
|
||||
{
|
||||
case MZ_STREAM_PROP_COMPRESS_ALGORITHM:
|
||||
libcomp->algorithm = (int16_t)value;
|
||||
break;
|
||||
case MZ_STREAM_PROP_TOTAL_IN_MAX:
|
||||
libcomp->max_total_in = value;
|
||||
break;
|
||||
default:
|
||||
return MZ_EXIST_ERROR;
|
||||
}
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
void *mz_stream_libcomp_create(void **stream)
|
||||
{
|
||||
mz_stream_libcomp *libcomp = NULL;
|
||||
|
||||
libcomp = (mz_stream_libcomp *)MZ_ALLOC(sizeof(mz_stream_libcomp));
|
||||
if (libcomp != NULL)
|
||||
{
|
||||
memset(libcomp, 0, sizeof(mz_stream_libcomp));
|
||||
libcomp->stream.vtbl = &mz_stream_libcomp_vtbl;
|
||||
}
|
||||
if (stream != NULL)
|
||||
*stream = libcomp;
|
||||
|
||||
return libcomp;
|
||||
}
|
||||
|
||||
void mz_stream_libcomp_delete(void **stream)
|
||||
{
|
||||
mz_stream_libcomp *libcomp = NULL;
|
||||
if (stream == NULL)
|
||||
return;
|
||||
libcomp = (mz_stream_libcomp *)*stream;
|
||||
if (libcomp != NULL)
|
||||
MZ_FREE(libcomp);
|
||||
*stream = NULL;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static mz_stream_vtbl mz_stream_zlib_vtbl = {
|
||||
mz_stream_libcomp_open,
|
||||
mz_stream_libcomp_is_open,
|
||||
mz_stream_libcomp_read,
|
||||
mz_stream_libcomp_write,
|
||||
mz_stream_libcomp_tell,
|
||||
mz_stream_libcomp_seek,
|
||||
mz_stream_libcomp_close,
|
||||
mz_stream_libcomp_error,
|
||||
mz_stream_zlib_create,
|
||||
mz_stream_libcomp_delete,
|
||||
mz_stream_libcomp_get_prop_int64,
|
||||
mz_stream_libcomp_set_prop_int64
|
||||
};
|
||||
|
||||
void *mz_stream_zlib_create(void **stream)
|
||||
{
|
||||
mz_stream_libcomp *libcomp = NULL;
|
||||
void *stream_int = NULL;
|
||||
mz_stream_libcomp_create(&stream_int);
|
||||
if (stream_int != NULL)
|
||||
{
|
||||
libcomp = (mz_stream_libcomp *)stream_int;
|
||||
libcomp->stream.vtbl = &mz_stream_zlib_vtbl;
|
||||
libcomp->algorithm = COMPRESSION_ZLIB;
|
||||
}
|
||||
if (stream != NULL)
|
||||
*stream = stream_int;
|
||||
return stream_int;
|
||||
}
|
||||
|
||||
void *mz_stream_zlib_get_interface(void)
|
||||
{
|
||||
return (void *)&mz_stream_zlib_vtbl;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/* mz_strm_libcomp.h -- Stream for apple compression
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
See the accompanying LICENSE file for the full text of the license.
|
||||
*/
|
||||
|
||||
#ifndef MZ_STREAM_LIBCOMP_H
|
||||
#define MZ_STREAM_LIBCOMP_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t mz_stream_libcomp_open(void *stream, const char *filename, int32_t mode);
|
||||
int32_t mz_stream_libcomp_is_open(void *stream);
|
||||
int32_t mz_stream_libcomp_read(void *stream, void *buf, int32_t size);
|
||||
int32_t mz_stream_libcomp_write(void *stream, const void *buf, int32_t size);
|
||||
int64_t mz_stream_libcomp_tell(void *stream);
|
||||
int32_t mz_stream_libcomp_seek(void *stream, int64_t offset, int32_t origin);
|
||||
int32_t mz_stream_libcomp_close(void *stream);
|
||||
int32_t mz_stream_libcomp_error(void *stream);
|
||||
|
||||
int32_t mz_stream_libcomp_get_prop_int64(void *stream, int32_t prop, int64_t *value);
|
||||
int32_t mz_stream_libcomp_set_prop_int64(void *stream, int32_t prop, int64_t value);
|
||||
|
||||
void* mz_stream_libcomp_create(void **stream);
|
||||
void mz_stream_libcomp_delete(void **stream);
|
||||
|
||||
void* mz_stream_libcomp_get_interface(void);
|
||||
void* mz_stream_libcomp_get_crc32_update(void);
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t mz_stream_zlib_open(void *stream, const char *filename, int32_t mode);
|
||||
int32_t mz_stream_zlib_is_open(void *stream);
|
||||
int32_t mz_stream_zlib_read(void *stream, void *buf, int32_t size);
|
||||
int32_t mz_stream_zlib_write(void *stream, const void *buf, int32_t size);
|
||||
int64_t mz_stream_zlib_tell(void *stream);
|
||||
int32_t mz_stream_zlib_seek(void *stream, int64_t offset, int32_t origin);
|
||||
int32_t mz_stream_zlib_close(void *stream);
|
||||
int32_t mz_stream_zlib_error(void *stream);
|
||||
|
||||
int32_t mz_stream_zlib_get_prop_int64(void *stream, int32_t prop, int64_t *value);
|
||||
int32_t mz_stream_zlib_set_prop_int64(void *stream, int32_t prop, int64_t value);
|
||||
|
||||
void* mz_stream_zlib_create(void **stream);
|
||||
void mz_stream_zlib_delete(void **stream);
|
||||
|
||||
void* mz_stream_zlib_get_interface(void);
|
||||
void* mz_stream_zlib_get_crc32_update(void);
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+44
-56
@@ -1,8 +1,8 @@
|
||||
/* mz_strm_lzma.c -- Stream for lzma inflate/deflate
|
||||
Version 2.3.6, July 11, 2018
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2018 Nathan Moinvaziri
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as lzma.
|
||||
@@ -10,18 +10,12 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <lzma.h>
|
||||
|
||||
#include "mz.h"
|
||||
#include "mz_strm.h"
|
||||
#include "mz_strm_lzma.h"
|
||||
|
||||
#include "lzma.h"
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#define MZ_LZMA_HEADER_SIZE (4)
|
||||
@@ -83,15 +77,17 @@ int32_t mz_stream_lzma_open(void *stream, const char *path, int32_t mode)
|
||||
|
||||
if (mode & MZ_OPEN_MODE_WRITE)
|
||||
{
|
||||
#ifdef MZ_ZIP_DECOMPRESS_ONLY
|
||||
#ifdef MZ_ZIP_NO_COMPRESSION
|
||||
MZ_UNUSED(filters);
|
||||
MZ_UNUSED(major);
|
||||
MZ_UNUSED(minor);
|
||||
return MZ_SUPPORT_ERROR;
|
||||
#else
|
||||
lzma->lstream.next_out = lzma->buffer;
|
||||
lzma->lstream.avail_out = sizeof(lzma->buffer);
|
||||
|
||||
if (lzma_lzma_preset(&opt_lzma, lzma->preset))
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_OPEN_ERROR;
|
||||
|
||||
memset(&filters, 0, sizeof(filters));
|
||||
|
||||
@@ -112,7 +108,10 @@ int32_t mz_stream_lzma_open(void *stream, const char *path, int32_t mode)
|
||||
}
|
||||
else if (mode & MZ_OPEN_MODE_READ)
|
||||
{
|
||||
#ifdef MZ_ZIP_COMPRESS_ONLY
|
||||
#ifdef MZ_ZIP_NO_DECOMPRESSION
|
||||
MZ_UNUSED(filters);
|
||||
MZ_UNUSED(major);
|
||||
MZ_UNUSED(minor);
|
||||
return MZ_SUPPORT_ERROR;
|
||||
#else
|
||||
lzma->lstream.next_in = lzma->buffer;
|
||||
@@ -129,7 +128,7 @@ int32_t mz_stream_lzma_open(void *stream, const char *path, int32_t mode)
|
||||
}
|
||||
|
||||
if (lzma->error != LZMA_OK)
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_OPEN_ERROR;
|
||||
|
||||
lzma->initialized = 1;
|
||||
lzma->mode = mode;
|
||||
@@ -140,13 +139,16 @@ int32_t mz_stream_lzma_is_open(void *stream)
|
||||
{
|
||||
mz_stream_lzma *lzma = (mz_stream_lzma *)stream;
|
||||
if (lzma->initialized != 1)
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_OPEN_ERROR;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_stream_lzma_read(void *stream, void *buf, int32_t size)
|
||||
{
|
||||
#ifdef MZ_ZIP_COMPRESS_ONLY
|
||||
#ifdef MZ_ZIP_NO_DECOMPRESSION
|
||||
MZ_UNUSED(stream);
|
||||
MZ_UNUSED(buf);
|
||||
MZ_UNUSED(size);
|
||||
return MZ_SUPPORT_ERROR;
|
||||
#else
|
||||
mz_stream_lzma *lzma = (mz_stream_lzma *)stream;
|
||||
@@ -154,10 +156,10 @@ int32_t mz_stream_lzma_read(void *stream, void *buf, int32_t size)
|
||||
uint64_t total_out_before = 0;
|
||||
uint64_t total_in_after = 0;
|
||||
uint64_t total_out_after = 0;
|
||||
uint32_t total_in = 0;
|
||||
uint32_t total_out = 0;
|
||||
uint32_t in_bytes = 0;
|
||||
uint32_t out_bytes = 0;
|
||||
int32_t total_in = 0;
|
||||
int32_t total_out = 0;
|
||||
int32_t in_bytes = 0;
|
||||
int32_t out_bytes = 0;
|
||||
int32_t bytes_to_read = 0;
|
||||
int32_t read = 0;
|
||||
int32_t err = LZMA_OK;
|
||||
@@ -173,22 +175,17 @@ int32_t mz_stream_lzma_read(void *stream, void *buf, int32_t size)
|
||||
bytes_to_read = sizeof(lzma->buffer);
|
||||
if (lzma->max_total_in > 0)
|
||||
{
|
||||
if ((lzma->max_total_in - lzma->total_in) < (int64_t)sizeof(lzma->buffer))
|
||||
if ((int64_t)bytes_to_read > (lzma->max_total_in - lzma->total_in))
|
||||
bytes_to_read = (int32_t)(lzma->max_total_in - lzma->total_in);
|
||||
}
|
||||
|
||||
read = mz_stream_read(lzma->stream.base, lzma->buffer, bytes_to_read);
|
||||
|
||||
if (read < 0)
|
||||
{
|
||||
lzma->error = MZ_STREAM_ERROR;
|
||||
break;
|
||||
}
|
||||
if (read == 0)
|
||||
break;
|
||||
return read;
|
||||
|
||||
lzma->lstream.next_in = lzma->buffer;
|
||||
lzma->lstream.avail_in = read;
|
||||
lzma->lstream.avail_in = (size_t)read;
|
||||
}
|
||||
|
||||
total_in_before = lzma->lstream.avail_in;
|
||||
@@ -199,10 +196,10 @@ int32_t mz_stream_lzma_read(void *stream, void *buf, int32_t size)
|
||||
total_in_after = lzma->lstream.avail_in;
|
||||
total_out_after = lzma->lstream.total_out;
|
||||
if ((lzma->max_total_out != -1) && (int64_t)total_out_after > lzma->max_total_out)
|
||||
total_out_after = lzma->max_total_out;
|
||||
total_out_after = (uint64_t)lzma->max_total_out;
|
||||
|
||||
in_bytes = (uint32_t)(total_in_before - total_in_after);
|
||||
out_bytes = (uint32_t)(total_out_after - total_out_before);
|
||||
in_bytes = (int32_t)(total_in_before - total_in_after);
|
||||
out_bytes = (int32_t)(total_out_after - total_out_before);
|
||||
|
||||
total_in += in_bytes;
|
||||
total_out += out_bytes;
|
||||
@@ -221,17 +218,18 @@ int32_t mz_stream_lzma_read(void *stream, void *buf, int32_t size)
|
||||
while (lzma->lstream.avail_out > 0);
|
||||
|
||||
if (lzma->error != 0)
|
||||
return lzma->error;
|
||||
return MZ_DATA_ERROR;
|
||||
|
||||
return total_out;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef MZ_ZIP_NO_COMPRESSION
|
||||
static int32_t mz_stream_lzma_flush(void *stream)
|
||||
{
|
||||
mz_stream_lzma *lzma = (mz_stream_lzma *)stream;
|
||||
if (mz_stream_write(lzma->stream.base, lzma->buffer, lzma->buffer_len) != lzma->buffer_len)
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_WRITE_ERROR;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
@@ -248,11 +246,9 @@ static int32_t mz_stream_lzma_code(void *stream, int32_t flush)
|
||||
{
|
||||
if (lzma->lstream.avail_out == 0)
|
||||
{
|
||||
if (mz_stream_lzma_flush(lzma) != MZ_OK)
|
||||
{
|
||||
lzma->error = MZ_STREAM_ERROR;
|
||||
return MZ_STREAM_ERROR;
|
||||
}
|
||||
err = mz_stream_lzma_flush(lzma);
|
||||
if (err != MZ_OK)
|
||||
return err;
|
||||
|
||||
lzma->lstream.avail_out = sizeof(lzma->buffer);
|
||||
lzma->lstream.next_out = lzma->buffer;
|
||||
@@ -261,7 +257,7 @@ static int32_t mz_stream_lzma_code(void *stream, int32_t flush)
|
||||
}
|
||||
|
||||
total_out_before = lzma->lstream.total_out;
|
||||
err = lzma_code(&lzma->lstream, flush);
|
||||
err = lzma_code(&lzma->lstream, (lzma_action)flush);
|
||||
total_out_after = lzma->lstream.total_out;
|
||||
|
||||
out_bytes = (uint32_t)(total_out_after - total_out_before);
|
||||
@@ -269,7 +265,7 @@ static int32_t mz_stream_lzma_code(void *stream, int32_t flush)
|
||||
if (err != LZMA_OK && err != LZMA_STREAM_END)
|
||||
{
|
||||
lzma->error = err;
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_DATA_ERROR;
|
||||
}
|
||||
|
||||
lzma->buffer_len += out_bytes;
|
||||
@@ -279,14 +275,16 @@ static int32_t mz_stream_lzma_code(void *stream, int32_t flush)
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t mz_stream_lzma_write(void *stream, const void *buf, int32_t size)
|
||||
{
|
||||
mz_stream_lzma *lzma = (mz_stream_lzma *)stream;
|
||||
int32_t err = size;
|
||||
|
||||
#ifdef MZ_ZIP_DECOMPRESS_ONLY
|
||||
#ifdef MZ_ZIP_NO_COMPRESSION
|
||||
MZ_UNUSED(lzma);
|
||||
MZ_UNUSED(buf);
|
||||
err = MZ_SUPPORT_ERROR;
|
||||
#else
|
||||
lzma->lstream.next_in = (uint8_t*)(intptr_t)buf;
|
||||
@@ -303,7 +301,7 @@ int64_t mz_stream_lzma_tell(void *stream)
|
||||
{
|
||||
MZ_UNUSED(stream);
|
||||
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_TELL_ERROR;
|
||||
}
|
||||
|
||||
int32_t mz_stream_lzma_seek(void *stream, int64_t offset, int32_t origin)
|
||||
@@ -312,7 +310,7 @@ int32_t mz_stream_lzma_seek(void *stream, int64_t offset, int32_t origin)
|
||||
MZ_UNUSED(offset);
|
||||
MZ_UNUSED(origin);
|
||||
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_SEEK_ERROR;
|
||||
}
|
||||
|
||||
int32_t mz_stream_lzma_close(void *stream)
|
||||
@@ -321,7 +319,7 @@ int32_t mz_stream_lzma_close(void *stream)
|
||||
|
||||
if (lzma->mode & MZ_OPEN_MODE_WRITE)
|
||||
{
|
||||
#ifdef MZ_ZIP_DECOMPRESS_ONLY
|
||||
#ifdef MZ_ZIP_NO_COMPRESSION
|
||||
return MZ_SUPPORT_ERROR;
|
||||
#else
|
||||
mz_stream_lzma_code(stream, LZMA_FINISH);
|
||||
@@ -332,7 +330,7 @@ int32_t mz_stream_lzma_close(void *stream)
|
||||
}
|
||||
else if (lzma->mode & MZ_OPEN_MODE_READ)
|
||||
{
|
||||
#ifdef MZ_ZIP_COMPRESS_ONLY
|
||||
#ifdef MZ_ZIP_NO_DECOMPRESSION
|
||||
return MZ_SUPPORT_ERROR;
|
||||
#else
|
||||
lzma_end(&lzma->lstream);
|
||||
@@ -342,7 +340,7 @@ int32_t mz_stream_lzma_close(void *stream)
|
||||
lzma->initialized = 0;
|
||||
|
||||
if (lzma->error != LZMA_OK)
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_CLOSE_ERROR;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
@@ -436,13 +434,3 @@ void *mz_stream_lzma_get_interface(void)
|
||||
{
|
||||
return (void *)&mz_stream_lzma_vtbl;
|
||||
}
|
||||
|
||||
static int64_t mz_stream_lzma_crc32(int64_t value, const void *buf, int32_t size)
|
||||
{
|
||||
return (int32_t)lzma_crc32(buf, size, (int32_t)value);
|
||||
}
|
||||
|
||||
void *mz_stream_lzma_get_crc32_update(void)
|
||||
{
|
||||
return (void *)mz_stream_lzma_crc32;
|
||||
}
|
||||
|
||||
+2
-5
@@ -1,8 +1,8 @@
|
||||
/* mz_strm_lzma.h -- Stream for lzma inflate/deflate
|
||||
Version 2.3.6, July 11, 2018
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2018 Nathan Moinvaziri
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as lzma.
|
||||
@@ -12,8 +12,6 @@
|
||||
#ifndef MZ_STREAM_LZMA_H
|
||||
#define MZ_STREAM_LZMA_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -36,7 +34,6 @@ void* mz_stream_lzma_create(void **stream);
|
||||
void mz_stream_lzma_delete(void **stream);
|
||||
|
||||
void* mz_stream_lzma_get_interface(void);
|
||||
void* mz_stream_lzma_get_crc32_update(void);
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
+53
-28
@@ -1,5 +1,5 @@
|
||||
/* mz_strm_mem.c -- Stream for memory access
|
||||
Version 2.3.6, July 11, 2018
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
This interface is designed to access memory rather than files.
|
||||
@@ -7,21 +7,17 @@
|
||||
|
||||
Based on Unzip ioapi.c version 0.22, May 19th, 2003
|
||||
|
||||
Copyright (C) 2010-2018 Nathan Moinvaziri
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
Copyright (C) 2003 Justin Fletcher
|
||||
Copyright (C) 1998-2003 Gilles Vollant
|
||||
http://www.winimage.com/zLibDll/minizip.html
|
||||
https://www.winimage.com/zLibDll/minizip.html
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
See the accompanying LICENSE file for the full text of the license.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mz.h"
|
||||
#include "mz_strm.h"
|
||||
#include "mz_strm_mem.h"
|
||||
@@ -48,23 +44,26 @@ static mz_stream_vtbl mz_stream_mem_vtbl = {
|
||||
typedef struct mz_stream_mem_s {
|
||||
mz_stream stream;
|
||||
int32_t mode;
|
||||
char *buffer; // Memory buffer pointer
|
||||
int32_t size; // Size of the memory buffer
|
||||
int32_t limit; // Furthest we've written
|
||||
int32_t position; // Current position in the memory
|
||||
int32_t grow_size; // Size to grow when full
|
||||
uint8_t *buffer; /* Memory buffer pointer */
|
||||
int32_t size; /* Size of the memory buffer */
|
||||
int32_t limit; /* Furthest we've written */
|
||||
int32_t position; /* Current position in the memory */
|
||||
int32_t grow_size; /* Size to grow when full */
|
||||
} mz_stream_mem;
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void mz_stream_mem_set_size(void *stream, int32_t size)
|
||||
static int32_t mz_stream_mem_set_size(void *stream, int32_t size)
|
||||
{
|
||||
mz_stream_mem *mem = (mz_stream_mem *)stream;
|
||||
int32_t new_size = size;
|
||||
char *new_buf = NULL;
|
||||
uint8_t *new_buf = NULL;
|
||||
|
||||
|
||||
new_buf = (char *)MZ_ALLOC(new_size);
|
||||
new_buf = (uint8_t *)MZ_ALLOC((uint32_t)new_size);
|
||||
if (new_buf == NULL)
|
||||
return MZ_BUF_ERROR;
|
||||
|
||||
if (mem->buffer)
|
||||
{
|
||||
memcpy(new_buf, mem->buffer, mem->size);
|
||||
@@ -73,11 +72,13 @@ static void mz_stream_mem_set_size(void *stream, int32_t size)
|
||||
|
||||
mem->buffer = new_buf;
|
||||
mem->size = new_size;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_stream_mem_open(void *stream, const char *path, int32_t mode)
|
||||
{
|
||||
mz_stream_mem *mem = (mz_stream_mem *)stream;
|
||||
int32_t err = MZ_OK;
|
||||
|
||||
MZ_UNUSED(path);
|
||||
|
||||
@@ -86,18 +87,18 @@ int32_t mz_stream_mem_open(void *stream, const char *path, int32_t mode)
|
||||
mem->position = 0;
|
||||
|
||||
if (mem->mode & MZ_OPEN_MODE_CREATE)
|
||||
mz_stream_mem_set_size(stream, mem->grow_size);
|
||||
err = mz_stream_mem_set_size(stream, mem->grow_size);
|
||||
else
|
||||
mem->limit = mem->size;
|
||||
|
||||
return MZ_OK;
|
||||
return err;
|
||||
}
|
||||
|
||||
int32_t mz_stream_mem_is_open(void *stream)
|
||||
{
|
||||
mz_stream_mem *mem = (mz_stream_mem *)stream;
|
||||
if (mem->buffer == NULL)
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_OPEN_ERROR;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
@@ -107,8 +108,10 @@ int32_t mz_stream_mem_read(void *stream, void *buf, int32_t size)
|
||||
|
||||
if (size > mem->size - mem->position)
|
||||
size = mem->size - mem->position;
|
||||
|
||||
if (mem->position + size > mem->limit)
|
||||
size = mem->limit - mem->position;
|
||||
|
||||
if (size <= 0)
|
||||
return 0;
|
||||
|
||||
memcpy(buf, mem->buffer + mem->position, size);
|
||||
@@ -121,6 +124,7 @@ int32_t mz_stream_mem_write(void *stream, const void *buf, int32_t size)
|
||||
{
|
||||
mz_stream_mem *mem = (mz_stream_mem *)stream;
|
||||
int32_t new_size = 0;
|
||||
int32_t err = MZ_OK;
|
||||
|
||||
if (size == 0)
|
||||
return size;
|
||||
@@ -135,7 +139,9 @@ int32_t mz_stream_mem_write(void *stream, const void *buf, int32_t size)
|
||||
else
|
||||
new_size += size;
|
||||
|
||||
mz_stream_mem_set_size(stream, new_size);
|
||||
err = mz_stream_mem_set_size(stream, new_size);
|
||||
if (err != MZ_OK)
|
||||
return err;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -162,6 +168,7 @@ int32_t mz_stream_mem_seek(void *stream, int64_t offset, int32_t origin)
|
||||
{
|
||||
mz_stream_mem *mem = (mz_stream_mem *)stream;
|
||||
int64_t new_pos = 0;
|
||||
int32_t err = MZ_OK;
|
||||
|
||||
switch (origin)
|
||||
{
|
||||
@@ -175,18 +182,24 @@ int32_t mz_stream_mem_seek(void *stream, int64_t offset, int32_t origin)
|
||||
new_pos = offset;
|
||||
break;
|
||||
default:
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_SEEK_ERROR;
|
||||
}
|
||||
|
||||
if (new_pos > mem->size)
|
||||
{
|
||||
if ((mem->mode & MZ_OPEN_MODE_CREATE) == 0)
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_SEEK_ERROR;
|
||||
|
||||
mz_stream_mem_set_size(stream, (int32_t)new_pos);
|
||||
err = mz_stream_mem_set_size(stream, (int32_t)new_pos);
|
||||
if (err != MZ_OK)
|
||||
return err;
|
||||
}
|
||||
else if (new_pos < 0)
|
||||
{
|
||||
return MZ_SEEK_ERROR;
|
||||
}
|
||||
|
||||
mem->position = (uint32_t)new_pos;
|
||||
mem->position = (int32_t)new_pos;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
@@ -194,7 +207,7 @@ int32_t mz_stream_mem_close(void *stream)
|
||||
{
|
||||
MZ_UNUSED(stream);
|
||||
|
||||
// We never return errors
|
||||
/* We never return errors */
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
@@ -202,14 +215,14 @@ int32_t mz_stream_mem_error(void *stream)
|
||||
{
|
||||
MZ_UNUSED(stream);
|
||||
|
||||
// We never return errors
|
||||
/* We never return errors */
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
void mz_stream_mem_set_buffer(void *stream, void *buf, int32_t size)
|
||||
{
|
||||
mz_stream_mem *mem = (mz_stream_mem *)stream;
|
||||
mem->buffer = buf;
|
||||
mem->buffer = (uint8_t *)buf;
|
||||
mem->size = size;
|
||||
mem->limit = size;
|
||||
}
|
||||
@@ -223,17 +236,29 @@ int32_t mz_stream_mem_get_buffer_at(void *stream, int64_t position, const void *
|
||||
{
|
||||
mz_stream_mem *mem = (mz_stream_mem *)stream;
|
||||
if (buf == NULL || position < 0 || mem->size < position || mem->buffer == NULL)
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_SEEK_ERROR;
|
||||
*buf = mem->buffer + position;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_stream_mem_get_buffer_at_current(void *stream, const void **buf)
|
||||
{
|
||||
mz_stream_mem *mem = (mz_stream_mem *)stream;
|
||||
return mz_stream_mem_get_buffer_at(stream, mem->position, buf);
|
||||
}
|
||||
|
||||
void mz_stream_mem_get_buffer_length(void *stream, int32_t *length)
|
||||
{
|
||||
mz_stream_mem *mem = (mz_stream_mem *)stream;
|
||||
*length = mem->limit;
|
||||
}
|
||||
|
||||
void mz_stream_mem_set_buffer_limit(void *stream, int32_t limit)
|
||||
{
|
||||
mz_stream_mem *mem = (mz_stream_mem *)stream;
|
||||
mem->limit = limit;
|
||||
}
|
||||
|
||||
void mz_stream_mem_set_grow_size(void *stream, int32_t grow_size)
|
||||
{
|
||||
mz_stream_mem *mem = (mz_stream_mem *)stream;
|
||||
|
||||
+4
-4
@@ -1,8 +1,8 @@
|
||||
/* mz_strm_mem.h -- Stream for memory access
|
||||
Version 2.3.6, July 11, 2018
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of MiniZip project
|
||||
|
||||
Copyright (C) 2010-2018 Nathan Moinvaziri
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
@@ -12,8 +12,6 @@
|
||||
#ifndef MZ_STREAM_MEM_H
|
||||
#define MZ_STREAM_MEM_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -32,7 +30,9 @@ int32_t mz_stream_mem_error(void *stream);
|
||||
void mz_stream_mem_set_buffer(void *stream, void *buf, int32_t size);
|
||||
int32_t mz_stream_mem_get_buffer(void *stream, const void **buf);
|
||||
int32_t mz_stream_mem_get_buffer_at(void *stream, int64_t position, const void **buf);
|
||||
int32_t mz_stream_mem_get_buffer_at_current(void *stream, const void **buf);
|
||||
void mz_stream_mem_get_buffer_length(void *stream, int32_t *length);
|
||||
void mz_stream_mem_set_buffer_limit(void *stream, int32_t limit);
|
||||
void mz_stream_mem_set_grow_size(void *stream, int32_t grow_size);
|
||||
|
||||
void* mz_stream_mem_create(void **stream);
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/* mz_sstrm_os.h -- Stream for filesystem access
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
See the accompanying LICENSE file for the full text of the license.
|
||||
*/
|
||||
|
||||
#ifndef MZ_STREAM_OS_H
|
||||
#define MZ_STREAM_OS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t mz_stream_os_open(void *stream, const char *path, int32_t mode);
|
||||
int32_t mz_stream_os_is_open(void *stream);
|
||||
int32_t mz_stream_os_read(void *stream, void *buf, int32_t size);
|
||||
int32_t mz_stream_os_write(void *stream, const void *buf, int32_t size);
|
||||
int64_t mz_stream_os_tell(void *stream);
|
||||
int32_t mz_stream_os_seek(void *stream, int64_t offset, int32_t origin);
|
||||
int32_t mz_stream_os_close(void *stream);
|
||||
int32_t mz_stream_os_error(void *stream);
|
||||
|
||||
void* mz_stream_os_create(void **stream);
|
||||
void mz_stream_os_delete(void **stream);
|
||||
|
||||
void* mz_stream_os_get_interface(void);
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,66 +1,59 @@
|
||||
/* mz_strm_posix.c -- Stream for filesystem access for posix/linux
|
||||
Version 2.3.6, July 11, 2018
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2018 Nathan Moinvaziri
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
Modifications for Zip64 support
|
||||
Copyright (C) 2009-2010 Mathias Svensson
|
||||
http://result42.com
|
||||
Copyright (C) 1998-2010 Gilles Vollant
|
||||
http://www.winimage.com/zLibDll/minizip.html
|
||||
https://www.winimage.com/zLibDll/minizip.html
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
See the accompanying LICENSE file for the full text of the license.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "mz.h"
|
||||
#include "mz_strm.h"
|
||||
#include "mz_strm_posix.h"
|
||||
#include "mz_strm_os.h"
|
||||
|
||||
#include <stdio.h> /* fopen, fread.. */
|
||||
#include <errno.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#if defined(MZ_USE_FILE32API)
|
||||
# define fopen64 fopen
|
||||
# define ftello64 ftell
|
||||
# define fseeko64 fseek
|
||||
#else
|
||||
# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \
|
||||
defined(__OpenBSD__) || defined(__APPLE__) || defined(__ANDROID__)
|
||||
# define fopen64 fopen
|
||||
#define fopen64 fopen
|
||||
#ifndef MZ_FILE32_API
|
||||
# ifndef NO_FSEEKO
|
||||
# define ftello64 ftello
|
||||
# define fseeko64 fseeko
|
||||
# elif defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||
# define ftello64 _ftelli64
|
||||
# define fseeko64 _fseeki64
|
||||
# endif
|
||||
# ifdef _MSC_VER
|
||||
# define fopen64 fopen
|
||||
# if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC)))
|
||||
# define ftello64 _ftelli64
|
||||
# define fseeko64 _fseeki64
|
||||
# else /* old MSC */
|
||||
# define ftello64 ftell
|
||||
# define fseeko64 fseek
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#ifndef ftello64
|
||||
# define ftello64 ftell
|
||||
#endif
|
||||
#ifndef fseeko64
|
||||
# define fseeko64 fseek
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static mz_stream_vtbl mz_stream_posix_vtbl = {
|
||||
mz_stream_posix_open,
|
||||
mz_stream_posix_is_open,
|
||||
mz_stream_posix_read,
|
||||
mz_stream_posix_write,
|
||||
mz_stream_posix_tell,
|
||||
mz_stream_posix_seek,
|
||||
mz_stream_posix_close,
|
||||
mz_stream_posix_error,
|
||||
mz_stream_posix_create,
|
||||
mz_stream_posix_delete,
|
||||
static mz_stream_vtbl mz_stream_os_vtbl = {
|
||||
mz_stream_os_open,
|
||||
mz_stream_os_is_open,
|
||||
mz_stream_os_read,
|
||||
mz_stream_os_write,
|
||||
mz_stream_os_tell,
|
||||
mz_stream_os_seek,
|
||||
mz_stream_os_close,
|
||||
mz_stream_os_error,
|
||||
mz_stream_os_create,
|
||||
mz_stream_os_delete,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
@@ -76,13 +69,13 @@ typedef struct mz_stream_posix_s
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t mz_stream_posix_open(void *stream, const char *path, int32_t mode)
|
||||
int32_t mz_stream_os_open(void *stream, const char *path, int32_t mode)
|
||||
{
|
||||
mz_stream_posix *posix = (mz_stream_posix *)stream;
|
||||
const char *mode_fopen = NULL;
|
||||
|
||||
if (path == NULL)
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
if ((mode & MZ_OPEN_MODE_READWRITE) == MZ_OPEN_MODE_READ)
|
||||
mode_fopen = "rb";
|
||||
@@ -91,63 +84,66 @@ int32_t mz_stream_posix_open(void *stream, const char *path, int32_t mode)
|
||||
else if (mode & MZ_OPEN_MODE_CREATE)
|
||||
mode_fopen = "wb";
|
||||
else
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_OPEN_ERROR;
|
||||
|
||||
posix->handle = fopen64(path, mode_fopen);
|
||||
if (posix->handle == NULL)
|
||||
{
|
||||
posix->error = errno;
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_OPEN_ERROR;
|
||||
}
|
||||
|
||||
if (mode & MZ_OPEN_MODE_APPEND)
|
||||
return mz_stream_os_seek(stream, 0, MZ_SEEK_END);
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_stream_posix_is_open(void *stream)
|
||||
int32_t mz_stream_os_is_open(void *stream)
|
||||
{
|
||||
mz_stream_posix *posix = (mz_stream_posix*)stream;
|
||||
if (posix->handle == NULL)
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_OPEN_ERROR;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_stream_posix_read(void *stream, void *buf, int32_t size)
|
||||
int32_t mz_stream_os_read(void *stream, void *buf, int32_t size)
|
||||
{
|
||||
mz_stream_posix *posix = (mz_stream_posix*)stream;
|
||||
int32_t read = (int32_t)fread(buf, 1, (size_t)size, posix->handle);
|
||||
if (read < size && ferror(posix->handle))
|
||||
{
|
||||
posix->error = errno;
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_READ_ERROR;
|
||||
}
|
||||
return read;
|
||||
}
|
||||
|
||||
int32_t mz_stream_posix_write(void *stream, const void *buf, int32_t size)
|
||||
int32_t mz_stream_os_write(void *stream, const void *buf, int32_t size)
|
||||
{
|
||||
mz_stream_posix *posix = (mz_stream_posix*)stream;
|
||||
int32_t written = (int32_t)fwrite(buf, 1, (size_t)size, posix->handle);
|
||||
if (written < size && ferror(posix->handle))
|
||||
{
|
||||
posix->error = errno;
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_WRITE_ERROR;
|
||||
}
|
||||
return written;
|
||||
}
|
||||
|
||||
int64_t mz_stream_posix_tell(void *stream)
|
||||
int64_t mz_stream_os_tell(void *stream)
|
||||
{
|
||||
mz_stream_posix *posix = (mz_stream_posix*)stream;
|
||||
int64_t position = ftello64(posix->handle);
|
||||
if (position == -1)
|
||||
{
|
||||
posix->error = errno;
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_TELL_ERROR;
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
int32_t mz_stream_posix_seek(void *stream, int64_t offset, int32_t origin)
|
||||
int32_t mz_stream_os_seek(void *stream, int64_t offset, int32_t origin)
|
||||
{
|
||||
mz_stream_posix *posix = (mz_stream_posix*)stream;
|
||||
int32_t fseek_origin = 0;
|
||||
@@ -164,19 +160,19 @@ int32_t mz_stream_posix_seek(void *stream, int64_t offset, int32_t origin)
|
||||
fseek_origin = SEEK_SET;
|
||||
break;
|
||||
default:
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_SEEK_ERROR;
|
||||
}
|
||||
|
||||
if (fseeko64(posix->handle, offset, fseek_origin) != 0)
|
||||
{
|
||||
posix->error = errno;
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_SEEK_ERROR;
|
||||
}
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_stream_posix_close(void *stream)
|
||||
int32_t mz_stream_os_close(void *stream)
|
||||
{
|
||||
mz_stream_posix *posix = (mz_stream_posix*)stream;
|
||||
int32_t closed = 0;
|
||||
@@ -188,18 +184,18 @@ int32_t mz_stream_posix_close(void *stream)
|
||||
if (closed != 0)
|
||||
{
|
||||
posix->error = errno;
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_CLOSE_ERROR;
|
||||
}
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_stream_posix_error(void *stream)
|
||||
int32_t mz_stream_os_error(void *stream)
|
||||
{
|
||||
mz_stream_posix *posix = (mz_stream_posix*)stream;
|
||||
return posix->error;
|
||||
}
|
||||
|
||||
void *mz_stream_posix_create(void **stream)
|
||||
void *mz_stream_os_create(void **stream)
|
||||
{
|
||||
mz_stream_posix *posix = NULL;
|
||||
|
||||
@@ -207,7 +203,7 @@ void *mz_stream_posix_create(void **stream)
|
||||
if (posix != NULL)
|
||||
{
|
||||
memset(posix, 0, sizeof(mz_stream_posix));
|
||||
posix->stream.vtbl = &mz_stream_posix_vtbl;
|
||||
posix->stream.vtbl = &mz_stream_os_vtbl;
|
||||
}
|
||||
if (stream != NULL)
|
||||
*stream = posix;
|
||||
@@ -215,7 +211,7 @@ void *mz_stream_posix_create(void **stream)
|
||||
return posix;
|
||||
}
|
||||
|
||||
void mz_stream_posix_delete(void **stream)
|
||||
void mz_stream_os_delete(void **stream)
|
||||
{
|
||||
mz_stream_posix *posix = NULL;
|
||||
if (stream == NULL)
|
||||
@@ -226,7 +222,7 @@ void mz_stream_posix_delete(void **stream)
|
||||
*stream = NULL;
|
||||
}
|
||||
|
||||
void *mz_stream_posix_get_interface(void)
|
||||
void *mz_stream_os_get_interface(void)
|
||||
{
|
||||
return (void *)&mz_stream_posix_vtbl;
|
||||
return (void *)&mz_stream_os_vtbl;
|
||||
}
|
||||
@@ -1,26 +1,26 @@
|
||||
/* mz_strm_win32.c -- Stream for filesystem access for windows
|
||||
Version 2.3.6, July 11, 2018
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2018 Nathan Moinvaziri
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
Copyright (C) 2009-2010 Mathias Svensson
|
||||
Modifications for Zip64 support
|
||||
http://result42.com
|
||||
Copyright (C) 1998-2010 Gilles Vollant
|
||||
http://www.winimage.com/zLibDll/minizip.html
|
||||
https://www.winimage.com/zLibDll/minizip.html
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
See the accompanying LICENSE file for the full text of the license.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "mz.h"
|
||||
#include "mz_os.h"
|
||||
#include "mz_strm.h"
|
||||
#include "mz_strm_win32.h"
|
||||
#include "mz_strm_os.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
@@ -40,17 +40,17 @@
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static mz_stream_vtbl mz_stream_win32_vtbl = {
|
||||
mz_stream_win32_open,
|
||||
mz_stream_win32_is_open,
|
||||
mz_stream_win32_read,
|
||||
mz_stream_win32_write,
|
||||
mz_stream_win32_tell,
|
||||
mz_stream_win32_seek,
|
||||
mz_stream_win32_close,
|
||||
mz_stream_win32_error,
|
||||
mz_stream_win32_create,
|
||||
mz_stream_win32_delete,
|
||||
static mz_stream_vtbl mz_stream_os_vtbl = {
|
||||
mz_stream_os_open,
|
||||
mz_stream_os_is_open,
|
||||
mz_stream_os_read,
|
||||
mz_stream_os_write,
|
||||
mz_stream_os_tell,
|
||||
mz_stream_os_seek,
|
||||
mz_stream_os_close,
|
||||
mz_stream_os_error,
|
||||
mz_stream_os_create,
|
||||
mz_stream_os_delete,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
@@ -66,7 +66,15 @@ typedef struct mz_stream_win32_s
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t mz_stream_win32_open(void *stream, const char *path, int32_t mode)
|
||||
#if 0
|
||||
# define mz_stream_os_print printf
|
||||
#else
|
||||
# define mz_stream_os_print(fmt,...)
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t mz_stream_os_open(void *stream, const char *path, int32_t mode)
|
||||
{
|
||||
mz_stream_win32 *win32 = (mz_stream_win32 *)stream;
|
||||
uint32_t desired_access = 0;
|
||||
@@ -74,11 +82,13 @@ int32_t mz_stream_win32_open(void *stream, const char *path, int32_t mode)
|
||||
uint32_t share_mode = FILE_SHARE_READ;
|
||||
uint32_t flags_attribs = FILE_ATTRIBUTE_NORMAL;
|
||||
wchar_t *path_wide = NULL;
|
||||
uint32_t path_wide_size = 0;
|
||||
|
||||
|
||||
if (path == NULL)
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
/* Some use cases require write sharing as well */
|
||||
share_mode |= FILE_SHARE_WRITE;
|
||||
|
||||
if ((mode & MZ_OPEN_MODE_READWRITE) == MZ_OPEN_MODE_READ)
|
||||
{
|
||||
@@ -97,50 +107,52 @@ int32_t mz_stream_win32_open(void *stream, const char *path, int32_t mode)
|
||||
}
|
||||
else
|
||||
{
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_PARAM_ERROR;
|
||||
}
|
||||
|
||||
path_wide_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
|
||||
path_wide = (wchar_t *)MZ_ALLOC((path_wide_size + 1) * sizeof(wchar_t));
|
||||
memset(path_wide, 0, sizeof(wchar_t) * (path_wide_size + 1));
|
||||
mz_stream_os_print("Win32 - Open - %s (mode %" PRId32 ")\n", path);
|
||||
|
||||
MultiByteToWideChar(CP_UTF8, 0, path, -1, path_wide, path_wide_size);
|
||||
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
|
||||
if (path_wide == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
#ifdef MZ_WINRT_API
|
||||
win32->handle = CreateFile2W(path_wide, desired_access, share_mode, creation_disposition, NULL);
|
||||
win32->handle = CreateFile2W(path_wide, desired_access, share_mode,
|
||||
creation_disposition, NULL);
|
||||
#else
|
||||
win32->handle = CreateFileW(path_wide, desired_access, share_mode, NULL, creation_disposition, flags_attribs, NULL);
|
||||
win32->handle = CreateFileW(path_wide, desired_access, share_mode, NULL,
|
||||
creation_disposition, flags_attribs, NULL);
|
||||
#endif
|
||||
|
||||
MZ_FREE(path_wide);
|
||||
mz_os_unicode_string_delete(&path_wide);
|
||||
|
||||
if (mz_stream_win32_is_open(stream) != MZ_OK)
|
||||
if (mz_stream_os_is_open(stream) != MZ_OK)
|
||||
{
|
||||
win32->error = GetLastError();
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_OPEN_ERROR;
|
||||
}
|
||||
|
||||
if (mode & MZ_OPEN_MODE_APPEND)
|
||||
return mz_stream_win32_seek(stream, 0, MZ_SEEK_END);
|
||||
return mz_stream_os_seek(stream, 0, MZ_SEEK_END);
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_stream_win32_is_open(void *stream)
|
||||
int32_t mz_stream_os_is_open(void *stream)
|
||||
{
|
||||
mz_stream_win32 *win32 = (mz_stream_win32 *)stream;
|
||||
if (win32->handle == NULL || win32->handle == INVALID_HANDLE_VALUE)
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_OPEN_ERROR;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_stream_win32_read(void *stream, void *buf, int32_t size)
|
||||
int32_t mz_stream_os_read(void *stream, void *buf, int32_t size)
|
||||
{
|
||||
mz_stream_win32 *win32 = (mz_stream_win32 *)stream;
|
||||
uint32_t read = 0;
|
||||
|
||||
if (mz_stream_win32_is_open(stream) != MZ_OK)
|
||||
return MZ_STREAM_ERROR;
|
||||
if (mz_stream_os_is_open(stream) != MZ_OK)
|
||||
return MZ_OPEN_ERROR;
|
||||
|
||||
if (!ReadFile(win32->handle, buf, size, (DWORD *)&read, NULL))
|
||||
{
|
||||
@@ -149,16 +161,18 @@ int32_t mz_stream_win32_read(void *stream, void *buf, int32_t size)
|
||||
win32->error = 0;
|
||||
}
|
||||
|
||||
mz_stream_os_print("Win32 - Read - %" PRId32 "\n", read);
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
int32_t mz_stream_win32_write(void *stream, const void *buf, int32_t size)
|
||||
int32_t mz_stream_os_write(void *stream, const void *buf, int32_t size)
|
||||
{
|
||||
mz_stream_win32 *win32 = (mz_stream_win32 *)stream;
|
||||
uint32_t written = 0;
|
||||
int32_t written = 0;
|
||||
|
||||
if (mz_stream_win32_is_open(stream) != MZ_OK)
|
||||
return MZ_STREAM_ERROR;
|
||||
if (mz_stream_os_is_open(stream) != MZ_OK)
|
||||
return MZ_OPEN_ERROR;
|
||||
|
||||
if (!WriteFile(win32->handle, buf, size, (DWORD *)&written, NULL))
|
||||
{
|
||||
@@ -167,19 +181,25 @@ int32_t mz_stream_win32_write(void *stream, const void *buf, int32_t size)
|
||||
win32->error = 0;
|
||||
}
|
||||
|
||||
mz_stream_os_print("Win32 - Write - %" PRId32 "\n", written);
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
static int32_t mz_stream_win32_seekinternal(HANDLE handle, LARGE_INTEGER large_pos, LARGE_INTEGER *new_pos, uint32_t move_method)
|
||||
static int32_t mz_stream_os_seekinternal(HANDLE handle, LARGE_INTEGER large_pos,
|
||||
LARGE_INTEGER *new_pos, uint32_t move_method)
|
||||
{
|
||||
#ifdef MZ_WINRT_API
|
||||
return SetFilePointerEx(handle, pos, newPos, dwMoveMethod);
|
||||
#else
|
||||
LONG high_part = large_pos.HighPart;
|
||||
uint32_t pos = SetFilePointer(handle, large_pos.LowPart, &high_part, move_method);
|
||||
LONG high_part = 0;
|
||||
uint32_t pos = 0;
|
||||
|
||||
high_part = large_pos.HighPart;
|
||||
pos = SetFilePointer(handle, large_pos.LowPart, &high_part, move_method);
|
||||
|
||||
if ((pos == INVALID_SET_FILE_POINTER) && (GetLastError() != NO_ERROR))
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_SEEK_ERROR;
|
||||
|
||||
if (new_pos != NULL)
|
||||
{
|
||||
@@ -191,31 +211,34 @@ static int32_t mz_stream_win32_seekinternal(HANDLE handle, LARGE_INTEGER large_p
|
||||
#endif
|
||||
}
|
||||
|
||||
int64_t mz_stream_win32_tell(void *stream)
|
||||
int64_t mz_stream_os_tell(void *stream)
|
||||
{
|
||||
mz_stream_win32 *win32 = (mz_stream_win32 *)stream;
|
||||
LARGE_INTEGER large_pos;
|
||||
|
||||
if (mz_stream_win32_is_open(stream) != MZ_OK)
|
||||
return MZ_STREAM_ERROR;
|
||||
if (mz_stream_os_is_open(stream) != MZ_OK)
|
||||
return MZ_OPEN_ERROR;
|
||||
|
||||
large_pos.QuadPart = 0;
|
||||
|
||||
if (mz_stream_win32_seekinternal(win32->handle, large_pos, &large_pos, FILE_CURRENT) != MZ_OK)
|
||||
if (mz_stream_os_seekinternal(win32->handle, large_pos, &large_pos, FILE_CURRENT) != MZ_OK)
|
||||
win32->error = GetLastError();
|
||||
|
||||
mz_stream_os_print("Win32 - Tell - %" PRId64 "\n", large_pos.QuadPart);
|
||||
|
||||
return large_pos.QuadPart;
|
||||
}
|
||||
|
||||
int32_t mz_stream_win32_seek(void *stream, int64_t offset, int32_t origin)
|
||||
int32_t mz_stream_os_seek(void *stream, int64_t offset, int32_t origin)
|
||||
{
|
||||
mz_stream_win32 *win32 = (mz_stream_win32 *)stream;
|
||||
uint32_t move_method = 0xFFFFFFFF;
|
||||
int32_t err = MZ_OK;
|
||||
LARGE_INTEGER large_pos;
|
||||
|
||||
|
||||
if (mz_stream_win32_is_open(stream) == MZ_STREAM_ERROR)
|
||||
return MZ_STREAM_ERROR;
|
||||
if (mz_stream_os_is_open(stream) != MZ_OK)
|
||||
return MZ_OPEN_ERROR;
|
||||
|
||||
switch (origin)
|
||||
{
|
||||
@@ -229,37 +252,41 @@ int32_t mz_stream_win32_seek(void *stream, int64_t offset, int32_t origin)
|
||||
move_method = FILE_BEGIN;
|
||||
break;
|
||||
default:
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_SEEK_ERROR;
|
||||
}
|
||||
|
||||
mz_stream_os_print("Win32 - Seek - %" PRId64 " (origin %" PRId32 ")\n", offset, origin);
|
||||
|
||||
large_pos.QuadPart = offset;
|
||||
|
||||
if (mz_stream_win32_seekinternal(win32->handle, large_pos, NULL, move_method) != MZ_OK)
|
||||
err = mz_stream_os_seekinternal(win32->handle, large_pos, NULL, move_method);
|
||||
if (err != MZ_OK)
|
||||
{
|
||||
win32->error = GetLastError();
|
||||
return MZ_STREAM_ERROR;
|
||||
return err;
|
||||
}
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int mz_stream_win32_close(void *stream)
|
||||
int32_t mz_stream_os_close(void *stream)
|
||||
{
|
||||
mz_stream_win32 *win32 = (mz_stream_win32 *)stream;
|
||||
|
||||
if (win32->handle != NULL)
|
||||
CloseHandle(win32->handle);
|
||||
mz_stream_os_print("Win32 - Close\n");
|
||||
win32->handle = NULL;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int mz_stream_win32_error(void *stream)
|
||||
int32_t mz_stream_os_error(void *stream)
|
||||
{
|
||||
mz_stream_win32 *win32 = (mz_stream_win32 *)stream;
|
||||
return win32->error;
|
||||
}
|
||||
|
||||
void *mz_stream_win32_create(void **stream)
|
||||
void *mz_stream_os_create(void **stream)
|
||||
{
|
||||
mz_stream_win32 *win32 = NULL;
|
||||
|
||||
@@ -267,7 +294,7 @@ void *mz_stream_win32_create(void **stream)
|
||||
if (win32 != NULL)
|
||||
{
|
||||
memset(win32, 0, sizeof(mz_stream_win32));
|
||||
win32->stream.vtbl = &mz_stream_win32_vtbl;
|
||||
win32->stream.vtbl = &mz_stream_os_vtbl;
|
||||
}
|
||||
if (stream != NULL)
|
||||
*stream = win32;
|
||||
@@ -275,7 +302,7 @@ void *mz_stream_win32_create(void **stream)
|
||||
return win32;
|
||||
}
|
||||
|
||||
void mz_stream_win32_delete(void **stream)
|
||||
void mz_stream_os_delete(void **stream)
|
||||
{
|
||||
mz_stream_win32 *win32 = NULL;
|
||||
if (stream == NULL)
|
||||
@@ -286,7 +313,7 @@ void mz_stream_win32_delete(void **stream)
|
||||
*stream = NULL;
|
||||
}
|
||||
|
||||
void *mz_stream_win32_get_interface(void)
|
||||
void *mz_stream_os_get_interface(void)
|
||||
{
|
||||
return (void *)&mz_stream_win32_vtbl;
|
||||
return (void *)&mz_stream_os_vtbl;
|
||||
}
|
||||
+112
-71
@@ -1,44 +1,35 @@
|
||||
/* mz_strm_pkcrypt.c -- Code for traditional PKWARE encryption
|
||||
Version 2.3.6, July 11, 2018
|
||||
part of the MiniZip project
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2018 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
Copyright (C) 1998-2005 Gilles Vollant
|
||||
Modifications for Info-ZIP crypting
|
||||
http://www.winimage.com/zLibDll/minizip.html
|
||||
Copyright (C) 2003 Terry Thorsen
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
Copyright (C) 1998-2005 Gilles Vollant
|
||||
Modifications for Info-ZIP crypting
|
||||
https://www.winimage.com/zLibDll/minizip.html
|
||||
Copyright (C) 2003 Terry Thorsen
|
||||
|
||||
This code is a modified version of crypting code in Info-ZIP distribution
|
||||
This code is a modified version of crypting code in Info-ZIP distribution
|
||||
|
||||
Copyright (C) 1990-2000 Info-ZIP. All rights reserved.
|
||||
Copyright (C) 1990-2000 Info-ZIP. All rights reserved.
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
See the accompanying LICENSE file for the full text of the license.
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
See the accompanying LICENSE file for the full text of the license.
|
||||
|
||||
This encryption code is a direct transcription of the algorithm from
|
||||
Roger Schlafly, described by Phil Katz in the file appnote.txt. This
|
||||
file (appnote.txt) is distributed with the PKZIP program (even in the
|
||||
version without encryption capabilities).
|
||||
This encryption code is a direct transcription of the algorithm from
|
||||
Roger Schlafly, described by Phil Katz in the file appnote.txt. This
|
||||
file (appnote.txt) is distributed with the PKZIP program (even in the
|
||||
version without encryption capabilities).
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mz.h"
|
||||
#include "mz_os.h"
|
||||
#include "mz_crypt.h"
|
||||
#include "mz_strm.h"
|
||||
#include "mz_strm_crc32.h"
|
||||
#include "mz_strm_pkcrypt.h"
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#define RAND_HEAD_LEN (12)
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static mz_stream_vtbl mz_stream_pkcrypt_vtbl = {
|
||||
mz_stream_pkcrypt_open,
|
||||
mz_stream_pkcrypt_is_open,
|
||||
@@ -51,7 +42,7 @@ static mz_stream_vtbl mz_stream_pkcrypt_vtbl = {
|
||||
mz_stream_pkcrypt_create,
|
||||
mz_stream_pkcrypt_delete,
|
||||
mz_stream_pkcrypt_get_prop_int64,
|
||||
NULL
|
||||
mz_stream_pkcrypt_set_prop_int64
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
@@ -60,26 +51,25 @@ typedef struct mz_stream_pkcrypt_s {
|
||||
mz_stream stream;
|
||||
int32_t error;
|
||||
int16_t initialized;
|
||||
uint8_t buffer[INT16_MAX];
|
||||
uint8_t buffer[UINT16_MAX];
|
||||
int64_t total_in;
|
||||
int64_t max_total_in;
|
||||
int64_t total_out;
|
||||
uint32_t keys[3]; // keys defining the pseudo-random sequence
|
||||
uint32_t keys[3]; /* keys defining the pseudo-random sequence */
|
||||
uint8_t verify1;
|
||||
uint8_t verify2;
|
||||
const char *password;
|
||||
mz_stream_crc32_update
|
||||
crc32_update;
|
||||
} mz_stream_pkcrypt;
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#define mz_stream_pkcrypt_decode(strm, c) \
|
||||
(mz_stream_pkcrypt_update_keys(strm, \
|
||||
#define mz_stream_pkcrypt_decode(strm, c) \
|
||||
(mz_stream_pkcrypt_update_keys(strm, \
|
||||
c ^= mz_stream_pkcrypt_decrypt_byte(strm)))
|
||||
|
||||
#define mz_stream_pkcrypt_encode(strm, c, t) \
|
||||
(t = mz_stream_pkcrypt_decrypt_byte(strm), \
|
||||
mz_stream_pkcrypt_update_keys(strm, c), t^(c))
|
||||
#define mz_stream_pkcrypt_encode(strm, c, t) \
|
||||
(t = mz_stream_pkcrypt_decrypt_byte(strm), \
|
||||
mz_stream_pkcrypt_update_keys(strm, (uint8_t)c), (uint8_t)(t^(c)))
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
@@ -87,9 +77,9 @@ static uint8_t mz_stream_pkcrypt_decrypt_byte(void *stream)
|
||||
{
|
||||
mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream;
|
||||
|
||||
unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
|
||||
* unpredictable manner on 16-bit systems; not a problem
|
||||
* with any known compiler so far, though */
|
||||
unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an */
|
||||
/* unpredictable manner on 16-bit systems; not a problem */
|
||||
/* with any known compiler so far, though. */
|
||||
|
||||
temp = pkcrypt->keys[2] | 2;
|
||||
return (uint8_t)(((temp * (temp ^ 1)) >> 8) & 0xff);
|
||||
@@ -100,14 +90,14 @@ static uint8_t mz_stream_pkcrypt_update_keys(void *stream, uint8_t c)
|
||||
mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream;
|
||||
uint8_t buf = c;
|
||||
|
||||
pkcrypt->keys[0] = (uint32_t)~pkcrypt->crc32_update(~pkcrypt->keys[0], &buf, 1);
|
||||
pkcrypt->keys[0] = (uint32_t)~mz_crypt_crc32_update(~pkcrypt->keys[0], &buf, 1);
|
||||
|
||||
pkcrypt->keys[1] += pkcrypt->keys[0] & 0xff;
|
||||
pkcrypt->keys[1] *= 134775813L;
|
||||
pkcrypt->keys[1] += 1;
|
||||
|
||||
buf = (uint8_t)(pkcrypt->keys[1] >> 24);
|
||||
pkcrypt->keys[2] = (uint32_t)~pkcrypt->crc32_update(~pkcrypt->keys[2], &buf, 1);
|
||||
pkcrypt->keys[2] = (uint32_t)~mz_crypt_crc32_update(~pkcrypt->keys[2], &buf, 1);
|
||||
|
||||
return (uint8_t)c;
|
||||
}
|
||||
@@ -122,7 +112,7 @@ static void mz_stream_pkcrypt_init_keys(void *stream, const char *password)
|
||||
|
||||
while (*password != 0)
|
||||
{
|
||||
mz_stream_pkcrypt_update_keys(stream, *password);
|
||||
mz_stream_pkcrypt_update_keys(stream, (uint8_t)*password);
|
||||
password += 1;
|
||||
}
|
||||
}
|
||||
@@ -136,7 +126,7 @@ int32_t mz_stream_pkcrypt_open(void *stream, const char *path, int32_t mode)
|
||||
int16_t i = 0;
|
||||
uint8_t verify1 = 0;
|
||||
uint8_t verify2 = 0;
|
||||
uint8_t header[RAND_HEAD_LEN];
|
||||
uint8_t header[MZ_PKCRYPT_HEADER_SIZE];
|
||||
const char *password = path;
|
||||
|
||||
pkcrypt->total_in = 0;
|
||||
@@ -144,52 +134,65 @@ int32_t mz_stream_pkcrypt_open(void *stream, const char *path, int32_t mode)
|
||||
pkcrypt->initialized = 0;
|
||||
|
||||
if (mz_stream_is_open(pkcrypt->stream.base) != MZ_OK)
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_OPEN_ERROR;
|
||||
|
||||
if (password == NULL)
|
||||
password = pkcrypt->password;
|
||||
if (password == NULL)
|
||||
return MZ_STREAM_ERROR;
|
||||
|
||||
if (mz_stream_crc32_get_update_func(&pkcrypt->crc32_update) != MZ_OK)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
mz_stream_pkcrypt_init_keys(stream, password);
|
||||
|
||||
if (mode & MZ_OPEN_MODE_WRITE)
|
||||
{
|
||||
// First generate RAND_HEAD_LEN - 2 random bytes.
|
||||
mz_os_rand(header, RAND_HEAD_LEN - 2);
|
||||
#ifdef MZ_ZIP_NO_COMPRESSION
|
||||
MZ_UNUSED(t);
|
||||
MZ_UNUSED(i);
|
||||
|
||||
// Encrypt random header (last two bytes is high word of crc)
|
||||
for (i = 0; i < RAND_HEAD_LEN - 2; i++)
|
||||
return MZ_SUPPORT_ERROR;
|
||||
#else
|
||||
/* First generate RAND_HEAD_LEN - 2 random bytes. */
|
||||
mz_crypt_rand(header, MZ_PKCRYPT_HEADER_SIZE - 2);
|
||||
|
||||
/* Encrypt random header (last two bytes is high word of crc) */
|
||||
for (i = 0; i < MZ_PKCRYPT_HEADER_SIZE - 2; i++)
|
||||
header[i] = mz_stream_pkcrypt_encode(stream, header[i], t);
|
||||
|
||||
header[i++] = mz_stream_pkcrypt_encode(stream, pkcrypt->verify1, t);
|
||||
header[i++] = mz_stream_pkcrypt_encode(stream, pkcrypt->verify2, t);
|
||||
|
||||
if (mz_stream_write(pkcrypt->stream.base, header, RAND_HEAD_LEN) != RAND_HEAD_LEN)
|
||||
return MZ_STREAM_ERROR;
|
||||
if (mz_stream_write(pkcrypt->stream.base, header, sizeof(header)) != sizeof(header))
|
||||
return MZ_WRITE_ERROR;
|
||||
|
||||
pkcrypt->total_out += RAND_HEAD_LEN;
|
||||
pkcrypt->total_out += MZ_PKCRYPT_HEADER_SIZE;
|
||||
#endif
|
||||
}
|
||||
else if (mode & MZ_OPEN_MODE_READ)
|
||||
{
|
||||
if (mz_stream_read(pkcrypt->stream.base, header, RAND_HEAD_LEN) != RAND_HEAD_LEN)
|
||||
return MZ_STREAM_ERROR;
|
||||
#ifdef MZ_ZIP_NO_DECOMPRESSION
|
||||
MZ_UNUSED(t);
|
||||
MZ_UNUSED(i);
|
||||
MZ_UNUSED(verify1);
|
||||
MZ_UNUSED(verify2);
|
||||
|
||||
for (i = 0; i < RAND_HEAD_LEN - 2; i++)
|
||||
return MZ_SUPPORT_ERROR;
|
||||
#else
|
||||
if (mz_stream_read(pkcrypt->stream.base, header, sizeof(header)) != sizeof(header))
|
||||
return MZ_READ_ERROR;
|
||||
|
||||
for (i = 0; i < MZ_PKCRYPT_HEADER_SIZE - 2; i++)
|
||||
header[i] = mz_stream_pkcrypt_decode(stream, header[i]);
|
||||
|
||||
verify1 = mz_stream_pkcrypt_decode(stream, header[i++]);
|
||||
verify2 = mz_stream_pkcrypt_decode(stream, header[i++]);
|
||||
|
||||
// Older versions used 2 byte check, newer versions use 1 byte check.
|
||||
/* Older versions used 2 byte check, newer versions use 1 byte check. */
|
||||
MZ_UNUSED(verify1);
|
||||
if ((verify2 != 0) && (verify2 != pkcrypt->verify2))
|
||||
return MZ_PASSWORD_ERROR;
|
||||
|
||||
pkcrypt->total_in += RAND_HEAD_LEN;
|
||||
pkcrypt->total_in += MZ_PKCRYPT_HEADER_SIZE;
|
||||
#endif
|
||||
}
|
||||
|
||||
pkcrypt->initialized = 1;
|
||||
@@ -200,7 +203,7 @@ int32_t mz_stream_pkcrypt_is_open(void *stream)
|
||||
{
|
||||
mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream;
|
||||
if (pkcrypt->initialized == 0)
|
||||
return MZ_STREAM_ERROR;
|
||||
return MZ_OPEN_ERROR;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
@@ -208,15 +211,22 @@ int32_t mz_stream_pkcrypt_read(void *stream, void *buf, int32_t size)
|
||||
{
|
||||
mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream;
|
||||
uint8_t *buf_ptr = (uint8_t *)buf;
|
||||
int32_t bytes_to_read = size;
|
||||
int32_t read = 0;
|
||||
int32_t i = 0;
|
||||
|
||||
read = mz_stream_read(pkcrypt->stream.base, buf, size);
|
||||
|
||||
if ((int64_t)bytes_to_read > (pkcrypt->max_total_in - pkcrypt->total_in))
|
||||
bytes_to_read = (int32_t)(pkcrypt->max_total_in - pkcrypt->total_in);
|
||||
|
||||
read = mz_stream_read(pkcrypt->stream.base, buf, bytes_to_read);
|
||||
|
||||
for (i = 0; i < read; i++)
|
||||
buf_ptr[i] = mz_stream_pkcrypt_decode(stream, buf_ptr[i]);
|
||||
|
||||
pkcrypt->total_in += read;
|
||||
if (read > 0)
|
||||
pkcrypt->total_in += read;
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
@@ -224,22 +234,36 @@ int32_t mz_stream_pkcrypt_write(void *stream, const void *buf, int32_t size)
|
||||
{
|
||||
mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream;
|
||||
const uint8_t *buf_ptr = (const uint8_t *)buf;
|
||||
int32_t bytes_to_write = sizeof(pkcrypt->buffer);
|
||||
int32_t total_written = 0;
|
||||
int32_t written = 0;
|
||||
int32_t i = 0;
|
||||
uint16_t t = 0;
|
||||
|
||||
if (size > (int32_t)sizeof(pkcrypt->buffer))
|
||||
return MZ_STREAM_ERROR;
|
||||
if (size < 0)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
pkcrypt->buffer[i] = mz_stream_pkcrypt_encode(stream, buf_ptr[i], t);
|
||||
do
|
||||
{
|
||||
if (bytes_to_write > (size - total_written))
|
||||
bytes_to_write = (size - total_written);
|
||||
|
||||
written = mz_stream_write(pkcrypt->stream.base, pkcrypt->buffer, size);
|
||||
for (i = 0; i < bytes_to_write; i += 1)
|
||||
{
|
||||
pkcrypt->buffer[i] = mz_stream_pkcrypt_encode(stream, *buf_ptr, t);
|
||||
buf_ptr += 1;
|
||||
}
|
||||
|
||||
if (written > 0)
|
||||
pkcrypt->total_out += written;
|
||||
written = mz_stream_write(pkcrypt->stream.base, pkcrypt->buffer, bytes_to_write);
|
||||
if (written < 0)
|
||||
return written;
|
||||
|
||||
return written;
|
||||
total_written += written;
|
||||
}
|
||||
while (total_written < size && written > 0);
|
||||
|
||||
pkcrypt->total_out += total_written;
|
||||
return total_written;
|
||||
}
|
||||
|
||||
int64_t mz_stream_pkcrypt_tell(void *stream)
|
||||
@@ -298,8 +322,11 @@ int32_t mz_stream_pkcrypt_get_prop_int64(void *stream, int32_t prop, int64_t *va
|
||||
case MZ_STREAM_PROP_TOTAL_OUT:
|
||||
*value = pkcrypt->total_out;
|
||||
break;
|
||||
case MZ_STREAM_PROP_TOTAL_IN_MAX:
|
||||
*value = pkcrypt->max_total_in;
|
||||
break;
|
||||
case MZ_STREAM_PROP_HEADER_SIZE:
|
||||
*value = RAND_HEAD_LEN;
|
||||
*value = MZ_PKCRYPT_HEADER_SIZE;
|
||||
break;
|
||||
case MZ_STREAM_PROP_FOOTER_SIZE:
|
||||
*value = 0;
|
||||
@@ -310,6 +337,20 @@ int32_t mz_stream_pkcrypt_get_prop_int64(void *stream, int32_t prop, int64_t *va
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int32_t mz_stream_pkcrypt_set_prop_int64(void *stream, int32_t prop, int64_t value)
|
||||
{
|
||||
mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream;
|
||||
switch (prop)
|
||||
{
|
||||
case MZ_STREAM_PROP_TOTAL_IN_MAX:
|
||||
pkcrypt->max_total_in = value;
|
||||
break;
|
||||
default:
|
||||
return MZ_EXIST_ERROR;
|
||||
}
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
void *mz_stream_pkcrypt_create(void **stream)
|
||||
{
|
||||
mz_stream_pkcrypt *pkcrypt = NULL;
|
||||
|
||||
+3
-4
@@ -1,8 +1,8 @@
|
||||
/* mz_strm_pkcrypt.h -- Code for traditional PKWARE encryption
|
||||
Version 2.3.6, July 11, 2018
|
||||
Version 2.9.2, February 12, 2020
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2018 Nathan Moinvaziri
|
||||
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
@@ -12,8 +12,6 @@
|
||||
#ifndef MZ_STREAM_PKCRYPT_H
|
||||
#define MZ_STREAM_PKCRYPT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -33,6 +31,7 @@ void mz_stream_pkcrypt_set_password(void *stream, const char *password);
|
||||
void mz_stream_pkcrypt_set_verify(void *stream, uint8_t verify1, uint8_t verify2);
|
||||
void mz_stream_pkcrypt_get_verify(void *stream, uint8_t *verify1, uint8_t *verify2);
|
||||
int32_t mz_stream_pkcrypt_get_prop_int64(void *stream, int32_t prop, int64_t *value);
|
||||
int32_t mz_stream_pkcrypt_set_prop_int64(void *stream, int32_t prop, int64_t value);
|
||||
|
||||
void* mz_stream_pkcrypt_create(void **stream);
|
||||
void mz_stream_pkcrypt_delete(void **stream);
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
/* mz_strm_posix.h -- Stream for filesystem access for posix/linux
|
||||
Version 2.3.6, July 11, 2018
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2018 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
||||
This program is distributed under the terms of the same license as zlib.
|
||||
See the accompanying LICENSE file for the full text of the license.
|
||||
*/
|
||||
|
||||
#ifndef MZ_STREAM_POSIX_H
|
||||
#define MZ_STREAM_POSIX_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t mz_stream_posix_open(void *stream, const char *path, int32_t mode);
|
||||
int32_t mz_stream_posix_is_open(void *stream);
|
||||
int32_t mz_stream_posix_read(void *stream, void *buf, int32_t size);
|
||||
int32_t mz_stream_posix_write(void *stream, const void *buf, int32_t size);
|
||||
int64_t mz_stream_posix_tell(void *stream);
|
||||
int32_t mz_stream_posix_seek(void *stream, int64_t offset, int32_t origin);
|
||||
int32_t mz_stream_posix_close(void *stream);
|
||||
int32_t mz_stream_posix_error(void *stream);
|
||||
|
||||
void* mz_stream_posix_create(void **stream);
|
||||
void mz_stream_posix_delete(void **stream);
|
||||
|
||||
void* mz_stream_posix_get_interface(void);
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#if !defined(_WIN32) && !defined(MZ_USE_WIN32_API)
|
||||
#define mz_stream_os_open mz_stream_posix_open
|
||||
#define mz_stream_os_is_open mz_stream_posix_is_open
|
||||
#define mz_stream_os_read mz_stream_posix_read
|
||||
#define mz_stream_os_write mz_stream_posix_write
|
||||
#define mz_stream_os_tell mz_stream_posix_tell
|
||||
#define mz_stream_os_seek mz_stream_posix_seek
|
||||
#define mz_stream_os_close mz_stream_posix_close
|
||||
#define mz_stream_os_error mz_stream_posix_error
|
||||
|
||||
#define mz_stream_os_create mz_stream_posix_create
|
||||
#define mz_stream_os_delete mz_stream_posix_delete
|
||||
|
||||
#define mz_stream_os_get_interface \
|
||||
mz_stream_posix_get_interface
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user