├── .gitignore
├── Application.manifest
├── LICENSE
├── README.md
├── build.bat
├── build.sh
├── consts.h
├── icon.ico
├── main.c
├── resource.h
├── resource.rc
├── utils.c
├── utils.h
└── xz
├── xz.h
├── xz_config.h
├── xz_crc32.c
├── xz_dec_lzma2.c
├── xz_dec_stream.c
├── xz_lzma2.h
├── xz_private.h
└── xz_stream.h
/.gitignore:
--------------------------------------------------------------------------------
1 | build/
--------------------------------------------------------------------------------
/Application.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Your application description here.
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 | {one line to give the program's name and a brief idea of what it does.}
635 | Copyright (C) {year} {name of author}
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | {project} Copyright (C) {year} {fullname}
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #Self-updater for uTox
2 | downloads signed updates from dl.utox.org
3 |
4 | #How it works
5 |
6 | 1. Builds are made locally and signed with libsodium's crypto_sign_ed25519() and my secret signing key then uploaded to dl.utox.org
7 |
8 | 2. Updater reads the latest version (dl.utox.org/version), if it already has this version it skips to last step
9 |
10 | 3. Downloads dl.utox.org/OSARCH-latest over http (ex: win64-latest for windows 64 bit)
11 |
12 | 4. Uses libsodium's crypto_sign_ed25519_open() using my public signing key (88905F2946BE7C4BBDECE467149C1D7848F4BC4FEC1AD1AD6F97786EFEF3CDA1) to verify the build
13 |
14 | 5. Checks the 4 byte timestamp to verify that the build is not expired (1 week)
15 |
16 | 6. Decompresses the build, writes it to a file
17 |
18 | 7. Run the file
19 |
20 | #Adding and modifiying resources
21 | * The resource.rc file contains the main dialog definition, default icon, and mainfest that enables visual styles.
22 | * Use [ResEdit](www.resedit.net) to open and modify it.
23 |
24 | #Building
25 | * requires mingw-w64
26 | * requires libsodium 1.0.0 ([github](https://github.com/jedisct1/libsodium), [binary releases](https://download.libsodium.org/libsodium/releases/))
27 | * on windows use build.bat
28 | * on linux use build.sh
29 |
30 | #Todo
31 |
32 | * Remove libsodium dependency
--------------------------------------------------------------------------------
/build.bat:
--------------------------------------------------------------------------------
1 | mkdir build
2 |
3 | windres resource.rc -O coff -o build/resource.res
4 |
5 | gcc -o build/utox-update.exe build/resource.res main.c utils.c xz/*.c -lcomctl32 -luuid -lole32 -lgdi32 -lws2_32 -lshlwapi -lsodium -mwindows -s -Ofast -static
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | mkdir build
2 |
3 | windres resource.rc -O coff -o build/resource.res
4 |
5 | gcc -o build/utox-update.exe build/resource.res main.c utils.c xz/*.c -lcomctl32 -luuid -lole32 -lgdi32 -lws2_32 -lshlwapi -lsodium -mwindows -s -Ofast -static
--------------------------------------------------------------------------------
/consts.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef TOX_CONSTS
3 | #define TOX_CONSTS
4 |
5 | #include
6 | #include
7 |
8 | #define APPENDED_VERSION_LENGTH (6 + 2)
9 |
10 | #define VERSION 3
11 |
12 | #define NUMBER_UPDATE_HOSTS 2
13 |
14 | static const char *TOX_DOWNNLOAD_HOSTS[NUMBER_UPDATE_HOSTS] = {
15 | "dl.utox.org",
16 | "irungentoo.github.io"
17 | };
18 |
19 | #define SELF_UPDATER_FILE_NAME "winselfpdate"
20 | #define VERSION_FILE_NAME "version1"
21 | static char GET_NAME[] = "win32-latest";
22 |
23 | static const uint8_t TOX_SELF_PUBLICK_KEY[crypto_sign_ed25519_PUBLICKEYBYTES] = {
24 | 0x88, 0x90, 0x5F, 0x29, 0x46, 0xBE, 0x7C, 0x4B, 0xBD, 0xEC, 0xE4, 0x67, 0x14, 0x9C, 0x1D, 0x78,
25 | 0x48, 0xF4, 0xBC, 0x4F, 0xEC, 0x1A, 0xD1, 0xAD, 0x6F, 0x97, 0x78, 0x6E, 0xFE, 0xF3, 0xCD, 0xA1
26 | };
27 |
28 | static const uint8_t TOX_SELF_PUBLICK_UPDATE_KEY[crypto_sign_ed25519_PUBLICKEYBYTES] = {
29 | 0x52, 0xA7, 0x9B, 0xCA, 0x48, 0x35, 0xD6, 0x34, 0x5E, 0x7D, 0xEF, 0x8B, 0x97, 0xC3, 0x54, 0x2D,
30 | 0x37, 0x9A, 0x9A, 0x8B, 0x00, 0xEB, 0xF3, 0xA8, 0xAD, 0x03, 0x92, 0x3E, 0x0E, 0x50, 0x77, 0x58
31 | };
32 |
33 | #endif
--------------------------------------------------------------------------------
/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notsecure/utox-update/d6b15551c547c8023eb391e0964d3fa530c1a42f/icon.ico
--------------------------------------------------------------------------------
/main.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #ifndef _WIN32_IE
5 | #define _WIN32_IE 0x0800
6 | #endif
7 |
8 | #ifdef _WIN32_WINNT
9 | #undef _WIN32_WINNT
10 | #endif
11 | #define _WIN32_WINNT 0x0600
12 |
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 |
21 | #include "utils.h"
22 | #include "consts.h"
23 | #include "resource.h"
24 |
25 | #define TOX_VERSION_NAME_MAX_LEN 32
26 |
27 | #define UTOX_TITLE "uTox"
28 | #define TOX_EXE_NAME "uTox.exe"
29 | #define TOX_VERSION_FILENAME "version"
30 | #define TOX_UPDATER_FILENAME "utox_runner.exe"
31 |
32 | #define TOX_UNINSTALL_FILENAME "uninstall.bat"
33 | #define TOX_UNINSTALL_CONTENTS "cd %~dp0\n" TOX_UPDATER_FILENAME " --uninstall\nIF NOT EXIST uTox.exe del utox_runner.exe\nIF NOT EXIST uTox.exe del uninstall.bat & exit\nexit\n"
34 |
35 | static char TOX_VERSION_NAME[TOX_VERSION_NAME_MAX_LEN];
36 |
37 | static char TOX_UPDATER_PATH[MAX_PATH];
38 | static uint32_t TOX_UPDATER_PATH_LEN;
39 |
40 | static _Bool is_tox_installed;
41 | static _Bool is_tox_set_start_on_boot;
42 |
43 | // Called arguments
44 |
45 | PSTR MY_CMD_ARGS;
46 | HINSTANCE MY_HINSTANCE;
47 |
48 | // Common UI
49 |
50 | static HWND main_window;
51 | static HWND progressbar;
52 | static HWND status_label;
53 |
54 | HANDLE utox_mutex_handle;
55 |
56 | void set_download_progress(int progress) {
57 | if (progressbar) {
58 | PostMessage(progressbar, PBM_SETPOS, progress, 0);
59 | }
60 | }
61 |
62 | void set_current_status(char *status) {
63 | SetWindowText(status_label, status);
64 | }
65 |
66 | static void init_tox_version_name() {
67 | FILE *version_file = fopen(TOX_VERSION_FILENAME, "rb");
68 |
69 | if (version_file) {
70 | int len = fread(TOX_VERSION_NAME, 1, sizeof(TOX_VERSION_NAME) - 1, version_file);
71 | TOX_VERSION_NAME[len] = 0;
72 | fclose(version_file);
73 |
74 | is_tox_installed = 1;
75 | }
76 | }
77 |
78 | #define UTOX_UPDATER_PARAM " --no-updater"
79 | #define UTOX_SET_START_ON_BOOT_PARAM " --set=start-on-boot"
80 |
81 | static void open_utox_and_exit() {
82 | char str[strlen(MY_CMD_ARGS) + sizeof(UTOX_UPDATER_PARAM) + sizeof(UTOX_SET_START_ON_BOOT_PARAM)];
83 | strcpy(str, MY_CMD_ARGS);
84 | strcat(str, UTOX_UPDATER_PARAM);
85 |
86 | if (is_tox_set_start_on_boot) {
87 | strcat(str, UTOX_SET_START_ON_BOOT_PARAM);
88 | }
89 |
90 | CloseHandle(utox_mutex_handle);
91 | ShellExecute(NULL, "open", TOX_EXE_NAME, str, NULL, SW_SHOW);
92 |
93 | fclose(LOG_FILE);
94 | exit(0);
95 | }
96 |
97 | static void restart_updater() {
98 | CloseHandle(utox_mutex_handle);
99 | ShellExecute(NULL, "open", TOX_UPDATER_PATH, MY_CMD_ARGS, NULL, SW_SHOW);
100 |
101 | fclose(LOG_FILE);
102 | exit(0);
103 | }
104 |
105 | static char* download_new_updater(uint32_t *new_updater_len) {
106 | char *new_updater = download_loop_all_host_ips(1, TOX_DOWNNLOAD_HOSTS, NUMBER_UPDATE_HOSTS, SELF_UPDATER_FILE_NAME, strlen(SELF_UPDATER_FILE_NAME), new_updater_len, 1024 * 1024 * 4, TOX_SELF_PUBLICK_UPDATE_KEY, 0, 0);
107 |
108 | return new_updater;
109 | }
110 |
111 | static _Bool install_new_updater(void *new_updater_data, uint32_t new_updater_data_len)
112 | {
113 | #ifdef __WIN32__
114 | char new_path[MAX_PATH] = {0};
115 | FILE *file;
116 |
117 | memcpy(new_path, TOX_UPDATER_PATH, TOX_UPDATER_PATH_LEN);
118 | strcat(new_path, ".old");
119 |
120 | DeleteFile(new_path);
121 | MoveFile(TOX_UPDATER_PATH, new_path);
122 |
123 | file = fopen(TOX_UPDATER_PATH, "wb");
124 | if(!file) {
125 | LOG_TO_FILE("failed to write new updater");
126 | return 0;
127 | }
128 |
129 | fwrite(new_updater_data, 1, new_updater_data_len, file);
130 |
131 | fclose(file);
132 | return 1;
133 | #else
134 | /* self update not implemented */
135 | return 0;
136 | #endif
137 | }
138 |
139 | /* return 0 on success.
140 | * return -1 if could not write file.
141 | * return -2 if download failed.
142 | */
143 | static int download_and_install_new_utox_version()
144 | {
145 | FILE *file;
146 | void *new_version_data;
147 | uint32_t len, rlen;
148 | new_version_data = download_loop_all_host_ips(1, TOX_DOWNNLOAD_HOSTS, NUMBER_UPDATE_HOSTS, GET_NAME, strlen(GET_NAME), &len, 1024 * 1024 * 4, TOX_SELF_PUBLICK_KEY, TOX_VERSION_NAME, APPENDED_VERSION_LENGTH);
149 |
150 | if (!new_version_data) {
151 | LOG_TO_FILE("download failed\n");
152 | if (is_tox_installed) {
153 | open_utox_and_exit();
154 | }
155 |
156 | return -2;
157 | }
158 |
159 | LOG_TO_FILE("Inflated size: %u\n", len);
160 |
161 | /* delete old version if found */
162 | file = fopen(TOX_VERSION_FILENAME, "rb");
163 | if (file) {
164 | char old_name[32];
165 | rlen = fread(old_name, 1, sizeof(old_name) - 1, file);
166 | old_name[rlen] = 0;
167 |
168 | /* Only there for smooth update from old updater. */
169 | DeleteFile(old_name);
170 | fclose(file);
171 | }
172 |
173 | /* write file */
174 | file = fopen(TOX_EXE_NAME, "wb");
175 | if (!file) {
176 | LOG_TO_FILE("fopen failed\n");
177 | free(new_version_data);
178 | return -1;
179 | }
180 |
181 | rlen = fwrite(new_version_data, 1, len, file);
182 | fclose(file);
183 | free(new_version_data);
184 | if (rlen != len) {
185 | LOG_TO_FILE("write failed (%u)\n", rlen);
186 | return -1;
187 | }
188 |
189 | /* write version to file */
190 | file = fopen(TOX_VERSION_FILENAME, "wb");
191 | if (file) {
192 | rlen = fwrite(TOX_VERSION_NAME, 1, APPENDED_VERSION_LENGTH, file);
193 | fclose(file);
194 | if (rlen != APPENDED_VERSION_LENGTH) {
195 | return -1;
196 | }
197 |
198 | return 0;
199 | }
200 |
201 | return -1;
202 | }
203 |
204 | static int check_new_version()
205 | {
206 | FILE *file;
207 | char *new_version_data;
208 | uint32_t len;
209 |
210 | new_version_data = download_loop_all_host_ips(0, TOX_DOWNNLOAD_HOSTS, NUMBER_UPDATE_HOSTS, VERSION_FILE_NAME, strlen(VERSION_FILE_NAME), &len, 7 + 4, TOX_SELF_PUBLICK_KEY, 0, 0);
211 |
212 | if (!new_version_data) {
213 | LOG_TO_FILE("version download failed\n");
214 | return -1;
215 | }
216 |
217 | if (len != 7 + 4) {
218 | LOG_TO_FILE("invalid version length (%u)\n", len);
219 | free(new_version_data);
220 | return -1;
221 | }
222 |
223 | char str[7];
224 | memcpy(str, new_version_data + 4, 7);
225 |
226 | if (str[6] > VERSION + '0') {
227 | LOG_TO_FILE("new updater version available (%u)\n", str[6]);
228 |
229 | char *new_updater_data;
230 | uint32_t new_updater_data_len;
231 |
232 | new_updater_data = download_new_updater(&new_updater_data_len);
233 |
234 | if (!new_updater_data) {
235 | LOG_TO_FILE("self update download failed\n");
236 | } else {
237 | if (install_new_updater(new_updater_data, new_updater_data_len)) {
238 | LOG_TO_FILE("successful self update\n");
239 |
240 | free(new_version_data);
241 |
242 | restart_updater();
243 | }
244 | }
245 | }
246 |
247 | str[6] = 0;
248 |
249 | LOG_TO_FILE("Version: %s\n", str);
250 | free(new_version_data);
251 |
252 | if (memcmp(TOX_VERSION_NAME + 2, str, 6) == 0) {
253 | /* check if we already have the exe */
254 | file = fopen(TOX_EXE_NAME, "rb");
255 | if (!file) {
256 | LOG_TO_FILE("We don't have the file\n");
257 | fclose(file);
258 | return 1;
259 | }
260 |
261 | return 0;
262 | }
263 |
264 | memcpy(TOX_VERSION_NAME + 2, str, 7);
265 | return 1;
266 | }
267 |
268 | static int write_uninstall()
269 | {
270 | FILE *file = fopen(TOX_UNINSTALL_FILENAME, "wb");
271 |
272 | if (!file)
273 | return -1;
274 |
275 | int len = fwrite(TOX_UNINSTALL_CONTENTS, 1, sizeof(TOX_UNINSTALL_CONTENTS) - 1, file);
276 |
277 | fclose(file);
278 | if (len != sizeof(TOX_UNINSTALL_CONTENTS) - 1)
279 | return -1;
280 |
281 | return 0;
282 | }
283 |
284 | /* return 0 on success.
285 | * return -1 if could not write file.
286 | * return -2 if download failed.
287 | */
288 | static int install_tox(int create_desktop_shortcut, int create_startmenu_shortcut, int use_with_tox_url, wchar_t *install_path, int install_path_len) {
289 |
290 | char dir[MAX_PATH];
291 |
292 | wchar_t selfpath[MAX_PATH];
293 | GetModuleFileNameW(MY_HINSTANCE, selfpath, MAX_PATH);
294 |
295 | SHCreateDirectoryExW(NULL, install_path, NULL);
296 | SetCurrentDirectoryW(install_path);
297 | if (CopyFileW(selfpath, L""TOX_UPDATER_FILENAME, 0) == 0)
298 | return -1;
299 |
300 | int ret = write_uninstall();
301 | if (ret != 0)
302 | return ret;
303 |
304 | set_current_status("downloading and installing tox...");
305 |
306 | ret = download_and_install_new_utox_version();
307 | if (ret != 0)
308 | return ret;
309 |
310 | HRESULT hr;
311 | HKEY key;
312 |
313 | if (create_desktop_shortcut || create_startmenu_shortcut) {
314 | hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
315 | if(SUCCEEDED(hr)) {
316 | //start menu
317 | IShellLink* psl;
318 |
319 | // Get a pointer to the IShellLink interface. It is assumed that CoInitialize
320 | // has already been called.
321 | hr = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLink, (LPVOID*)&psl);
322 | if (SUCCEEDED(hr)) {
323 | IPersistFile* ppf;
324 |
325 | // Set the path to the shortcut target and add the description.
326 |
327 | GetCurrentDirectory(MAX_PATH, dir);
328 | psl->lpVtbl->SetWorkingDirectory(psl, dir);
329 | strcat(dir, "\\"TOX_UPDATER_FILENAME);
330 | psl->lpVtbl->SetPath(psl, dir);
331 | psl->lpVtbl->SetDescription(psl, "Tox");
332 |
333 | // Query IShellLink for the IPersistFile interface, used for saving the
334 | // shortcut in persistent storage.
335 | hr = psl->lpVtbl->QueryInterface(psl, &IID_IPersistFile, (LPVOID*)&ppf);
336 |
337 | if (SUCCEEDED(hr)) {
338 | wchar_t wsz[MAX_PATH + 64];
339 | if (create_startmenu_shortcut) {
340 | hr = SHGetFolderPathW(NULL, CSIDL_STARTMENU, NULL, 0, wsz);
341 | if (SUCCEEDED(hr)) {
342 | LOG_TO_FILE("%ls\n", wsz);
343 | wcscat(wsz, L"\\Programs\\Tox.lnk");
344 | hr = ppf->lpVtbl->Save(ppf, wsz, TRUE);
345 | }
346 | }
347 |
348 | if (create_desktop_shortcut) {
349 | hr = SHGetFolderPathW(NULL, CSIDL_DESKTOPDIRECTORY, NULL, 0, wsz);
350 | if (SUCCEEDED(hr)) {
351 | wcscat(wsz, L"\\Tox.lnk");
352 | hr = ppf->lpVtbl->Save(ppf, wsz, TRUE);
353 | }
354 | }
355 |
356 | ppf->lpVtbl->Release(ppf);
357 | }
358 | psl->lpVtbl->Release(psl);
359 | }
360 | }
361 | }
362 |
363 | if (use_with_tox_url) {
364 | GetCurrentDirectory(MAX_PATH, dir);
365 | strcat(dir, "\\" TOX_EXE_NAME);
366 |
367 | char str[MAX_PATH];
368 |
369 | if (RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\tox", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS) {
370 | LOG_TO_FILE("nice\n");
371 | RegSetValueEx(key, NULL, 0, REG_SZ, (BYTE*)"URL:Tox Protocol", sizeof("URL:Tox Protocol"));
372 | RegSetValueEx(key, "URL Protocol", 0, REG_SZ, (BYTE*)"", sizeof(""));
373 |
374 | HKEY key2;
375 | if (RegCreateKeyEx(key, "DefaultIcon", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key2, NULL) == ERROR_SUCCESS) {
376 | int i = sprintf(str, "%s,101", dir) + 1;
377 | RegSetValueEx(key2, NULL, 0, REG_SZ, (BYTE*)str, i);
378 | }
379 |
380 | if (RegCreateKeyEx(key, "shell", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key2, NULL) == ERROR_SUCCESS) {
381 | if (RegCreateKeyEx(key2, "open", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS) {
382 | if (RegCreateKeyEx(key, "command", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key2, NULL) == ERROR_SUCCESS) {
383 | int i = sprintf(str, "%s %%1", dir) + 1;
384 | RegSetValueEx(key2, NULL, 0, REG_SZ, (BYTE*)str, i);
385 | }
386 | }
387 | }
388 | }
389 | }
390 |
391 | if (RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\uTox", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS) {
392 | wchar_t icon[install_path_len + 64];
393 | wchar_t uninstall[install_path_len + 64];
394 | memcpy(icon, install_path, install_path_len * 2);
395 | icon[install_path_len] = 0;
396 | uninstall[0] = 0;
397 | wcscat(uninstall, L"cmd /C start \"\" /MIN \"");
398 |
399 | wcscat(icon, L"\\uTox.exe");
400 | wcscat(uninstall, install_path);
401 | wcscat(uninstall, L"\\uninstall.bat\"");
402 |
403 | RegSetValueEx(key, NULL, 0, REG_SZ, (BYTE*)"", sizeof(""));
404 | RegSetValueEx(key, "DisplayName", 0, REG_SZ, (BYTE*)"uTox", sizeof("uTox"));
405 | RegSetValueExW(key, L"InstallLocation", 0, REG_SZ, (BYTE*)install_path, wcslen(install_path) * 2);
406 | RegSetValueExW(key, L"DisplayIcon", 0, REG_SZ, (BYTE*)icon, wcslen(icon) * 2);
407 | RegSetValueExW(key, L"UninstallString", 0, REG_SZ, (BYTE*)uninstall, wcslen(uninstall) * 2);
408 | }
409 | return 0;
410 | }
411 |
412 | static int uninstall_tox()
413 | {
414 | if (MessageBox(NULL, "Are you sure you want to uninstall uTox?", "uTox Updater", MB_YESNO | MB_ICONQUESTION | MB_SETFOREGROUND) == IDYES) {
415 | wchar_t wsz[MAX_PATH + 64];
416 |
417 | if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_STARTMENU, NULL, 0, wsz))) {
418 | wcscat(wsz, L"\\Programs\\Tox.lnk");
419 | DeleteFileW(wsz);
420 | }
421 |
422 | if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_DESKTOPDIRECTORY, NULL, 0, wsz))) {
423 | wcscat(wsz, L"\\Tox.lnk");
424 | DeleteFileW(wsz);
425 | }
426 |
427 | SHDeleteKey(HKEY_CURRENT_USER, "Software\\Classes\\tox");
428 | SHDeleteKey(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\uTox");
429 | SHDeleteValue(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", "uTox");
430 | DeleteFile(TOX_EXE_NAME);
431 | DeleteFile(TOX_VERSION_FILENAME);
432 | MessageBox(main_window, "uTox uninstalled.", "uTox Updater", MB_OK | MB_SETFOREGROUND);
433 | }
434 |
435 | exit(0);
436 | }
437 |
438 | #define UTOX_INSTALL_ENDED 18273
439 |
440 | static void buttons_enable(_Bool enable)
441 | {
442 | Button_Enable(GetDlgItem(main_window, ID_INSTALL_BUTTON), enable);
443 | Button_Enable(GetDlgItem(main_window, ID_BROWSE_BUTTON), enable);
444 | Button_Enable(GetDlgItem(main_window, ID_DESKTOP_SHORTCUT_CHECKBOX), enable);
445 | Button_Enable(GetDlgItem(main_window, ID_STARTMENU_SHORTCUT_CHECKBOX), enable);
446 | Button_Enable(GetDlgItem(main_window, ID_TOX_URL_CHECKBOX), enable);
447 | }
448 |
449 | static void start_installation() {
450 | HWND desktop_shortcut_checkbox = GetDlgItem(main_window, ID_DESKTOP_SHORTCUT_CHECKBOX);
451 | HWND startmenu_shortcut_checkbox = GetDlgItem(main_window, ID_STARTMENU_SHORTCUT_CHECKBOX);
452 | HWND start_on_boot_checkbox = GetDlgItem(main_window, ID_START_ON_BOOT_CHECKBOX);
453 | HWND tox_url_checkbox = GetDlgItem(main_window, ID_TOX_URL_CHECKBOX);
454 | HWND browse_textbox = GetDlgItem(main_window, ID_BROWSE_TEXTBOX);
455 |
456 | _Bool create_desktop_shortcut, create_startmenu_shortcut, use_with_tox_url;
457 |
458 | wchar_t install_path[MAX_PATH];
459 | int install_path_len = GetWindowTextW(browse_textbox, install_path, MAX_PATH);
460 |
461 | if (install_path_len == 0) {
462 | MessageBox(main_window, "Please select a folder to install uTox in", "Error", MB_OK | MB_SETFOREGROUND);
463 | PostMessage(main_window, WM_APP, UTOX_INSTALL_ENDED, 0);
464 | return;
465 | }
466 |
467 | create_desktop_shortcut = Button_GetCheck(desktop_shortcut_checkbox);
468 | create_startmenu_shortcut = Button_GetCheck(startmenu_shortcut_checkbox);
469 | use_with_tox_url = Button_GetCheck(tox_url_checkbox);
470 | is_tox_set_start_on_boot = Button_GetCheck(start_on_boot_checkbox);
471 |
472 | LOG_TO_FILE("will install with options: %u %u %u %ls\n", create_desktop_shortcut, create_startmenu_shortcut, use_with_tox_url, install_path);
473 |
474 | if (MessageBox(main_window, "Are you sure you want to continue?", "uTox Updater", MB_YESNO | MB_SETFOREGROUND) != IDYES) {
475 | PostMessage(main_window, WM_APP, UTOX_INSTALL_ENDED, 0);
476 | return;
477 | }
478 |
479 | buttons_enable(0);
480 | int ret = install_tox(create_desktop_shortcut, create_startmenu_shortcut, use_with_tox_url, install_path, install_path_len);
481 | if (ret == 0) {
482 | set_current_status("installation complete");
483 |
484 | MessageBox(main_window, "Installation successful.", "uTox Updater", MB_OK | MB_SETFOREGROUND);
485 | open_utox_and_exit();
486 | } else if (ret == -1) {
487 | set_current_status("could not write to install directory.");
488 | } else if (ret == -2) {
489 | set_current_status("download error, please check your internet connection and try again.");
490 | } else {
491 | set_current_status("error during installation");
492 |
493 | MessageBox(main_window, "Installation failed. If it's not an internet issue please send the log file (tox_log.txt) to the developers.", "uTox Updater", MB_OK | MB_SETFOREGROUND);
494 | exit(0);
495 | }
496 |
497 | PostMessage(main_window, WM_APP, UTOX_INSTALL_ENDED, 0);
498 | buttons_enable(1);
499 | }
500 |
501 | static void set_utox_path(wchar_t *path)
502 | {
503 | HWND browse_textbox = GetDlgItem(main_window, ID_BROWSE_TEXTBOX);
504 |
505 | unsigned int str_len = wcslen(path);
506 | if (str_len != 0) {
507 | wchar_t file_path[str_len + sizeof(L"\\uTox")];
508 | memcpy(file_path, path, str_len * sizeof(wchar_t));
509 | memcpy(file_path + str_len, L"\\uTox", sizeof(L"\\uTox"));
510 | SetWindowTextW(browse_textbox, file_path);
511 | }
512 | }
513 |
514 | static void browse_for_install_folder() {
515 | HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
516 |
517 | IFileOpenDialog *pFileOpen;
518 | hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_ALL, &IID_IFileOpenDialog, (void*)&pFileOpen);
519 | if (SUCCEEDED(hr)) {
520 | hr = pFileOpen->lpVtbl->SetOptions(pFileOpen, FOS_PICKFOLDERS);
521 | hr = pFileOpen->lpVtbl->SetTitle(pFileOpen, L"Tox Install Location");
522 | hr = pFileOpen->lpVtbl->Show(pFileOpen, NULL);
523 |
524 | if (SUCCEEDED(hr)) {
525 | IShellItem *pItem;
526 | hr = pFileOpen->lpVtbl->GetResult(pFileOpen, &pItem);
527 |
528 | if (SUCCEEDED(hr)) {
529 | PWSTR pszFilePath;
530 | hr = pItem->lpVtbl->GetDisplayName(pItem, SIGDN_FILESYSPATH, &pszFilePath);
531 |
532 | if (SUCCEEDED(hr)) {
533 | set_utox_path(pszFilePath);
534 | CoTaskMemFree(pszFilePath);
535 | }
536 | pItem->lpVtbl->Release(pItem);
537 | }
538 | }
539 | pFileOpen->lpVtbl->Release(pFileOpen);
540 |
541 | CoUninitialize();
542 | }
543 | else {
544 | wchar_t path[MAX_PATH];
545 | BROWSEINFOW bi = {
546 | .pszDisplayName = path,
547 | .lpszTitle = L"Install Location",
548 | .ulFlags = BIF_USENEWUI | BIF_NONEWFOLDERBUTTON,
549 | };
550 | LPITEMIDLIST lpItem = SHBrowseForFolderW(&bi);
551 | if (!lpItem) {
552 | return;
553 | }
554 |
555 | SHGetPathFromIDListW(lpItem, path);
556 | set_utox_path(path);
557 | }
558 | }
559 |
560 | static void check_updates() {
561 | set_current_status("fetching new version data...");
562 |
563 | int new_version = check_new_version();
564 | set_download_progress(0);
565 |
566 | if (new_version == -1) {
567 | if (!is_tox_installed) {
568 | MessageBox(main_window, "Error fetching latest version data. Please check your internet connection.\n\nExiting now...", "Error", MB_OK | MB_SETFOREGROUND);
569 | exit(0);
570 | } else {
571 | open_utox_and_exit();
572 | }
573 | }
574 |
575 | set_current_status("version data fetched successfully");
576 | Button_Enable(GetDlgItem(main_window, ID_INSTALL_BUTTON), 1);
577 |
578 | if (is_tox_installed) {
579 |
580 | if (new_version) {
581 | ShowWindow(main_window, SW_SHOW);
582 | set_current_status("found new version");
583 |
584 | if (MessageBox(NULL, "A new version of uTox is available.\nUpdate?", "uTox Updater", MB_YESNO | MB_ICONQUESTION | MB_SETFOREGROUND) == IDYES) {
585 | download_and_install_new_utox_version();
586 | }
587 | }
588 |
589 | open_utox_and_exit();
590 | }
591 | }
592 |
593 | INT_PTR CALLBACK MainDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
594 | {
595 | UNREFERENCED_PARAMETER(lParam);
596 |
597 | static _Bool install_thread_running = 0;
598 |
599 | switch (message)
600 | {
601 | case WM_INITDIALOG:
602 | return (INT_PTR)TRUE;
603 | case WM_CLOSE:
604 | PostQuitMessage(0);
605 | break;
606 |
607 | case WM_COMMAND: {
608 | if (HIWORD(wParam) == BN_CLICKED) {
609 | int id = LOWORD(wParam);
610 | //HWND control_hwnd = (HWND)lParam;
611 |
612 | switch (id) {
613 | case ID_CANCEL_BUTTON:
614 | if (MessageBox(main_window, "Are you sure you want to exit?", "uTox Updater", MB_YESNO | MB_SETFOREGROUND) == IDYES) {
615 | if (is_tox_installed) {
616 | open_utox_and_exit();
617 | }
618 | else {
619 | exit(0);
620 | }
621 | }
622 | break;
623 |
624 | case ID_INSTALL_BUTTON:
625 |
626 | if (!install_thread_running) {
627 | if (_beginthread(start_installation, 0, 0) != -1)
628 | install_thread_running = 1;
629 | }
630 |
631 | break;
632 |
633 | case ID_BROWSE_BUTTON:
634 | buttons_enable(0);
635 | browse_for_install_folder();
636 | buttons_enable(1);
637 |
638 | break;
639 | }
640 | }
641 | break;
642 | }
643 |
644 | case WM_APP: {
645 | if (wParam == UTOX_INSTALL_ENDED)
646 | install_thread_running = 0;
647 | }
648 | }
649 |
650 | return (INT_PTR)FALSE;
651 | }
652 |
653 | int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR cmd, int nCmdShow)
654 | {
655 | utox_mutex_handle = CreateMutex(NULL, 0, UTOX_TITLE);
656 |
657 | if (!utox_mutex_handle) {
658 | return 0;
659 | }
660 |
661 | if (GetLastError() == ERROR_ALREADY_EXISTS) {
662 | HWND window = FindWindow(UTOX_TITLE, NULL);
663 |
664 | /* uTox is running. */
665 | if (window) {
666 | SetForegroundWindow(window);
667 | }
668 |
669 | return 0;
670 | }
671 |
672 | MY_CMD_ARGS = cmd;
673 | MY_HINSTANCE = hInstance;
674 |
675 | TOX_UPDATER_PATH_LEN = GetModuleFileName(NULL, TOX_UPDATER_PATH, MAX_PATH);
676 | TOX_UPDATER_PATH[TOX_UPDATER_PATH_LEN] = 0;
677 |
678 | {
679 | char path[MAX_PATH], *s;
680 | memcpy(path, TOX_UPDATER_PATH, TOX_UPDATER_PATH_LEN + 1);
681 | s = path + TOX_UPDATER_PATH_LEN;
682 | while(*s != '\\') {
683 | s--;
684 | }
685 |
686 | *s = 0;
687 | SetCurrentDirectory(path);
688 | }
689 |
690 | LPWSTR *arglist;
691 | int argc, i;
692 |
693 | init_tox_version_name();
694 |
695 | /* Convert PSTR command line args from windows to argc */
696 | arglist = CommandLineToArgvW(GetCommandLineW(), &argc);
697 | if( NULL != arglist ){
698 | for (i = 0; i < argc; i++) {
699 | if(wcscmp(arglist[i], L"--uninstall") == 0) {
700 | if (is_tox_installed) {
701 | uninstall_tox();
702 | return 0;
703 | }
704 | }
705 | }
706 | }
707 |
708 | LOG_FILE = fopen("tox_log.txt", "w");
709 |
710 | /* initialize winsock */
711 | WSADATA wsaData;
712 | if(WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
713 | LOG_TO_FILE("WSAStartup failed\n");
714 | return 1;
715 | }
716 |
717 | if (IsWindowsVistaOrGreater()) {
718 | /* check if we are on a 64-bit system */
719 | _Bool iswow64 = 0;
720 | _Bool (WINAPI *fnIsWow64Process)(HANDLE, _Bool*) = (void*)GetProcAddress(GetModuleHandleA("kernel32"),"IsWow64Process");
721 | if(fnIsWow64Process) {
722 | fnIsWow64Process(GetCurrentProcess(), &iswow64);
723 | }
724 |
725 | if(iswow64) {
726 | /* replace the arch in the GET_NAME/TOX_VERSION_NAME strings (todo: not use constants for offsets) */
727 | GET_NAME[3] = '6';
728 | GET_NAME[4] = '4';
729 | TOX_VERSION_NAME[0] = '6';
730 | TOX_VERSION_NAME[1] = '4';
731 | LOG_TO_FILE("detected 64bit system\n");
732 | } else {
733 | GET_NAME[3] = '3';
734 | GET_NAME[4] = '2';
735 | TOX_VERSION_NAME[0] = '3';
736 | TOX_VERSION_NAME[1] = '2';
737 | LOG_TO_FILE("detected 32bit system\n");
738 | }
739 | } else {
740 | GET_NAME[3] = 'x';
741 | GET_NAME[4] = 'p';
742 | TOX_VERSION_NAME[0] = 'x';
743 | TOX_VERSION_NAME[1] = 'p';
744 | LOG_TO_FILE("detected XP system\n");
745 | }
746 |
747 | /* init common controls */
748 | INITCOMMONCONTROLSEX InitCtrlEx;
749 |
750 | InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
751 | InitCtrlEx.dwICC = ICC_PROGRESS_CLASS;
752 | InitCommonControlsEx(&InitCtrlEx);
753 |
754 | main_window = CreateDialog(MY_HINSTANCE, MAKEINTRESOURCE(IDD_MAIN_DIALOG), NULL, MainDialogProc);
755 |
756 | if (!main_window) {
757 | LOG_TO_FILE("error creating main window %lu\n", GetLastError());
758 | exit(0);
759 | }
760 |
761 | progressbar = GetDlgItem(main_window, ID_PROGRESSBAR);
762 | set_download_progress(0);
763 | status_label = GetDlgItem(main_window, IDC_STATUS_LABEL);
764 |
765 | if (!is_tox_installed) {
766 | // show installer controls
767 | HWND desktop_shortcut_checkbox = GetDlgItem(main_window, ID_DESKTOP_SHORTCUT_CHECKBOX);
768 | Button_SetCheck(desktop_shortcut_checkbox, 1);
769 | ShowWindow(desktop_shortcut_checkbox, SW_SHOW);
770 |
771 | HWND startmenu_shortcut_checkbox = GetDlgItem(main_window, ID_STARTMENU_SHORTCUT_CHECKBOX);
772 | Button_SetCheck(startmenu_shortcut_checkbox, 1);
773 | ShowWindow(startmenu_shortcut_checkbox, SW_SHOW);
774 |
775 | HWND start_on_boot_checkbox = GetDlgItem(main_window, ID_START_ON_BOOT_CHECKBOX);
776 | Button_SetCheck(start_on_boot_checkbox, 1);
777 | ShowWindow(start_on_boot_checkbox, SW_SHOW);
778 |
779 | ShowWindow(GetDlgItem(main_window, ID_TOX_URL_CHECKBOX), SW_SHOW);
780 |
781 | wchar_t appdatalocal_path[MAX_PATH] = {0};
782 | if (SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, 0, appdatalocal_path) == S_OK) {
783 | set_utox_path(appdatalocal_path);
784 | }
785 |
786 | Button_Enable(GetDlgItem(main_window, ID_INSTALL_BUTTON), 0);
787 | ShowWindow(GetDlgItem(main_window, ID_INSTALL_BUTTON), SW_SHOW);
788 |
789 | Edit_SetReadOnly(GetDlgItem(main_window, ID_BROWSE_TEXTBOX), 1);
790 | ShowWindow(GetDlgItem(main_window, ID_BROWSE_TEXTBOX), SW_SHOW);
791 | ShowWindow(GetDlgItem(main_window, ID_BROWSE_BUTTON), SW_SHOW);
792 | ShowWindow(GetDlgItem(main_window, IDC_INSTALL_FOLDER_LABEL), SW_SHOW);
793 | ShowWindow(main_window, SW_SHOW);
794 | }
795 |
796 | _beginthread(check_updates, 0, NULL);
797 |
798 | MSG msg;
799 |
800 | while (GetMessage(&msg, NULL, 0, 0) > 0) {
801 | DispatchMessage(&msg);
802 | }
803 |
804 | open_utox_and_exit();
805 |
806 | return 0;
807 | }
808 |
--------------------------------------------------------------------------------
/resource.h:
--------------------------------------------------------------------------------
1 | #ifndef IDC_STATIC
2 | #define IDC_STATIC (-1)
3 | #endif
4 |
5 | #define IDD_MAIN_DIALOG 101
6 | #define ID_STARTMENU_SHORTCUT_CHECKBOX 1001
7 | #define ID_DESKTOP_SHORTCUT_CHECKBOX 1002
8 | #define ID_TOX_URL_CHECKBOX 1003
9 | #define ID_PROGRESSBAR 1004
10 | #define ID_BROWSE_TEXTBOX 1005
11 | #define ID_BROWSE_BUTTON 1006
12 | #define ID_INSTALL_BUTTON 1008
13 | #define ID_CANCEL_BUTTON 1009
14 | #define IDC_STATUS_LABEL 1010
15 | #define IDC_INSTALL_FOLDER_LABEL 1012
16 | #define ID_START_ON_BOOT_CHECKBOX 1013
17 |
--------------------------------------------------------------------------------
/resource.rc:
--------------------------------------------------------------------------------
1 | // Generated by ResEdit 1.6.3
2 | // Copyright (C) 2006-2014
3 | // http://www.resedit.net
4 |
5 | #include
6 | #include
7 | #include
8 | #include "resource.h"
9 |
10 |
11 |
12 |
13 | //
14 | // Dialog resources
15 | //
16 | LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
17 | IDD_MAIN_DIALOG DIALOGEX 0, 0, 309, 154
18 | STYLE DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_MINIMIZEBOX | WS_POPUP | WS_SYSMENU
19 | CAPTION "uTox"
20 | FONT 8, "MS Shell Dlg", 400, 0, 1
21 | {
22 | DEFPUSHBUTTON "Install", ID_INSTALL_BUTTON, 183, 125, 50, 14, NOT WS_VISIBLE, WS_EX_LEFT
23 | PUSHBUTTON "Cancel", ID_CANCEL_BUTTON, 239, 125, 50, 14, 0, WS_EX_LEFT
24 | AUTOCHECKBOX "Create Start Menu shortcut", ID_STARTMENU_SHORTCUT_CHECKBOX, 22, 16, 128, 10, NOT WS_VISIBLE, WS_EX_LEFT
25 | AUTOCHECKBOX "Create Desktop shortcut", ID_DESKTOP_SHORTCUT_CHECKBOX, 22, 32, 128, 10, NOT WS_VISIBLE, WS_EX_LEFT
26 | AUTOCHECKBOX "Start uTox on boot", ID_START_ON_BOOT_CHECKBOX, 22, 48, 128, 10, NOT WS_VISIBLE, WS_EX_LEFT
27 | AUTOCHECKBOX "Open tox:// URLs with uTox", ID_TOX_URL_CHECKBOX, 155, 16, 128, 10, NOT WS_VISIBLE, WS_EX_LEFT
28 | CONTROL "", ID_PROGRESSBAR, PROGRESS_CLASS, WS_BORDER, 22, 91, 265, 14, WS_EX_LEFT
29 | CTEXT "", IDC_STATUS_LABEL, 22, 107, 261, 8, NOT WS_GROUP | SS_CENTER, WS_EX_LEFT
30 | EDITTEXT ID_BROWSE_TEXTBOX, 67, 66, 166, 14, NOT WS_VISIBLE | ES_AUTOHSCROLL, WS_EX_LEFT
31 | PUSHBUTTON "Browse", ID_BROWSE_BUTTON, 237, 66, 50, 14, NOT WS_VISIBLE, WS_EX_LEFT
32 | LTEXT "Install Folder", IDC_INSTALL_FOLDER_LABEL, 22, 68, 42, 8, NOT WS_VISIBLE | SS_LEFT, WS_EX_LEFT
33 | }
34 |
35 |
36 |
37 | //
38 | // Icon resources
39 | //
40 | LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
41 | 101 ICON "icon.ico"
42 |
43 |
44 |
45 | //
46 | // Manifest resources
47 | //
48 | LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
49 | 1 RT_MANIFEST "Application.manifest"
50 |
--------------------------------------------------------------------------------
/utils.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include
5 | #define close(x) closesocket(x)
6 |
7 | #define SODIUM_STATIC
8 | #include
9 |
10 | #include "xz/xz.h"
11 |
12 | #include "utils.h"
13 |
14 | static uint32_t inflate(void *dest, void *src, uint32_t dest_size, uint32_t src_len)
15 | {
16 | xz_crc32_init();
17 |
18 | struct xz_dec *dec = xz_dec_init(XZ_SINGLE, 0);
19 | if(!dec) {
20 | return 0;
21 | }
22 |
23 | struct xz_buf buf = {
24 | .in = src,
25 | .in_pos = 0,
26 | .in_size = src_len,
27 |
28 | .out = dest,
29 | .out_pos = 0,
30 | .out_size = dest_size,
31 | };
32 |
33 | int r = xz_dec_run(dec, &buf);
34 | xz_dec_end(dec);
35 |
36 | LOG_TO_FILE("%i\n", r);
37 |
38 | /* out_pos is only set on success*/
39 | return buf.out_pos;
40 | }
41 |
42 | static void* checksignature(void *data, uint32_t dlen, const uint8_t *self_public_key, unsigned long long *downloaded_len)
43 | {
44 | void *mdata;
45 | int r;
46 |
47 | mdata = malloc(dlen);
48 | if(!mdata) {
49 | LOG_TO_FILE("malloc failed\n");
50 | free(data);
51 | return NULL;
52 | }
53 |
54 | r = crypto_sign_ed25519_open(mdata, downloaded_len, data, dlen, self_public_key);
55 | free(data);
56 |
57 | if(r == -1) {
58 | LOG_TO_FILE("invalid signature\n");
59 | free(mdata);
60 | return NULL;
61 | }
62 |
63 | return mdata;
64 | }
65 |
66 |
67 | static void* download(struct sockaddr_storage *sock_addr, size_t addr_len, char *request, uint16_t request_len, uint32_t *downloaded_length, uint32_t downloaded_len_max)
68 | {
69 | uint32_t sock, len, rlen, dlen;
70 | char *data = 0;
71 | _Bool header = 0;
72 |
73 | sock = socket(sock_addr->ss_family, SOCK_STREAM, IPPROTO_TCP);
74 | if(sock == ~0) {
75 | LOG_TO_FILE("socket failed\n");
76 | return NULL;
77 | }
78 |
79 | if (connect(sock, (struct sockaddr *)sock_addr, addr_len) != 0) {
80 | LOG_TO_FILE("connect failed\n");
81 | close(sock);
82 | return NULL;
83 | }
84 |
85 | if(send(sock, request, request_len, 0) != request_len) {
86 | LOG_TO_FILE("send failed\n");
87 | close(sock);
88 | return NULL;
89 | }
90 |
91 | uint8_t recvbuf[0x10000];
92 |
93 | while((len = recv(sock, (char*)recvbuf, 0xFFFF, 0)) > 0) {
94 | if(!header) {
95 | /* work with a null-terminated buffer */
96 | recvbuf[len] = 0;
97 |
98 | /* check for "Not Found" response (todo: only check first line of response)*/
99 | if(strstr((char*)recvbuf, "404 Not Found\r\n")) {
100 | LOG_TO_FILE("Not Found\n");
101 | break;
102 | }
103 |
104 | /* find the length field */
105 | char *str = strstr((char*)recvbuf, "Content-Length: ");
106 | if(!str) {
107 | LOG_TO_FILE("invalid HTTP response (1)\n");
108 | break;
109 | }
110 |
111 | /* parse the length field */
112 | str += sizeof("Content-Length: ") - 1;
113 | dlen = strtol(str, NULL, 10);
114 | if(dlen > downloaded_len_max) {
115 | LOG_TO_FILE("too large\n");
116 | break;
117 | }
118 |
119 | /* find the end of the http response header */
120 | str = strstr(str, "\r\n\r\n");
121 | if(!str) {
122 | LOG_TO_FILE("invalid HTTP response (2)\n");
123 | break;
124 | }
125 |
126 | str += sizeof("\r\n\r\n") - 1;
127 |
128 | /* allocate buffer to read into) */
129 | data = malloc(dlen);
130 | if(!data) {
131 | LOG_TO_FILE("malloc failed (1) (%u)\n", dlen);
132 | break;
133 | }
134 |
135 | LOG_TO_FILE("Download size: %u\n", dlen);
136 |
137 | /* read the first piece */
138 | rlen = len - (str - (char*)recvbuf);
139 | memcpy(data, str, rlen);
140 |
141 | header = 1;
142 | continue;
143 | }
144 |
145 | /* check if received too much */
146 | if(rlen + len > dlen) {
147 | LOG_TO_FILE("bad download\n");
148 | break;
149 | }
150 |
151 | memcpy(data + rlen, recvbuf, len);
152 | rlen += len;
153 | set_download_progress((rlen * 100) / dlen);
154 | }
155 |
156 | close(sock);
157 |
158 | if(!header) {
159 | /* read nothing or invalid header */
160 | LOG_TO_FILE("download() failed\n");
161 | return NULL;
162 | } else if(rlen != dlen) {
163 | LOG_TO_FILE("number of bytes read does not match (%u)\n", rlen);
164 | free(data);
165 | return NULL;
166 | }
167 |
168 | *downloaded_length = dlen;
169 | return data;
170 | }
171 |
172 | static int generate_request(char *out, size_t out_len, const char *host, size_t host_len, const char *filename, size_t filename_len)
173 | {
174 | char host_terminated[host_len + 1];
175 | memcpy(host_terminated, host, host_len);
176 | host_terminated[host_len] = 0;
177 |
178 | char filename_terminated[filename_len + 1];
179 | memcpy(filename_terminated, filename, filename_len);
180 | filename_terminated[filename_len] = 0;
181 |
182 | int len = snprintf(out, out_len, "GET /%s HTTP/1.0\r\n""Host: %s\r\n\r\n", filename_terminated, host_terminated);
183 |
184 | if (len > out_len + 1 || len <= 0)
185 | return -1;
186 |
187 | return len;
188 | }
189 |
190 | void* download_signed(void *sock_addr, size_t addr_len, const char *host, size_t host_len, const char *filename, size_t filename_len, uint32_t *downloaded_len, uint32_t downloaded_len_max, const uint8_t *self_public_key)
191 | {
192 | void *data, *mdata;
193 | uint32_t len, t;
194 | time_t now;
195 | unsigned long long mlen;
196 |
197 | char request[512];
198 | int request_len = generate_request(request, sizeof(request), host, host_len, filename, filename_len);
199 |
200 | if (request_len == -1)
201 | return NULL;
202 |
203 | data = download(sock_addr, addr_len, request, request_len, &len, downloaded_len_max + crypto_sign_ed25519_BYTES);
204 | if(!data) {
205 | return NULL;
206 | }
207 |
208 | mdata = checksignature(data, len, self_public_key, &mlen);
209 | if(!mdata) {
210 | return NULL;
211 | }
212 |
213 | time(&now);
214 | memcpy(&t, mdata, 4);
215 |
216 | LOG_TO_FILE("signed %u, now %u\n", (uint32_t)t, (uint32_t)now);
217 |
218 | if(t < now && now - t >= 60 * 60 * 24 * UPDATE_EXPIRE_DAYS) {
219 | /* build is more than 1 week old: expired */
220 | LOG_TO_FILE("expired signature (%u)\n", (uint32_t)(now - t));
221 | free(mdata);
222 | return NULL;
223 | }
224 |
225 | *downloaded_len = mlen;
226 | return mdata;
227 | }
228 |
229 | void* download_signed_compressed(void *sock_addr, size_t addr_len, const char *host, size_t host_len, const char *filename, size_t filename_len, uint32_t *downloaded_len, uint32_t downloaded_len_max, const uint8_t *self_public_key)
230 | {
231 | char *data, *mdata;
232 | uint32_t len, mlen;
233 |
234 | mdata = download_signed(sock_addr, addr_len, host, host_len, filename, filename_len, &mlen, downloaded_len_max, self_public_key);
235 | if(!mdata) {
236 | LOG_TO_FILE("file download failed\n");
237 | return NULL;
238 | }
239 |
240 | /* inflate */
241 | data = malloc(downloaded_len_max);
242 | if(!data) {
243 | LOG_TO_FILE("malloc failed (2) (%u)\n", downloaded_len_max);
244 | free(mdata);
245 | return NULL;
246 | }
247 |
248 | len = inflate(data, mdata + 4, downloaded_len_max, mlen - 4);
249 | free(mdata);
250 | if(len == 0) {
251 | LOG_TO_FILE("inflate failed\n");
252 | free(data);
253 | return NULL;
254 | }
255 |
256 | *downloaded_len = len;
257 | return data;
258 | }
259 |
260 | #define TRY_TIMES 2
261 |
262 | void *download_loop_all_host_ips(_Bool compressed, const char *hosts[], size_t number_hosts, const char *filename, size_t filename_len, uint32_t *downloaded_len, uint32_t downloaded_len_max, const uint8_t *self_public_key, const char *cmp_end_file, size_t cmp_end_file_len)
263 | {
264 | time_t now;
265 | time(&now);
266 |
267 | unsigned int i;
268 |
269 | for (i = 0; i < (number_hosts * TRY_TIMES); ++i) {
270 | unsigned int index = (i + now) % number_hosts;
271 | struct addrinfo *root, *info;
272 |
273 | if(getaddrinfo(hosts[index], "80", NULL, &root) != 0) {
274 | LOG_TO_FILE("getaddrinfo failed\n");
275 | continue;
276 | }
277 |
278 | info = root;
279 |
280 | do {
281 | LOG_TO_FILE("addrinfo %i %i %i %i %i\n", info->ai_flags, info->ai_family, info->ai_socktype, info->ai_protocol, info->ai_addrlen);
282 | if (info->ai_socktype && info->ai_socktype != SOCK_STREAM)
283 | continue;
284 |
285 | LOG_TO_FILE("Trying this one\n");
286 | void *data = 0;
287 | uint32_t dled_len = 0;
288 | if (compressed) {
289 | data = download_signed_compressed(info->ai_addr, info->ai_addrlen, hosts[index], strlen(hosts[index]), filename, filename_len, &dled_len, downloaded_len_max, self_public_key);
290 | } else {
291 | data = download_signed(info->ai_addr, info->ai_addrlen, hosts[index], strlen(hosts[index]), filename, filename_len, &dled_len, downloaded_len_max, self_public_key);
292 | }
293 |
294 | if (!data) {
295 | LOG_TO_FILE("data is NULL\n");
296 | continue;
297 | }
298 |
299 | if (cmp_end_file && cmp_end_file_len) {
300 | if (dled_len < cmp_end_file_len) {
301 | LOG_TO_FILE("Too Small %u < %u\n", dled_len, cmp_end_file_len);
302 | continue;
303 | }
304 |
305 | if (memcmp(cmp_end_file, data + (dled_len - cmp_end_file_len), cmp_end_file_len) != 0) {
306 | LOG_TO_FILE("cmp_end_file cmp error length %u\n", cmp_end_file_len);
307 | unsigned int j;
308 | for (j = 0; j < cmp_end_file_len; ++j) {
309 | LOG_TO_FILE("%c", cmp_end_file[j]);
310 | }
311 |
312 | LOG_TO_FILE("\n");
313 |
314 | uint8_t *tmpdt = data + (dled_len - cmp_end_file_len);
315 | for (j = 0; j < cmp_end_file_len; ++j) {
316 | LOG_TO_FILE("%c", tmpdt[j]);
317 | }
318 |
319 | LOG_TO_FILE("\n");
320 | continue;
321 | }
322 |
323 | dled_len -= cmp_end_file_len;
324 | }
325 |
326 | *downloaded_len = dled_len;
327 | freeaddrinfo(root);
328 | return data;
329 | } while ((info = info->ai_next));
330 |
331 | freeaddrinfo(root);
332 | }
333 |
334 | return NULL;
335 | }
336 |
--------------------------------------------------------------------------------
/utils.h:
--------------------------------------------------------------------------------
1 | #ifndef TOX_UTILS
2 | #define TOX_UTILS
3 |
4 | #define UPDATE_EXPIRE_DAYS 9
5 |
6 | FILE* LOG_FILE;
7 | #define LOG_TO_FILE(...) (LOG_FILE ? fprintf(LOG_FILE, __VA_ARGS__) : -1)
8 |
9 | /* in main.c */
10 | void set_download_progress(int progress);
11 |
12 | void *download_loop_all_host_ips(_Bool compressed, const char *hosts[], size_t number_hosts, const char *filename, size_t filename_len, uint32_t *downloaded_len, uint32_t downloaded_len_max, const uint8_t *self_public_key, const char *cmp_end_file, size_t cmp_end_file_len);
13 |
14 | #endif
15 |
--------------------------------------------------------------------------------
/xz/xz.h:
--------------------------------------------------------------------------------
1 | /*
2 | * XZ decompressor
3 | *
4 | * Authors: Lasse Collin
5 | * Igor Pavlov
6 | *
7 | * This file has been put into the public domain.
8 | * You can do whatever you want with this file.
9 | */
10 |
11 | #ifndef XZ_H
12 | #define XZ_H
13 |
14 | #ifdef __KERNEL__
15 | # include
16 | # include
17 | #else
18 | # include
19 | # include
20 | #endif
21 |
22 | #ifdef __cplusplus
23 | extern "C" {
24 | #endif
25 |
26 | /* In Linux, this is used to make extern functions static when needed. */
27 | #ifndef XZ_EXTERN
28 | # define XZ_EXTERN extern
29 | #endif
30 |
31 | /**
32 | * enum xz_mode - Operation mode
33 | *
34 | * @XZ_SINGLE: Single-call mode. This uses less RAM than
35 | * than multi-call modes, because the LZMA2
36 | * dictionary doesn't need to be allocated as
37 | * part of the decoder state. All required data
38 | * structures are allocated at initialization,
39 | * so xz_dec_run() cannot return XZ_MEM_ERROR.
40 | * @XZ_PREALLOC: Multi-call mode with preallocated LZMA2
41 | * dictionary buffer. All data structures are
42 | * allocated at initialization, so xz_dec_run()
43 | * cannot return XZ_MEM_ERROR.
44 | * @XZ_DYNALLOC: Multi-call mode. The LZMA2 dictionary is
45 | * allocated once the required size has been
46 | * parsed from the stream headers. If the
47 | * allocation fails, xz_dec_run() will return
48 | * XZ_MEM_ERROR.
49 | *
50 | * It is possible to enable support only for a subset of the above
51 | * modes at compile time by defining XZ_DEC_SINGLE, XZ_DEC_PREALLOC,
52 | * or XZ_DEC_DYNALLOC. The xz_dec kernel module is always compiled
53 | * with support for all operation modes, but the preboot code may
54 | * be built with fewer features to minimize code size.
55 | */
56 | enum xz_mode {
57 | XZ_SINGLE,
58 | XZ_PREALLOC,
59 | XZ_DYNALLOC
60 | };
61 |
62 | /**
63 | * enum xz_ret - Return codes
64 | * @XZ_OK: Everything is OK so far. More input or more
65 | * output space is required to continue. This
66 | * return code is possible only in multi-call mode
67 | * (XZ_PREALLOC or XZ_DYNALLOC).
68 | * @XZ_STREAM_END: Operation finished successfully.
69 | * @XZ_UNSUPPORTED_CHECK: Integrity check type is not supported. Decoding
70 | * is still possible in multi-call mode by simply
71 | * calling xz_dec_run() again.
72 | * Note that this return value is used only if
73 | * XZ_DEC_ANY_CHECK was defined at build time,
74 | * which is not used in the kernel. Unsupported
75 | * check types return XZ_OPTIONS_ERROR if
76 | * XZ_DEC_ANY_CHECK was not defined at build time.
77 | * @XZ_MEM_ERROR: Allocating memory failed. This return code is
78 | * possible only if the decoder was initialized
79 | * with XZ_DYNALLOC. The amount of memory that was
80 | * tried to be allocated was no more than the
81 | * dict_max argument given to xz_dec_init().
82 | * @XZ_MEMLIMIT_ERROR: A bigger LZMA2 dictionary would be needed than
83 | * allowed by the dict_max argument given to
84 | * xz_dec_init(). This return value is possible
85 | * only in multi-call mode (XZ_PREALLOC or
86 | * XZ_DYNALLOC); the single-call mode (XZ_SINGLE)
87 | * ignores the dict_max argument.
88 | * @XZ_FORMAT_ERROR: File format was not recognized (wrong magic
89 | * bytes).
90 | * @XZ_OPTIONS_ERROR: This implementation doesn't support the requested
91 | * compression options. In the decoder this means
92 | * that the header CRC32 matches, but the header
93 | * itself specifies something that we don't support.
94 | * @XZ_DATA_ERROR: Compressed data is corrupt.
95 | * @XZ_BUF_ERROR: Cannot make any progress. Details are slightly
96 | * different between multi-call and single-call
97 | * mode; more information below.
98 | *
99 | * In multi-call mode, XZ_BUF_ERROR is returned when two consecutive calls
100 | * to XZ code cannot consume any input and cannot produce any new output.
101 | * This happens when there is no new input available, or the output buffer
102 | * is full while at least one output byte is still pending. Assuming your
103 | * code is not buggy, you can get this error only when decoding a compressed
104 | * stream that is truncated or otherwise corrupt.
105 | *
106 | * In single-call mode, XZ_BUF_ERROR is returned only when the output buffer
107 | * is too small or the compressed input is corrupt in a way that makes the
108 | * decoder produce more output than the caller expected. When it is
109 | * (relatively) clear that the compressed input is truncated, XZ_DATA_ERROR
110 | * is used instead of XZ_BUF_ERROR.
111 | */
112 | enum xz_ret {
113 | XZ_OK,
114 | XZ_STREAM_END,
115 | XZ_UNSUPPORTED_CHECK,
116 | XZ_MEM_ERROR,
117 | XZ_MEMLIMIT_ERROR,
118 | XZ_FORMAT_ERROR,
119 | XZ_OPTIONS_ERROR,
120 | XZ_DATA_ERROR,
121 | XZ_BUF_ERROR
122 | };
123 |
124 | /**
125 | * struct xz_buf - Passing input and output buffers to XZ code
126 | * @in: Beginning of the input buffer. This may be NULL if and only
127 | * if in_pos is equal to in_size.
128 | * @in_pos: Current position in the input buffer. This must not exceed
129 | * in_size.
130 | * @in_size: Size of the input buffer
131 | * @out: Beginning of the output buffer. This may be NULL if and only
132 | * if out_pos is equal to out_size.
133 | * @out_pos: Current position in the output buffer. This must not exceed
134 | * out_size.
135 | * @out_size: Size of the output buffer
136 | *
137 | * Only the contents of the output buffer from out[out_pos] onward, and
138 | * the variables in_pos and out_pos are modified by the XZ code.
139 | */
140 | struct xz_buf {
141 | const uint8_t *in;
142 | size_t in_pos;
143 | size_t in_size;
144 |
145 | uint8_t *out;
146 | size_t out_pos;
147 | size_t out_size;
148 | };
149 |
150 | /**
151 | * struct xz_dec - Opaque type to hold the XZ decoder state
152 | */
153 | struct xz_dec;
154 |
155 | /**
156 | * xz_dec_init() - Allocate and initialize a XZ decoder state
157 | * @mode: Operation mode
158 | * @dict_max: Maximum size of the LZMA2 dictionary (history buffer) for
159 | * multi-call decoding. This is ignored in single-call mode
160 | * (mode == XZ_SINGLE). LZMA2 dictionary is always 2^n bytes
161 | * or 2^n + 2^(n-1) bytes (the latter sizes are less common
162 | * in practice), so other values for dict_max don't make sense.
163 | * In the kernel, dictionary sizes of 64 KiB, 128 KiB, 256 KiB,
164 | * 512 KiB, and 1 MiB are probably the only reasonable values,
165 | * except for kernel and initramfs images where a bigger
166 | * dictionary can be fine and useful.
167 | *
168 | * Single-call mode (XZ_SINGLE): xz_dec_run() decodes the whole stream at
169 | * once. The caller must provide enough output space or the decoding will
170 | * fail. The output space is used as the dictionary buffer, which is why
171 | * there is no need to allocate the dictionary as part of the decoder's
172 | * internal state.
173 | *
174 | * Because the output buffer is used as the workspace, streams encoded using
175 | * a big dictionary are not a problem in single-call mode. It is enough that
176 | * the output buffer is big enough to hold the actual uncompressed data; it
177 | * can be smaller than the dictionary size stored in the stream headers.
178 | *
179 | * Multi-call mode with preallocated dictionary (XZ_PREALLOC): dict_max bytes
180 | * of memory is preallocated for the LZMA2 dictionary. This way there is no
181 | * risk that xz_dec_run() could run out of memory, since xz_dec_run() will
182 | * never allocate any memory. Instead, if the preallocated dictionary is too
183 | * small for decoding the given input stream, xz_dec_run() will return
184 | * XZ_MEMLIMIT_ERROR. Thus, it is important to know what kind of data will be
185 | * decoded to avoid allocating excessive amount of memory for the dictionary.
186 | *
187 | * Multi-call mode with dynamically allocated dictionary (XZ_DYNALLOC):
188 | * dict_max specifies the maximum allowed dictionary size that xz_dec_run()
189 | * may allocate once it has parsed the dictionary size from the stream
190 | * headers. This way excessive allocations can be avoided while still
191 | * limiting the maximum memory usage to a sane value to prevent running the
192 | * system out of memory when decompressing streams from untrusted sources.
193 | *
194 | * On success, xz_dec_init() returns a pointer to struct xz_dec, which is
195 | * ready to be used with xz_dec_run(). If memory allocation fails,
196 | * xz_dec_init() returns NULL.
197 | */
198 | XZ_EXTERN struct xz_dec *xz_dec_init(enum xz_mode mode, uint32_t dict_max);
199 |
200 | /**
201 | * xz_dec_run() - Run the XZ decoder
202 | * @s: Decoder state allocated using xz_dec_init()
203 | * @b: Input and output buffers
204 | *
205 | * The possible return values depend on build options and operation mode.
206 | * See enum xz_ret for details.
207 | *
208 | * Note that if an error occurs in single-call mode (return value is not
209 | * XZ_STREAM_END), b->in_pos and b->out_pos are not modified and the
210 | * contents of the output buffer from b->out[b->out_pos] onward are
211 | * undefined. This is true even after XZ_BUF_ERROR, because with some filter
212 | * chains, there may be a second pass over the output buffer, and this pass
213 | * cannot be properly done if the output buffer is truncated. Thus, you
214 | * cannot give the single-call decoder a too small buffer and then expect to
215 | * get that amount valid data from the beginning of the stream. You must use
216 | * the multi-call decoder if you don't want to uncompress the whole stream.
217 | */
218 | XZ_EXTERN enum xz_ret xz_dec_run(struct xz_dec *s, struct xz_buf *b);
219 |
220 | /**
221 | * xz_dec_reset() - Reset an already allocated decoder state
222 | * @s: Decoder state allocated using xz_dec_init()
223 | *
224 | * This function can be used to reset the multi-call decoder state without
225 | * freeing and reallocating memory with xz_dec_end() and xz_dec_init().
226 | *
227 | * In single-call mode, xz_dec_reset() is always called in the beginning of
228 | * xz_dec_run(). Thus, explicit call to xz_dec_reset() is useful only in
229 | * multi-call mode.
230 | */
231 | XZ_EXTERN void xz_dec_reset(struct xz_dec *s);
232 |
233 | /**
234 | * xz_dec_end() - Free the memory allocated for the decoder state
235 | * @s: Decoder state allocated using xz_dec_init(). If s is NULL,
236 | * this function does nothing.
237 | */
238 | XZ_EXTERN void xz_dec_end(struct xz_dec *s);
239 |
240 | /*
241 | * Standalone build (userspace build or in-kernel build for boot time use)
242 | * needs a CRC32 implementation. For normal in-kernel use, kernel's own
243 | * CRC32 module is used instead, and users of this module don't need to
244 | * care about the functions below.
245 | */
246 | #ifndef XZ_INTERNAL_CRC32
247 | # ifdef __KERNEL__
248 | # define XZ_INTERNAL_CRC32 0
249 | # else
250 | # define XZ_INTERNAL_CRC32 1
251 | # endif
252 | #endif
253 |
254 | /*
255 | * If CRC64 support has been enabled with XZ_USE_CRC64, a CRC64
256 | * implementation is needed too.
257 | */
258 | #ifndef XZ_USE_CRC64
259 | # undef XZ_INTERNAL_CRC64
260 | # define XZ_INTERNAL_CRC64 0
261 | #endif
262 | #ifndef XZ_INTERNAL_CRC64
263 | # ifdef __KERNEL__
264 | # error Using CRC64 in the kernel has not been implemented.
265 | # else
266 | # define XZ_INTERNAL_CRC64 1
267 | # endif
268 | #endif
269 |
270 | #if XZ_INTERNAL_CRC32
271 | /*
272 | * This must be called before any other xz_* function to initialize
273 | * the CRC32 lookup table.
274 | */
275 | XZ_EXTERN void xz_crc32_init(void);
276 |
277 | /*
278 | * Update CRC32 value using the polynomial from IEEE-802.3. To start a new
279 | * calculation, the third argument must be zero. To continue the calculation,
280 | * the previously returned value is passed as the third argument.
281 | */
282 | XZ_EXTERN uint32_t xz_crc32(const uint8_t *buf, size_t size, uint32_t crc);
283 | #endif
284 |
285 | #if XZ_INTERNAL_CRC64
286 | /*
287 | * This must be called before any other xz_* function (except xz_crc32_init())
288 | * to initialize the CRC64 lookup table.
289 | */
290 | XZ_EXTERN void xz_crc64_init(void);
291 |
292 | /*
293 | * Update CRC64 value using the polynomial from ECMA-182. To start a new
294 | * calculation, the third argument must be zero. To continue the calculation,
295 | * the previously returned value is passed as the third argument.
296 | */
297 | XZ_EXTERN uint64_t xz_crc64(const uint8_t *buf, size_t size, uint64_t crc);
298 | #endif
299 |
300 | #ifdef __cplusplus
301 | }
302 | #endif
303 |
304 | #endif
305 |
--------------------------------------------------------------------------------
/xz/xz_config.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Private includes and definitions for userspace use of XZ Embedded
3 | *
4 | * Author: Lasse Collin
5 | *
6 | * This file has been put into the public domain.
7 | * You can do whatever you want with this file.
8 | */
9 |
10 | #ifndef XZ_CONFIG_H
11 | #define XZ_CONFIG_H
12 |
13 | /* Uncomment to enable CRC64 support. */
14 | /* #define XZ_USE_CRC64 */
15 |
16 | /* Uncomment as needed to enable BCJ filter decoders. */
17 | /* #define XZ_DEC_X86 */
18 | /* #define XZ_DEC_POWERPC */
19 | /* #define XZ_DEC_IA64 */
20 | /* #define XZ_DEC_ARM */
21 | /* #define XZ_DEC_ARMTHUMB */
22 | /* #define XZ_DEC_SPARC */
23 |
24 | /*
25 | * MSVC doesn't support modern C but XZ Embedded is mostly C89
26 | * so these are enough.
27 | */
28 | #ifdef _MSC_VER
29 | typedef unsigned char bool;
30 | # define true 1
31 | # define false 0
32 | # define inline __inline
33 | #else
34 | # include
35 | #endif
36 |
37 | #include
38 | #include
39 |
40 | #include "xz.h"
41 |
42 | #define kmalloc(size, flags) malloc(size)
43 | #define kfree(ptr) free(ptr)
44 | #define vmalloc(size) malloc(size)
45 | #define vfree(ptr) free(ptr)
46 |
47 | #define memeq(a, b, size) (memcmp(a, b, size) == 0)
48 | #define memzero(buf, size) memset(buf, 0, size)
49 |
50 | #ifndef min
51 | # define min(x, y) ((x) < (y) ? (x) : (y))
52 | #endif
53 | #define min_t(type, x, y) min(x, y)
54 |
55 | /*
56 | * Some functions have been marked with __always_inline to keep the
57 | * performance reasonable even when the compiler is optimizing for
58 | * small code size. You may be able to save a few bytes by #defining
59 | * __always_inline to plain inline, but don't complain if the code
60 | * becomes slow.
61 | *
62 | * NOTE: System headers on GNU/Linux may #define this macro already,
63 | * so if you want to change it, you need to #undef it first.
64 | */
65 | #ifndef __always_inline
66 | # ifdef __GNUC__
67 | # define __always_inline \
68 | inline __attribute__((__always_inline__))
69 | # else
70 | # define __always_inline inline
71 | # endif
72 | #endif
73 |
74 | /* Inline functions to access unaligned unsigned 32-bit integers */
75 | #ifndef get_unaligned_le32
76 | static inline uint32_t get_unaligned_le32(const uint8_t *buf)
77 | {
78 | return (uint32_t)buf[0]
79 | | ((uint32_t)buf[1] << 8)
80 | | ((uint32_t)buf[2] << 16)
81 | | ((uint32_t)buf[3] << 24);
82 | }
83 | #endif
84 |
85 | #ifndef get_unaligned_be32
86 | static inline uint32_t get_unaligned_be32(const uint8_t *buf)
87 | {
88 | return (uint32_t)(buf[0] << 24)
89 | | ((uint32_t)buf[1] << 16)
90 | | ((uint32_t)buf[2] << 8)
91 | | (uint32_t)buf[3];
92 | }
93 | #endif
94 |
95 | #ifndef put_unaligned_le32
96 | static inline void put_unaligned_le32(uint32_t val, uint8_t *buf)
97 | {
98 | buf[0] = (uint8_t)val;
99 | buf[1] = (uint8_t)(val >> 8);
100 | buf[2] = (uint8_t)(val >> 16);
101 | buf[3] = (uint8_t)(val >> 24);
102 | }
103 | #endif
104 |
105 | #ifndef put_unaligned_be32
106 | static inline void put_unaligned_be32(uint32_t val, uint8_t *buf)
107 | {
108 | buf[0] = (uint8_t)(val >> 24);
109 | buf[1] = (uint8_t)(val >> 16);
110 | buf[2] = (uint8_t)(val >> 8);
111 | buf[3] = (uint8_t)val;
112 | }
113 | #endif
114 |
115 | /*
116 | * Use get_unaligned_le32() also for aligned access for simplicity. On
117 | * little endian systems, #define get_le32(ptr) (*(const uint32_t *)(ptr))
118 | * could save a few bytes in code size.
119 | */
120 | #ifndef get_le32
121 | # define get_le32 get_unaligned_le32
122 | #endif
123 |
124 | #endif
125 |
--------------------------------------------------------------------------------
/xz/xz_crc32.c:
--------------------------------------------------------------------------------
1 | /*
2 | * CRC32 using the polynomial from IEEE-802.3
3 | *
4 | * Authors: Lasse Collin
5 | * Igor Pavlov
6 | *
7 | * This file has been put into the public domain.
8 | * You can do whatever you want with this file.
9 | */
10 |
11 | /*
12 | * This is not the fastest implementation, but it is pretty compact.
13 | * The fastest versions of xz_crc32() on modern CPUs without hardware
14 | * accelerated CRC instruction are 3-5 times as fast as this version,
15 | * but they are bigger and use more memory for the lookup table.
16 | */
17 |
18 | #include "xz_private.h"
19 |
20 | /*
21 | * STATIC_RW_DATA is used in the pre-boot environment on some architectures.
22 | * See for details.
23 | */
24 | #ifndef STATIC_RW_DATA
25 | # define STATIC_RW_DATA static
26 | #endif
27 |
28 | STATIC_RW_DATA uint32_t xz_crc32_table[256];
29 |
30 | XZ_EXTERN void xz_crc32_init(void)
31 | {
32 | const uint32_t poly = 0xEDB88320;
33 |
34 | uint32_t i;
35 | uint32_t j;
36 | uint32_t r;
37 |
38 | for (i = 0; i < 256; ++i) {
39 | r = i;
40 | for (j = 0; j < 8; ++j)
41 | r = (r >> 1) ^ (poly & ~((r & 1) - 1));
42 |
43 | xz_crc32_table[i] = r;
44 | }
45 |
46 | return;
47 | }
48 |
49 | XZ_EXTERN uint32_t xz_crc32(const uint8_t *buf, size_t size, uint32_t crc)
50 | {
51 | crc = ~crc;
52 |
53 | while (size != 0) {
54 | crc = xz_crc32_table[*buf++ ^ (crc & 0xFF)] ^ (crc >> 8);
55 | --size;
56 | }
57 |
58 | return ~crc;
59 | }
60 |
--------------------------------------------------------------------------------
/xz/xz_dec_lzma2.c:
--------------------------------------------------------------------------------
1 | /*
2 | * LZMA2 decoder
3 | *
4 | * Authors: Lasse Collin
5 | * Igor Pavlov
6 | *
7 | * This file has been put into the public domain.
8 | * You can do whatever you want with this file.
9 | */
10 |
11 | #include "xz_private.h"
12 | #include "xz_lzma2.h"
13 |
14 | /*
15 | * Range decoder initialization eats the first five bytes of each LZMA chunk.
16 | */
17 | #define RC_INIT_BYTES 5
18 |
19 | /*
20 | * Minimum number of usable input buffer to safely decode one LZMA symbol.
21 | * The worst case is that we decode 22 bits using probabilities and 26
22 | * direct bits. This may decode at maximum of 20 bytes of input. However,
23 | * lzma_main() does an extra normalization before returning, thus we
24 | * need to put 21 here.
25 | */
26 | #define LZMA_IN_REQUIRED 21
27 |
28 | /*
29 | * Dictionary (history buffer)
30 | *
31 | * These are always true:
32 | * start <= pos <= full <= end
33 | * pos <= limit <= end
34 | *
35 | * In multi-call mode, also these are true:
36 | * end == size
37 | * size <= size_max
38 | * allocated <= size
39 | *
40 | * Most of these variables are size_t to support single-call mode,
41 | * in which the dictionary variables address the actual output
42 | * buffer directly.
43 | */
44 | struct dictionary {
45 | /* Beginning of the history buffer */
46 | uint8_t *buf;
47 |
48 | /* Old position in buf (before decoding more data) */
49 | size_t start;
50 |
51 | /* Position in buf */
52 | size_t pos;
53 |
54 | /*
55 | * How full dictionary is. This is used to detect corrupt input that
56 | * would read beyond the beginning of the uncompressed stream.
57 | */
58 | size_t full;
59 |
60 | /* Write limit; we don't write to buf[limit] or later bytes. */
61 | size_t limit;
62 |
63 | /*
64 | * End of the dictionary buffer. In multi-call mode, this is
65 | * the same as the dictionary size. In single-call mode, this
66 | * indicates the size of the output buffer.
67 | */
68 | size_t end;
69 |
70 | /*
71 | * Size of the dictionary as specified in Block Header. This is used
72 | * together with "full" to detect corrupt input that would make us
73 | * read beyond the beginning of the uncompressed stream.
74 | */
75 | uint32_t size;
76 |
77 | /*
78 | * Maximum allowed dictionary size in multi-call mode.
79 | * This is ignored in single-call mode.
80 | */
81 | uint32_t size_max;
82 |
83 | /*
84 | * Amount of memory currently allocated for the dictionary.
85 | * This is used only with XZ_DYNALLOC. (With XZ_PREALLOC,
86 | * size_max is always the same as the allocated size.)
87 | */
88 | uint32_t allocated;
89 |
90 | /* Operation mode */
91 | enum xz_mode mode;
92 | };
93 |
94 | /* Range decoder */
95 | struct rc_dec {
96 | uint32_t range;
97 | uint32_t code;
98 |
99 | /*
100 | * Number of initializing bytes remaining to be read
101 | * by rc_read_init().
102 | */
103 | uint32_t init_bytes_left;
104 |
105 | /*
106 | * Buffer from which we read our input. It can be either
107 | * temp.buf or the caller-provided input buffer.
108 | */
109 | const uint8_t *in;
110 | size_t in_pos;
111 | size_t in_limit;
112 | };
113 |
114 | /* Probabilities for a length decoder. */
115 | struct lzma_len_dec {
116 | /* Probability of match length being at least 10 */
117 | uint16_t choice;
118 |
119 | /* Probability of match length being at least 18 */
120 | uint16_t choice2;
121 |
122 | /* Probabilities for match lengths 2-9 */
123 | uint16_t low[POS_STATES_MAX][LEN_LOW_SYMBOLS];
124 |
125 | /* Probabilities for match lengths 10-17 */
126 | uint16_t mid[POS_STATES_MAX][LEN_MID_SYMBOLS];
127 |
128 | /* Probabilities for match lengths 18-273 */
129 | uint16_t high[LEN_HIGH_SYMBOLS];
130 | };
131 |
132 | struct lzma_dec {
133 | /* Distances of latest four matches */
134 | uint32_t rep0;
135 | uint32_t rep1;
136 | uint32_t rep2;
137 | uint32_t rep3;
138 |
139 | /* Types of the most recently seen LZMA symbols */
140 | enum lzma_state state;
141 |
142 | /*
143 | * Length of a match. This is updated so that dict_repeat can
144 | * be called again to finish repeating the whole match.
145 | */
146 | uint32_t len;
147 |
148 | /*
149 | * LZMA properties or related bit masks (number of literal
150 | * context bits, a mask dervied from the number of literal
151 | * position bits, and a mask dervied from the number
152 | * position bits)
153 | */
154 | uint32_t lc;
155 | uint32_t literal_pos_mask; /* (1 << lp) - 1 */
156 | uint32_t pos_mask; /* (1 << pb) - 1 */
157 |
158 | /* If 1, it's a match. Otherwise it's a single 8-bit literal. */
159 | uint16_t is_match[STATES][POS_STATES_MAX];
160 |
161 | /* If 1, it's a repeated match. The distance is one of rep0 .. rep3. */
162 | uint16_t is_rep[STATES];
163 |
164 | /*
165 | * If 0, distance of a repeated match is rep0.
166 | * Otherwise check is_rep1.
167 | */
168 | uint16_t is_rep0[STATES];
169 |
170 | /*
171 | * If 0, distance of a repeated match is rep1.
172 | * Otherwise check is_rep2.
173 | */
174 | uint16_t is_rep1[STATES];
175 |
176 | /* If 0, distance of a repeated match is rep2. Otherwise it is rep3. */
177 | uint16_t is_rep2[STATES];
178 |
179 | /*
180 | * If 1, the repeated match has length of one byte. Otherwise
181 | * the length is decoded from rep_len_decoder.
182 | */
183 | uint16_t is_rep0_long[STATES][POS_STATES_MAX];
184 |
185 | /*
186 | * Probability tree for the highest two bits of the match
187 | * distance. There is a separate probability tree for match
188 | * lengths of 2 (i.e. MATCH_LEN_MIN), 3, 4, and [5, 273].
189 | */
190 | uint16_t dist_slot[DIST_STATES][DIST_SLOTS];
191 |
192 | /*
193 | * Probility trees for additional bits for match distance
194 | * when the distance is in the range [4, 127].
195 | */
196 | uint16_t dist_special[FULL_DISTANCES - DIST_MODEL_END];
197 |
198 | /*
199 | * Probability tree for the lowest four bits of a match
200 | * distance that is equal to or greater than 128.
201 | */
202 | uint16_t dist_align[ALIGN_SIZE];
203 |
204 | /* Length of a normal match */
205 | struct lzma_len_dec match_len_dec;
206 |
207 | /* Length of a repeated match */
208 | struct lzma_len_dec rep_len_dec;
209 |
210 | /* Probabilities of literals */
211 | uint16_t literal[LITERAL_CODERS_MAX][LITERAL_CODER_SIZE];
212 | };
213 |
214 | struct lzma2_dec {
215 | /* Position in xz_dec_lzma2_run(). */
216 | enum lzma2_seq {
217 | SEQ_CONTROL,
218 | SEQ_UNCOMPRESSED_1,
219 | SEQ_UNCOMPRESSED_2,
220 | SEQ_COMPRESSED_0,
221 | SEQ_COMPRESSED_1,
222 | SEQ_PROPERTIES,
223 | SEQ_LZMA_PREPARE,
224 | SEQ_LZMA_RUN,
225 | SEQ_COPY
226 | } sequence;
227 |
228 | /* Next position after decoding the compressed size of the chunk. */
229 | enum lzma2_seq next_sequence;
230 |
231 | /* Uncompressed size of LZMA chunk (2 MiB at maximum) */
232 | uint32_t uncompressed;
233 |
234 | /*
235 | * Compressed size of LZMA chunk or compressed/uncompressed
236 | * size of uncompressed chunk (64 KiB at maximum)
237 | */
238 | uint32_t compressed;
239 |
240 | /*
241 | * True if dictionary reset is needed. This is false before
242 | * the first chunk (LZMA or uncompressed).
243 | */
244 | bool need_dict_reset;
245 |
246 | /*
247 | * True if new LZMA properties are needed. This is false
248 | * before the first LZMA chunk.
249 | */
250 | bool need_props;
251 | };
252 |
253 | struct xz_dec_lzma2 {
254 | /*
255 | * The order below is important on x86 to reduce code size and
256 | * it shouldn't hurt on other platforms. Everything up to and
257 | * including lzma.pos_mask are in the first 128 bytes on x86-32,
258 | * which allows using smaller instructions to access those
259 | * variables. On x86-64, fewer variables fit into the first 128
260 | * bytes, but this is still the best order without sacrificing
261 | * the readability by splitting the structures.
262 | */
263 | struct rc_dec rc;
264 | struct dictionary dict;
265 | struct lzma2_dec lzma2;
266 | struct lzma_dec lzma;
267 |
268 | /*
269 | * Temporary buffer which holds small number of input bytes between
270 | * decoder calls. See lzma2_lzma() for details.
271 | */
272 | struct {
273 | uint32_t size;
274 | uint8_t buf[3 * LZMA_IN_REQUIRED];
275 | } temp;
276 | };
277 |
278 | /**************
279 | * Dictionary *
280 | **************/
281 |
282 | /*
283 | * Reset the dictionary state. When in single-call mode, set up the beginning
284 | * of the dictionary to point to the actual output buffer.
285 | */
286 | static void dict_reset(struct dictionary *dict, struct xz_buf *b)
287 | {
288 | if (DEC_IS_SINGLE(dict->mode)) {
289 | dict->buf = b->out + b->out_pos;
290 | dict->end = b->out_size - b->out_pos;
291 | }
292 |
293 | dict->start = 0;
294 | dict->pos = 0;
295 | dict->limit = 0;
296 | dict->full = 0;
297 | }
298 |
299 | /* Set dictionary write limit */
300 | static void dict_limit(struct dictionary *dict, size_t out_max)
301 | {
302 | if (dict->end - dict->pos <= out_max)
303 | dict->limit = dict->end;
304 | else
305 | dict->limit = dict->pos + out_max;
306 | }
307 |
308 | /* Return true if at least one byte can be written into the dictionary. */
309 | static inline bool dict_has_space(const struct dictionary *dict)
310 | {
311 | return dict->pos < dict->limit;
312 | }
313 |
314 | /*
315 | * Get a byte from the dictionary at the given distance. The distance is
316 | * assumed to valid, or as a special case, zero when the dictionary is
317 | * still empty. This special case is needed for single-call decoding to
318 | * avoid writing a '\0' to the end of the destination buffer.
319 | */
320 | static inline uint32_t dict_get(const struct dictionary *dict, uint32_t dist)
321 | {
322 | size_t offset = dict->pos - dist - 1;
323 |
324 | if (dist >= dict->pos)
325 | offset += dict->end;
326 |
327 | return dict->full > 0 ? dict->buf[offset] : 0;
328 | }
329 |
330 | /*
331 | * Put one byte into the dictionary. It is assumed that there is space for it.
332 | */
333 | static inline void dict_put(struct dictionary *dict, uint8_t byte)
334 | {
335 | dict->buf[dict->pos++] = byte;
336 |
337 | if (dict->full < dict->pos)
338 | dict->full = dict->pos;
339 | }
340 |
341 | /*
342 | * Repeat given number of bytes from the given distance. If the distance is
343 | * invalid, false is returned. On success, true is returned and *len is
344 | * updated to indicate how many bytes were left to be repeated.
345 | */
346 | static bool dict_repeat(struct dictionary *dict, uint32_t *len, uint32_t dist)
347 | {
348 | size_t back;
349 | uint32_t left;
350 |
351 | if (dist >= dict->full || dist >= dict->size)
352 | return false;
353 |
354 | left = min_t(size_t, dict->limit - dict->pos, *len);
355 | *len -= left;
356 |
357 | back = dict->pos - dist - 1;
358 | if (dist >= dict->pos)
359 | back += dict->end;
360 |
361 | do {
362 | dict->buf[dict->pos++] = dict->buf[back++];
363 | if (back == dict->end)
364 | back = 0;
365 | } while (--left > 0);
366 |
367 | if (dict->full < dict->pos)
368 | dict->full = dict->pos;
369 |
370 | return true;
371 | }
372 |
373 | /* Copy uncompressed data as is from input to dictionary and output buffers. */
374 | static void dict_uncompressed(struct dictionary *dict, struct xz_buf *b,
375 | uint32_t *left)
376 | {
377 | size_t copy_size;
378 |
379 | while (*left > 0 && b->in_pos < b->in_size
380 | && b->out_pos < b->out_size) {
381 | copy_size = min(b->in_size - b->in_pos,
382 | b->out_size - b->out_pos);
383 | if (copy_size > dict->end - dict->pos)
384 | copy_size = dict->end - dict->pos;
385 | if (copy_size > *left)
386 | copy_size = *left;
387 |
388 | *left -= copy_size;
389 |
390 | memcpy(dict->buf + dict->pos, b->in + b->in_pos, copy_size);
391 | dict->pos += copy_size;
392 |
393 | if (dict->full < dict->pos)
394 | dict->full = dict->pos;
395 |
396 | if (DEC_IS_MULTI(dict->mode)) {
397 | if (dict->pos == dict->end)
398 | dict->pos = 0;
399 |
400 | memcpy(b->out + b->out_pos, b->in + b->in_pos,
401 | copy_size);
402 | }
403 |
404 | dict->start = dict->pos;
405 |
406 | b->out_pos += copy_size;
407 | b->in_pos += copy_size;
408 | }
409 | }
410 |
411 | /*
412 | * Flush pending data from dictionary to b->out. It is assumed that there is
413 | * enough space in b->out. This is guaranteed because caller uses dict_limit()
414 | * before decoding data into the dictionary.
415 | */
416 | static uint32_t dict_flush(struct dictionary *dict, struct xz_buf *b)
417 | {
418 | size_t copy_size = dict->pos - dict->start;
419 |
420 | if (DEC_IS_MULTI(dict->mode)) {
421 | if (dict->pos == dict->end)
422 | dict->pos = 0;
423 |
424 | memcpy(b->out + b->out_pos, dict->buf + dict->start,
425 | copy_size);
426 | }
427 |
428 | dict->start = dict->pos;
429 | b->out_pos += copy_size;
430 | return copy_size;
431 | }
432 |
433 | /*****************
434 | * Range decoder *
435 | *****************/
436 |
437 | /* Reset the range decoder. */
438 | static void rc_reset(struct rc_dec *rc)
439 | {
440 | rc->range = (uint32_t)-1;
441 | rc->code = 0;
442 | rc->init_bytes_left = RC_INIT_BYTES;
443 | }
444 |
445 | /*
446 | * Read the first five initial bytes into rc->code if they haven't been
447 | * read already. (Yes, the first byte gets completely ignored.)
448 | */
449 | static bool rc_read_init(struct rc_dec *rc, struct xz_buf *b)
450 | {
451 | while (rc->init_bytes_left > 0) {
452 | if (b->in_pos == b->in_size)
453 | return false;
454 |
455 | rc->code = (rc->code << 8) + b->in[b->in_pos++];
456 | --rc->init_bytes_left;
457 | }
458 |
459 | return true;
460 | }
461 |
462 | /* Return true if there may not be enough input for the next decoding loop. */
463 | static inline bool rc_limit_exceeded(const struct rc_dec *rc)
464 | {
465 | return rc->in_pos > rc->in_limit;
466 | }
467 |
468 | /*
469 | * Return true if it is possible (from point of view of range decoder) that
470 | * we have reached the end of the LZMA chunk.
471 | */
472 | static inline bool rc_is_finished(const struct rc_dec *rc)
473 | {
474 | return rc->code == 0;
475 | }
476 |
477 | /* Read the next input byte if needed. */
478 | static __always_inline void rc_normalize(struct rc_dec *rc)
479 | {
480 | if (rc->range < RC_TOP_VALUE) {
481 | rc->range <<= RC_SHIFT_BITS;
482 | rc->code = (rc->code << RC_SHIFT_BITS) + rc->in[rc->in_pos++];
483 | }
484 | }
485 |
486 | /*
487 | * Decode one bit. In some versions, this function has been splitted in three
488 | * functions so that the compiler is supposed to be able to more easily avoid
489 | * an extra branch. In this particular version of the LZMA decoder, this
490 | * doesn't seem to be a good idea (tested with GCC 3.3.6, 3.4.6, and 4.3.3
491 | * on x86). Using a non-splitted version results in nicer looking code too.
492 | *
493 | * NOTE: This must return an int. Do not make it return a bool or the speed
494 | * of the code generated by GCC 3.x decreases 10-15 %. (GCC 4.3 doesn't care,
495 | * and it generates 10-20 % faster code than GCC 3.x from this file anyway.)
496 | */
497 | static __always_inline int rc_bit(struct rc_dec *rc, uint16_t *prob)
498 | {
499 | uint32_t bound;
500 | int bit;
501 |
502 | rc_normalize(rc);
503 | bound = (rc->range >> RC_BIT_MODEL_TOTAL_BITS) * *prob;
504 | if (rc->code < bound) {
505 | rc->range = bound;
506 | *prob += (RC_BIT_MODEL_TOTAL - *prob) >> RC_MOVE_BITS;
507 | bit = 0;
508 | } else {
509 | rc->range -= bound;
510 | rc->code -= bound;
511 | *prob -= *prob >> RC_MOVE_BITS;
512 | bit = 1;
513 | }
514 |
515 | return bit;
516 | }
517 |
518 | /* Decode a bittree starting from the most significant bit. */
519 | static __always_inline uint32_t rc_bittree(struct rc_dec *rc,
520 | uint16_t *probs, uint32_t limit)
521 | {
522 | uint32_t symbol = 1;
523 |
524 | do {
525 | if (rc_bit(rc, &probs[symbol]))
526 | symbol = (symbol << 1) + 1;
527 | else
528 | symbol <<= 1;
529 | } while (symbol < limit);
530 |
531 | return symbol;
532 | }
533 |
534 | /* Decode a bittree starting from the least significant bit. */
535 | static __always_inline void rc_bittree_reverse(struct rc_dec *rc,
536 | uint16_t *probs,
537 | uint32_t *dest, uint32_t limit)
538 | {
539 | uint32_t symbol = 1;
540 | uint32_t i = 0;
541 |
542 | do {
543 | if (rc_bit(rc, &probs[symbol])) {
544 | symbol = (symbol << 1) + 1;
545 | *dest += 1 << i;
546 | } else {
547 | symbol <<= 1;
548 | }
549 | } while (++i < limit);
550 | }
551 |
552 | /* Decode direct bits (fixed fifty-fifty probability) */
553 | static inline void rc_direct(struct rc_dec *rc, uint32_t *dest, uint32_t limit)
554 | {
555 | uint32_t mask;
556 |
557 | do {
558 | rc_normalize(rc);
559 | rc->range >>= 1;
560 | rc->code -= rc->range;
561 | mask = (uint32_t)0 - (rc->code >> 31);
562 | rc->code += rc->range & mask;
563 | *dest = (*dest << 1) + (mask + 1);
564 | } while (--limit > 0);
565 | }
566 |
567 | /********
568 | * LZMA *
569 | ********/
570 |
571 | /* Get pointer to literal coder probability array. */
572 | static uint16_t *lzma_literal_probs(struct xz_dec_lzma2 *s)
573 | {
574 | uint32_t prev_byte = dict_get(&s->dict, 0);
575 | uint32_t low = prev_byte >> (8 - s->lzma.lc);
576 | uint32_t high = (s->dict.pos & s->lzma.literal_pos_mask) << s->lzma.lc;
577 | return s->lzma.literal[low + high];
578 | }
579 |
580 | /* Decode a literal (one 8-bit byte) */
581 | static void lzma_literal(struct xz_dec_lzma2 *s)
582 | {
583 | uint16_t *probs;
584 | uint32_t symbol;
585 | uint32_t match_byte;
586 | uint32_t match_bit;
587 | uint32_t offset;
588 | uint32_t i;
589 |
590 | probs = lzma_literal_probs(s);
591 |
592 | if (lzma_state_is_literal(s->lzma.state)) {
593 | symbol = rc_bittree(&s->rc, probs, 0x100);
594 | } else {
595 | symbol = 1;
596 | match_byte = dict_get(&s->dict, s->lzma.rep0) << 1;
597 | offset = 0x100;
598 |
599 | do {
600 | match_bit = match_byte & offset;
601 | match_byte <<= 1;
602 | i = offset + match_bit + symbol;
603 |
604 | if (rc_bit(&s->rc, &probs[i])) {
605 | symbol = (symbol << 1) + 1;
606 | offset &= match_bit;
607 | } else {
608 | symbol <<= 1;
609 | offset &= ~match_bit;
610 | }
611 | } while (symbol < 0x100);
612 | }
613 |
614 | dict_put(&s->dict, (uint8_t)symbol);
615 | lzma_state_literal(&s->lzma.state);
616 | }
617 |
618 | /* Decode the length of the match into s->lzma.len. */
619 | static void lzma_len(struct xz_dec_lzma2 *s, struct lzma_len_dec *l,
620 | uint32_t pos_state)
621 | {
622 | uint16_t *probs;
623 | uint32_t limit;
624 |
625 | if (!rc_bit(&s->rc, &l->choice)) {
626 | probs = l->low[pos_state];
627 | limit = LEN_LOW_SYMBOLS;
628 | s->lzma.len = MATCH_LEN_MIN;
629 | } else {
630 | if (!rc_bit(&s->rc, &l->choice2)) {
631 | probs = l->mid[pos_state];
632 | limit = LEN_MID_SYMBOLS;
633 | s->lzma.len = MATCH_LEN_MIN + LEN_LOW_SYMBOLS;
634 | } else {
635 | probs = l->high;
636 | limit = LEN_HIGH_SYMBOLS;
637 | s->lzma.len = MATCH_LEN_MIN + LEN_LOW_SYMBOLS
638 | + LEN_MID_SYMBOLS;
639 | }
640 | }
641 |
642 | s->lzma.len += rc_bittree(&s->rc, probs, limit) - limit;
643 | }
644 |
645 | /* Decode a match. The distance will be stored in s->lzma.rep0. */
646 | static void lzma_match(struct xz_dec_lzma2 *s, uint32_t pos_state)
647 | {
648 | uint16_t *probs;
649 | uint32_t dist_slot;
650 | uint32_t limit;
651 |
652 | lzma_state_match(&s->lzma.state);
653 |
654 | s->lzma.rep3 = s->lzma.rep2;
655 | s->lzma.rep2 = s->lzma.rep1;
656 | s->lzma.rep1 = s->lzma.rep0;
657 |
658 | lzma_len(s, &s->lzma.match_len_dec, pos_state);
659 |
660 | probs = s->lzma.dist_slot[lzma_get_dist_state(s->lzma.len)];
661 | dist_slot = rc_bittree(&s->rc, probs, DIST_SLOTS) - DIST_SLOTS;
662 |
663 | if (dist_slot < DIST_MODEL_START) {
664 | s->lzma.rep0 = dist_slot;
665 | } else {
666 | limit = (dist_slot >> 1) - 1;
667 | s->lzma.rep0 = 2 + (dist_slot & 1);
668 |
669 | if (dist_slot < DIST_MODEL_END) {
670 | s->lzma.rep0 <<= limit;
671 | probs = s->lzma.dist_special + s->lzma.rep0
672 | - dist_slot - 1;
673 | rc_bittree_reverse(&s->rc, probs,
674 | &s->lzma.rep0, limit);
675 | } else {
676 | rc_direct(&s->rc, &s->lzma.rep0, limit - ALIGN_BITS);
677 | s->lzma.rep0 <<= ALIGN_BITS;
678 | rc_bittree_reverse(&s->rc, s->lzma.dist_align,
679 | &s->lzma.rep0, ALIGN_BITS);
680 | }
681 | }
682 | }
683 |
684 | /*
685 | * Decode a repeated match. The distance is one of the four most recently
686 | * seen matches. The distance will be stored in s->lzma.rep0.
687 | */
688 | static void lzma_rep_match(struct xz_dec_lzma2 *s, uint32_t pos_state)
689 | {
690 | uint32_t tmp;
691 |
692 | if (!rc_bit(&s->rc, &s->lzma.is_rep0[s->lzma.state])) {
693 | if (!rc_bit(&s->rc, &s->lzma.is_rep0_long[
694 | s->lzma.state][pos_state])) {
695 | lzma_state_short_rep(&s->lzma.state);
696 | s->lzma.len = 1;
697 | return;
698 | }
699 | } else {
700 | if (!rc_bit(&s->rc, &s->lzma.is_rep1[s->lzma.state])) {
701 | tmp = s->lzma.rep1;
702 | } else {
703 | if (!rc_bit(&s->rc, &s->lzma.is_rep2[s->lzma.state])) {
704 | tmp = s->lzma.rep2;
705 | } else {
706 | tmp = s->lzma.rep3;
707 | s->lzma.rep3 = s->lzma.rep2;
708 | }
709 |
710 | s->lzma.rep2 = s->lzma.rep1;
711 | }
712 |
713 | s->lzma.rep1 = s->lzma.rep0;
714 | s->lzma.rep0 = tmp;
715 | }
716 |
717 | lzma_state_long_rep(&s->lzma.state);
718 | lzma_len(s, &s->lzma.rep_len_dec, pos_state);
719 | }
720 |
721 | /* LZMA decoder core */
722 | static bool lzma_main(struct xz_dec_lzma2 *s)
723 | {
724 | uint32_t pos_state;
725 |
726 | /*
727 | * If the dictionary was reached during the previous call, try to
728 | * finish the possibly pending repeat in the dictionary.
729 | */
730 | if (dict_has_space(&s->dict) && s->lzma.len > 0)
731 | dict_repeat(&s->dict, &s->lzma.len, s->lzma.rep0);
732 |
733 | /*
734 | * Decode more LZMA symbols. One iteration may consume up to
735 | * LZMA_IN_REQUIRED - 1 bytes.
736 | */
737 | while (dict_has_space(&s->dict) && !rc_limit_exceeded(&s->rc)) {
738 | pos_state = s->dict.pos & s->lzma.pos_mask;
739 |
740 | if (!rc_bit(&s->rc, &s->lzma.is_match[
741 | s->lzma.state][pos_state])) {
742 | lzma_literal(s);
743 | } else {
744 | if (rc_bit(&s->rc, &s->lzma.is_rep[s->lzma.state]))
745 | lzma_rep_match(s, pos_state);
746 | else
747 | lzma_match(s, pos_state);
748 |
749 | if (!dict_repeat(&s->dict, &s->lzma.len, s->lzma.rep0))
750 | return false;
751 | }
752 | }
753 |
754 | /*
755 | * Having the range decoder always normalized when we are outside
756 | * this function makes it easier to correctly handle end of the chunk.
757 | */
758 | rc_normalize(&s->rc);
759 |
760 | return true;
761 | }
762 |
763 | /*
764 | * Reset the LZMA decoder and range decoder state. Dictionary is nore reset
765 | * here, because LZMA state may be reset without resetting the dictionary.
766 | */
767 | static void lzma_reset(struct xz_dec_lzma2 *s)
768 | {
769 | uint16_t *probs;
770 | size_t i;
771 |
772 | s->lzma.state = STATE_LIT_LIT;
773 | s->lzma.rep0 = 0;
774 | s->lzma.rep1 = 0;
775 | s->lzma.rep2 = 0;
776 | s->lzma.rep3 = 0;
777 |
778 | /*
779 | * All probabilities are initialized to the same value. This hack
780 | * makes the code smaller by avoiding a separate loop for each
781 | * probability array.
782 | *
783 | * This could be optimized so that only that part of literal
784 | * probabilities that are actually required. In the common case
785 | * we would write 12 KiB less.
786 | */
787 | probs = s->lzma.is_match[0];
788 | for (i = 0; i < PROBS_TOTAL; ++i)
789 | probs[i] = RC_BIT_MODEL_TOTAL / 2;
790 |
791 | rc_reset(&s->rc);
792 | }
793 |
794 | /*
795 | * Decode and validate LZMA properties (lc/lp/pb) and calculate the bit masks
796 | * from the decoded lp and pb values. On success, the LZMA decoder state is
797 | * reset and true is returned.
798 | */
799 | static bool lzma_props(struct xz_dec_lzma2 *s, uint8_t props)
800 | {
801 | if (props > (4 * 5 + 4) * 9 + 8)
802 | return false;
803 |
804 | s->lzma.pos_mask = 0;
805 | while (props >= 9 * 5) {
806 | props -= 9 * 5;
807 | ++s->lzma.pos_mask;
808 | }
809 |
810 | s->lzma.pos_mask = (1 << s->lzma.pos_mask) - 1;
811 |
812 | s->lzma.literal_pos_mask = 0;
813 | while (props >= 9) {
814 | props -= 9;
815 | ++s->lzma.literal_pos_mask;
816 | }
817 |
818 | s->lzma.lc = props;
819 |
820 | if (s->lzma.lc + s->lzma.literal_pos_mask > 4)
821 | return false;
822 |
823 | s->lzma.literal_pos_mask = (1 << s->lzma.literal_pos_mask) - 1;
824 |
825 | lzma_reset(s);
826 |
827 | return true;
828 | }
829 |
830 | /*********
831 | * LZMA2 *
832 | *********/
833 |
834 | /*
835 | * The LZMA decoder assumes that if the input limit (s->rc.in_limit) hasn't
836 | * been exceeded, it is safe to read up to LZMA_IN_REQUIRED bytes. This
837 | * wrapper function takes care of making the LZMA decoder's assumption safe.
838 | *
839 | * As long as there is plenty of input left to be decoded in the current LZMA
840 | * chunk, we decode directly from the caller-supplied input buffer until
841 | * there's LZMA_IN_REQUIRED bytes left. Those remaining bytes are copied into
842 | * s->temp.buf, which (hopefully) gets filled on the next call to this
843 | * function. We decode a few bytes from the temporary buffer so that we can
844 | * continue decoding from the caller-supplied input buffer again.
845 | */
846 | static bool lzma2_lzma(struct xz_dec_lzma2 *s, struct xz_buf *b)
847 | {
848 | size_t in_avail;
849 | uint32_t tmp;
850 |
851 | in_avail = b->in_size - b->in_pos;
852 | if (s->temp.size > 0 || s->lzma2.compressed == 0) {
853 | tmp = 2 * LZMA_IN_REQUIRED - s->temp.size;
854 | if (tmp > s->lzma2.compressed - s->temp.size)
855 | tmp = s->lzma2.compressed - s->temp.size;
856 | if (tmp > in_avail)
857 | tmp = in_avail;
858 |
859 | memcpy(s->temp.buf + s->temp.size, b->in + b->in_pos, tmp);
860 |
861 | if (s->temp.size + tmp == s->lzma2.compressed) {
862 | memzero(s->temp.buf + s->temp.size + tmp,
863 | sizeof(s->temp.buf)
864 | - s->temp.size - tmp);
865 | s->rc.in_limit = s->temp.size + tmp;
866 | } else if (s->temp.size + tmp < LZMA_IN_REQUIRED) {
867 | s->temp.size += tmp;
868 | b->in_pos += tmp;
869 | return true;
870 | } else {
871 | s->rc.in_limit = s->temp.size + tmp - LZMA_IN_REQUIRED;
872 | }
873 |
874 | s->rc.in = s->temp.buf;
875 | s->rc.in_pos = 0;
876 |
877 | if (!lzma_main(s) || s->rc.in_pos > s->temp.size + tmp)
878 | return false;
879 |
880 | s->lzma2.compressed -= s->rc.in_pos;
881 |
882 | if (s->rc.in_pos < s->temp.size) {
883 | s->temp.size -= s->rc.in_pos;
884 | memmove(s->temp.buf, s->temp.buf + s->rc.in_pos,
885 | s->temp.size);
886 | return true;
887 | }
888 |
889 | b->in_pos += s->rc.in_pos - s->temp.size;
890 | s->temp.size = 0;
891 | }
892 |
893 | in_avail = b->in_size - b->in_pos;
894 | if (in_avail >= LZMA_IN_REQUIRED) {
895 | s->rc.in = b->in;
896 | s->rc.in_pos = b->in_pos;
897 |
898 | if (in_avail >= s->lzma2.compressed + LZMA_IN_REQUIRED)
899 | s->rc.in_limit = b->in_pos + s->lzma2.compressed;
900 | else
901 | s->rc.in_limit = b->in_size - LZMA_IN_REQUIRED;
902 |
903 | if (!lzma_main(s))
904 | return false;
905 |
906 | in_avail = s->rc.in_pos - b->in_pos;
907 | if (in_avail > s->lzma2.compressed)
908 | return false;
909 |
910 | s->lzma2.compressed -= in_avail;
911 | b->in_pos = s->rc.in_pos;
912 | }
913 |
914 | in_avail = b->in_size - b->in_pos;
915 | if (in_avail < LZMA_IN_REQUIRED) {
916 | if (in_avail > s->lzma2.compressed)
917 | in_avail = s->lzma2.compressed;
918 |
919 | memcpy(s->temp.buf, b->in + b->in_pos, in_avail);
920 | s->temp.size = in_avail;
921 | b->in_pos += in_avail;
922 | }
923 |
924 | return true;
925 | }
926 |
927 | /*
928 | * Take care of the LZMA2 control layer, and forward the job of actual LZMA
929 | * decoding or copying of uncompressed chunks to other functions.
930 | */
931 | XZ_EXTERN enum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s,
932 | struct xz_buf *b)
933 | {
934 | uint32_t tmp;
935 |
936 | while (b->in_pos < b->in_size || s->lzma2.sequence == SEQ_LZMA_RUN) {
937 | switch (s->lzma2.sequence) {
938 | case SEQ_CONTROL:
939 | /*
940 | * LZMA2 control byte
941 | *
942 | * Exact values:
943 | * 0x00 End marker
944 | * 0x01 Dictionary reset followed by
945 | * an uncompressed chunk
946 | * 0x02 Uncompressed chunk (no dictionary reset)
947 | *
948 | * Highest three bits (s->control & 0xE0):
949 | * 0xE0 Dictionary reset, new properties and state
950 | * reset, followed by LZMA compressed chunk
951 | * 0xC0 New properties and state reset, followed
952 | * by LZMA compressed chunk (no dictionary
953 | * reset)
954 | * 0xA0 State reset using old properties,
955 | * followed by LZMA compressed chunk (no
956 | * dictionary reset)
957 | * 0x80 LZMA chunk (no dictionary or state reset)
958 | *
959 | * For LZMA compressed chunks, the lowest five bits
960 | * (s->control & 1F) are the highest bits of the
961 | * uncompressed size (bits 16-20).
962 | *
963 | * A new LZMA2 stream must begin with a dictionary
964 | * reset. The first LZMA chunk must set new
965 | * properties and reset the LZMA state.
966 | *
967 | * Values that don't match anything described above
968 | * are invalid and we return XZ_DATA_ERROR.
969 | */
970 | tmp = b->in[b->in_pos++];
971 |
972 | if (tmp == 0x00)
973 | return XZ_STREAM_END;
974 |
975 | if (tmp >= 0xE0 || tmp == 0x01) {
976 | s->lzma2.need_props = true;
977 | s->lzma2.need_dict_reset = false;
978 | dict_reset(&s->dict, b);
979 | } else if (s->lzma2.need_dict_reset) {
980 | return XZ_DATA_ERROR;
981 | }
982 |
983 | if (tmp >= 0x80) {
984 | s->lzma2.uncompressed = (tmp & 0x1F) << 16;
985 | s->lzma2.sequence = SEQ_UNCOMPRESSED_1;
986 |
987 | if (tmp >= 0xC0) {
988 | /*
989 | * When there are new properties,
990 | * state reset is done at
991 | * SEQ_PROPERTIES.
992 | */
993 | s->lzma2.need_props = false;
994 | s->lzma2.next_sequence
995 | = SEQ_PROPERTIES;
996 |
997 | } else if (s->lzma2.need_props) {
998 | return XZ_DATA_ERROR;
999 |
1000 | } else {
1001 | s->lzma2.next_sequence
1002 | = SEQ_LZMA_PREPARE;
1003 | if (tmp >= 0xA0)
1004 | lzma_reset(s);
1005 | }
1006 | } else {
1007 | if (tmp > 0x02)
1008 | return XZ_DATA_ERROR;
1009 |
1010 | s->lzma2.sequence = SEQ_COMPRESSED_0;
1011 | s->lzma2.next_sequence = SEQ_COPY;
1012 | }
1013 |
1014 | break;
1015 |
1016 | case SEQ_UNCOMPRESSED_1:
1017 | s->lzma2.uncompressed
1018 | += (uint32_t)b->in[b->in_pos++] << 8;
1019 | s->lzma2.sequence = SEQ_UNCOMPRESSED_2;
1020 | break;
1021 |
1022 | case SEQ_UNCOMPRESSED_2:
1023 | s->lzma2.uncompressed
1024 | += (uint32_t)b->in[b->in_pos++] + 1;
1025 | s->lzma2.sequence = SEQ_COMPRESSED_0;
1026 | break;
1027 |
1028 | case SEQ_COMPRESSED_0:
1029 | s->lzma2.compressed
1030 | = (uint32_t)b->in[b->in_pos++] << 8;
1031 | s->lzma2.sequence = SEQ_COMPRESSED_1;
1032 | break;
1033 |
1034 | case SEQ_COMPRESSED_1:
1035 | s->lzma2.compressed
1036 | += (uint32_t)b->in[b->in_pos++] + 1;
1037 | s->lzma2.sequence = s->lzma2.next_sequence;
1038 | break;
1039 |
1040 | case SEQ_PROPERTIES:
1041 | if (!lzma_props(s, b->in[b->in_pos++]))
1042 | return XZ_DATA_ERROR;
1043 |
1044 | s->lzma2.sequence = SEQ_LZMA_PREPARE;
1045 |
1046 | /* Fall through */
1047 |
1048 | case SEQ_LZMA_PREPARE:
1049 | if (s->lzma2.compressed < RC_INIT_BYTES)
1050 | return XZ_DATA_ERROR;
1051 |
1052 | if (!rc_read_init(&s->rc, b))
1053 | return XZ_OK;
1054 |
1055 | s->lzma2.compressed -= RC_INIT_BYTES;
1056 | s->lzma2.sequence = SEQ_LZMA_RUN;
1057 |
1058 | /* Fall through */
1059 |
1060 | case SEQ_LZMA_RUN:
1061 | /*
1062 | * Set dictionary limit to indicate how much we want
1063 | * to be encoded at maximum. Decode new data into the
1064 | * dictionary. Flush the new data from dictionary to
1065 | * b->out. Check if we finished decoding this chunk.
1066 | * In case the dictionary got full but we didn't fill
1067 | * the output buffer yet, we may run this loop
1068 | * multiple times without changing s->lzma2.sequence.
1069 | */
1070 | dict_limit(&s->dict, min_t(size_t,
1071 | b->out_size - b->out_pos,
1072 | s->lzma2.uncompressed));
1073 | if (!lzma2_lzma(s, b))
1074 | return XZ_DATA_ERROR;
1075 |
1076 | s->lzma2.uncompressed -= dict_flush(&s->dict, b);
1077 |
1078 | if (s->lzma2.uncompressed == 0) {
1079 | if (s->lzma2.compressed > 0 || s->lzma.len > 0
1080 | || !rc_is_finished(&s->rc))
1081 | return XZ_DATA_ERROR;
1082 |
1083 | rc_reset(&s->rc);
1084 | s->lzma2.sequence = SEQ_CONTROL;
1085 |
1086 | } else if (b->out_pos == b->out_size
1087 | || (b->in_pos == b->in_size
1088 | && s->temp.size
1089 | < s->lzma2.compressed)) {
1090 | return XZ_OK;
1091 | }
1092 |
1093 | break;
1094 |
1095 | case SEQ_COPY:
1096 | dict_uncompressed(&s->dict, b, &s->lzma2.compressed);
1097 | if (s->lzma2.compressed > 0)
1098 | return XZ_OK;
1099 |
1100 | s->lzma2.sequence = SEQ_CONTROL;
1101 | break;
1102 | }
1103 | }
1104 |
1105 | return XZ_OK;
1106 | }
1107 |
1108 | XZ_EXTERN struct xz_dec_lzma2 *xz_dec_lzma2_create(enum xz_mode mode,
1109 | uint32_t dict_max)
1110 | {
1111 | struct xz_dec_lzma2 *s = kmalloc(sizeof(*s), GFP_KERNEL);
1112 | if (s == NULL)
1113 | return NULL;
1114 |
1115 | s->dict.mode = mode;
1116 | s->dict.size_max = dict_max;
1117 |
1118 | if (DEC_IS_PREALLOC(mode)) {
1119 | s->dict.buf = vmalloc(dict_max);
1120 | if (s->dict.buf == NULL) {
1121 | kfree(s);
1122 | return NULL;
1123 | }
1124 | } else if (DEC_IS_DYNALLOC(mode)) {
1125 | s->dict.buf = NULL;
1126 | s->dict.allocated = 0;
1127 | }
1128 |
1129 | return s;
1130 | }
1131 |
1132 | XZ_EXTERN enum xz_ret xz_dec_lzma2_reset(struct xz_dec_lzma2 *s, uint8_t props)
1133 | {
1134 | /* This limits dictionary size to 3 GiB to keep parsing simpler. */
1135 | if (props > 39)
1136 | return XZ_OPTIONS_ERROR;
1137 |
1138 | s->dict.size = 2 + (props & 1);
1139 | s->dict.size <<= (props >> 1) + 11;
1140 |
1141 | if (DEC_IS_MULTI(s->dict.mode)) {
1142 | if (s->dict.size > s->dict.size_max)
1143 | return XZ_MEMLIMIT_ERROR;
1144 |
1145 | s->dict.end = s->dict.size;
1146 |
1147 | if (DEC_IS_DYNALLOC(s->dict.mode)) {
1148 | if (s->dict.allocated < s->dict.size) {
1149 | vfree(s->dict.buf);
1150 | s->dict.buf = vmalloc(s->dict.size);
1151 | if (s->dict.buf == NULL) {
1152 | s->dict.allocated = 0;
1153 | return XZ_MEM_ERROR;
1154 | }
1155 | }
1156 | }
1157 | }
1158 |
1159 | s->lzma.len = 0;
1160 |
1161 | s->lzma2.sequence = SEQ_CONTROL;
1162 | s->lzma2.need_dict_reset = true;
1163 |
1164 | s->temp.size = 0;
1165 |
1166 | return XZ_OK;
1167 | }
1168 |
1169 | XZ_EXTERN void xz_dec_lzma2_end(struct xz_dec_lzma2 *s)
1170 | {
1171 | if (DEC_IS_MULTI(s->dict.mode))
1172 | vfree(s->dict.buf);
1173 |
1174 | kfree(s);
1175 | }
1176 |
--------------------------------------------------------------------------------
/xz/xz_dec_stream.c:
--------------------------------------------------------------------------------
1 | /*
2 | * .xz Stream decoder
3 | *
4 | * Author: Lasse Collin
5 | *
6 | * This file has been put into the public domain.
7 | * You can do whatever you want with this file.
8 | */
9 |
10 | #include "xz_private.h"
11 | #include "xz_stream.h"
12 |
13 | #ifdef XZ_USE_CRC64
14 | # define IS_CRC64(check_type) ((check_type) == XZ_CHECK_CRC64)
15 | #else
16 | # define IS_CRC64(check_type) false
17 | #endif
18 |
19 | /* Hash used to validate the Index field */
20 | struct xz_dec_hash {
21 | vli_type unpadded;
22 | vli_type uncompressed;
23 | uint32_t crc32;
24 | };
25 |
26 | struct xz_dec {
27 | /* Position in dec_main() */
28 | enum {
29 | SEQ_STREAM_HEADER,
30 | SEQ_BLOCK_START,
31 | SEQ_BLOCK_HEADER,
32 | SEQ_BLOCK_UNCOMPRESS,
33 | SEQ_BLOCK_PADDING,
34 | SEQ_BLOCK_CHECK,
35 | SEQ_INDEX,
36 | SEQ_INDEX_PADDING,
37 | SEQ_INDEX_CRC32,
38 | SEQ_STREAM_FOOTER
39 | } sequence;
40 |
41 | /* Position in variable-length integers and Check fields */
42 | uint32_t pos;
43 |
44 | /* Variable-length integer decoded by dec_vli() */
45 | vli_type vli;
46 |
47 | /* Saved in_pos and out_pos */
48 | size_t in_start;
49 | size_t out_start;
50 |
51 | #ifdef XZ_USE_CRC64
52 | /* CRC32 or CRC64 value in Block or CRC32 value in Index */
53 | uint64_t crc;
54 | #else
55 | /* CRC32 value in Block or Index */
56 | uint32_t crc;
57 | #endif
58 |
59 | /* Type of the integrity check calculated from uncompressed data */
60 | enum xz_check check_type;
61 |
62 | /* Operation mode */
63 | enum xz_mode mode;
64 |
65 | /*
66 | * True if the next call to xz_dec_run() is allowed to return
67 | * XZ_BUF_ERROR.
68 | */
69 | bool allow_buf_error;
70 |
71 | /* Information stored in Block Header */
72 | struct {
73 | /*
74 | * Value stored in the Compressed Size field, or
75 | * VLI_UNKNOWN if Compressed Size is not present.
76 | */
77 | vli_type compressed;
78 |
79 | /*
80 | * Value stored in the Uncompressed Size field, or
81 | * VLI_UNKNOWN if Uncompressed Size is not present.
82 | */
83 | vli_type uncompressed;
84 |
85 | /* Size of the Block Header field */
86 | uint32_t size;
87 | } block_header;
88 |
89 | /* Information collected when decoding Blocks */
90 | struct {
91 | /* Observed compressed size of the current Block */
92 | vli_type compressed;
93 |
94 | /* Observed uncompressed size of the current Block */
95 | vli_type uncompressed;
96 |
97 | /* Number of Blocks decoded so far */
98 | vli_type count;
99 |
100 | /*
101 | * Hash calculated from the Block sizes. This is used to
102 | * validate the Index field.
103 | */
104 | struct xz_dec_hash hash;
105 | } block;
106 |
107 | /* Variables needed when verifying the Index field */
108 | struct {
109 | /* Position in dec_index() */
110 | enum {
111 | SEQ_INDEX_COUNT,
112 | SEQ_INDEX_UNPADDED,
113 | SEQ_INDEX_UNCOMPRESSED
114 | } sequence;
115 |
116 | /* Size of the Index in bytes */
117 | vli_type size;
118 |
119 | /* Number of Records (matches block.count in valid files) */
120 | vli_type count;
121 |
122 | /*
123 | * Hash calculated from the Records (matches block.hash in
124 | * valid files).
125 | */
126 | struct xz_dec_hash hash;
127 | } index;
128 |
129 | /*
130 | * Temporary buffer needed to hold Stream Header, Block Header,
131 | * and Stream Footer. The Block Header is the biggest (1 KiB)
132 | * so we reserve space according to that. buf[] has to be aligned
133 | * to a multiple of four bytes; the size_t variables before it
134 | * should guarantee this.
135 | */
136 | struct {
137 | size_t pos;
138 | size_t size;
139 | uint8_t buf[1024];
140 | } temp;
141 |
142 | struct xz_dec_lzma2 *lzma2;
143 |
144 | #ifdef XZ_DEC_BCJ
145 | struct xz_dec_bcj *bcj;
146 | bool bcj_active;
147 | #endif
148 | };
149 |
150 | #ifdef XZ_DEC_ANY_CHECK
151 | /* Sizes of the Check field with different Check IDs */
152 | static const uint8_t check_sizes[16] = {
153 | 0,
154 | 4, 4, 4,
155 | 8, 8, 8,
156 | 16, 16, 16,
157 | 32, 32, 32,
158 | 64, 64, 64
159 | };
160 | #endif
161 |
162 | /*
163 | * Fill s->temp by copying data starting from b->in[b->in_pos]. Caller
164 | * must have set s->temp.pos to indicate how much data we are supposed
165 | * to copy into s->temp.buf. Return true once s->temp.pos has reached
166 | * s->temp.size.
167 | */
168 | static bool fill_temp(struct xz_dec *s, struct xz_buf *b)
169 | {
170 | size_t copy_size = min_t(size_t,
171 | b->in_size - b->in_pos, s->temp.size - s->temp.pos);
172 |
173 | memcpy(s->temp.buf + s->temp.pos, b->in + b->in_pos, copy_size);
174 | b->in_pos += copy_size;
175 | s->temp.pos += copy_size;
176 |
177 | if (s->temp.pos == s->temp.size) {
178 | s->temp.pos = 0;
179 | return true;
180 | }
181 |
182 | return false;
183 | }
184 |
185 | /* Decode a variable-length integer (little-endian base-128 encoding) */
186 | static enum xz_ret dec_vli(struct xz_dec *s, const uint8_t *in,
187 | size_t *in_pos, size_t in_size)
188 | {
189 | uint8_t byte;
190 |
191 | if (s->pos == 0)
192 | s->vli = 0;
193 |
194 | while (*in_pos < in_size) {
195 | byte = in[*in_pos];
196 | ++*in_pos;
197 |
198 | s->vli |= (vli_type)(byte & 0x7F) << s->pos;
199 |
200 | if ((byte & 0x80) == 0) {
201 | /* Don't allow non-minimal encodings. */
202 | if (byte == 0 && s->pos != 0)
203 | return XZ_DATA_ERROR;
204 |
205 | s->pos = 0;
206 | return XZ_STREAM_END;
207 | }
208 |
209 | s->pos += 7;
210 | if (s->pos == 7 * VLI_BYTES_MAX)
211 | return XZ_DATA_ERROR;
212 | }
213 |
214 | return XZ_OK;
215 | }
216 |
217 | /*
218 | * Decode the Compressed Data field from a Block. Update and validate
219 | * the observed compressed and uncompressed sizes of the Block so that
220 | * they don't exceed the values possibly stored in the Block Header
221 | * (validation assumes that no integer overflow occurs, since vli_type
222 | * is normally uint64_t). Update the CRC32 or CRC64 value if presence of
223 | * the CRC32 or CRC64 field was indicated in Stream Header.
224 | *
225 | * Once the decoding is finished, validate that the observed sizes match
226 | * the sizes possibly stored in the Block Header. Update the hash and
227 | * Block count, which are later used to validate the Index field.
228 | */
229 | static enum xz_ret dec_block(struct xz_dec *s, struct xz_buf *b)
230 | {
231 | enum xz_ret ret;
232 |
233 | s->in_start = b->in_pos;
234 | s->out_start = b->out_pos;
235 |
236 | #ifdef XZ_DEC_BCJ
237 | if (s->bcj_active)
238 | ret = xz_dec_bcj_run(s->bcj, s->lzma2, b);
239 | else
240 | #endif
241 | ret = xz_dec_lzma2_run(s->lzma2, b);
242 |
243 | s->block.compressed += b->in_pos - s->in_start;
244 | s->block.uncompressed += b->out_pos - s->out_start;
245 |
246 | /*
247 | * There is no need to separately check for VLI_UNKNOWN, since
248 | * the observed sizes are always smaller than VLI_UNKNOWN.
249 | */
250 | if (s->block.compressed > s->block_header.compressed
251 | || s->block.uncompressed
252 | > s->block_header.uncompressed)
253 | return XZ_DATA_ERROR;
254 |
255 | if (s->check_type == XZ_CHECK_CRC32)
256 | s->crc = xz_crc32(b->out + s->out_start,
257 | b->out_pos - s->out_start, s->crc);
258 | #ifdef XZ_USE_CRC64
259 | else if (s->check_type == XZ_CHECK_CRC64)
260 | s->crc = xz_crc64(b->out + s->out_start,
261 | b->out_pos - s->out_start, s->crc);
262 | #endif
263 |
264 | if (ret == XZ_STREAM_END) {
265 | if (s->block_header.compressed != VLI_UNKNOWN
266 | && s->block_header.compressed
267 | != s->block.compressed)
268 | return XZ_DATA_ERROR;
269 |
270 | if (s->block_header.uncompressed != VLI_UNKNOWN
271 | && s->block_header.uncompressed
272 | != s->block.uncompressed)
273 | return XZ_DATA_ERROR;
274 |
275 | s->block.hash.unpadded += s->block_header.size
276 | + s->block.compressed;
277 |
278 | #ifdef XZ_DEC_ANY_CHECK
279 | s->block.hash.unpadded += check_sizes[s->check_type];
280 | #else
281 | if (s->check_type == XZ_CHECK_CRC32)
282 | s->block.hash.unpadded += 4;
283 | else if (IS_CRC64(s->check_type))
284 | s->block.hash.unpadded += 8;
285 | #endif
286 |
287 | s->block.hash.uncompressed += s->block.uncompressed;
288 | s->block.hash.crc32 = xz_crc32(
289 | (const uint8_t *)&s->block.hash,
290 | sizeof(s->block.hash), s->block.hash.crc32);
291 |
292 | ++s->block.count;
293 | }
294 |
295 | return ret;
296 | }
297 |
298 | /* Update the Index size and the CRC32 value. */
299 | static void index_update(struct xz_dec *s, const struct xz_buf *b)
300 | {
301 | size_t in_used = b->in_pos - s->in_start;
302 | s->index.size += in_used;
303 | s->crc = xz_crc32(b->in + s->in_start, in_used, s->crc);
304 | }
305 |
306 | /*
307 | * Decode the Number of Records, Unpadded Size, and Uncompressed Size
308 | * fields from the Index field. That is, Index Padding and CRC32 are not
309 | * decoded by this function.
310 | *
311 | * This can return XZ_OK (more input needed), XZ_STREAM_END (everything
312 | * successfully decoded), or XZ_DATA_ERROR (input is corrupt).
313 | */
314 | static enum xz_ret dec_index(struct xz_dec *s, struct xz_buf *b)
315 | {
316 | enum xz_ret ret;
317 |
318 | do {
319 | ret = dec_vli(s, b->in, &b->in_pos, b->in_size);
320 | if (ret != XZ_STREAM_END) {
321 | index_update(s, b);
322 | return ret;
323 | }
324 |
325 | switch (s->index.sequence) {
326 | case SEQ_INDEX_COUNT:
327 | s->index.count = s->vli;
328 |
329 | /*
330 | * Validate that the Number of Records field
331 | * indicates the same number of Records as
332 | * there were Blocks in the Stream.
333 | */
334 | if (s->index.count != s->block.count)
335 | return XZ_DATA_ERROR;
336 |
337 | s->index.sequence = SEQ_INDEX_UNPADDED;
338 | break;
339 |
340 | case SEQ_INDEX_UNPADDED:
341 | s->index.hash.unpadded += s->vli;
342 | s->index.sequence = SEQ_INDEX_UNCOMPRESSED;
343 | break;
344 |
345 | case SEQ_INDEX_UNCOMPRESSED:
346 | s->index.hash.uncompressed += s->vli;
347 | s->index.hash.crc32 = xz_crc32(
348 | (const uint8_t *)&s->index.hash,
349 | sizeof(s->index.hash),
350 | s->index.hash.crc32);
351 | --s->index.count;
352 | s->index.sequence = SEQ_INDEX_UNPADDED;
353 | break;
354 | }
355 | } while (s->index.count > 0);
356 |
357 | return XZ_STREAM_END;
358 | }
359 |
360 | /*
361 | * Validate that the next four or eight input bytes match the value
362 | * of s->crc. s->pos must be zero when starting to validate the first byte.
363 | * The "bits" argument allows using the same code for both CRC32 and CRC64.
364 | */
365 | static enum xz_ret crc_validate(struct xz_dec *s, struct xz_buf *b,
366 | uint32_t bits)
367 | {
368 | do {
369 | if (b->in_pos == b->in_size)
370 | return XZ_OK;
371 |
372 | if (((s->crc >> s->pos) & 0xFF) != b->in[b->in_pos++])
373 | return XZ_DATA_ERROR;
374 |
375 | s->pos += 8;
376 |
377 | } while (s->pos < bits);
378 |
379 | s->crc = 0;
380 | s->pos = 0;
381 |
382 | return XZ_STREAM_END;
383 | }
384 |
385 | #ifdef XZ_DEC_ANY_CHECK
386 | /*
387 | * Skip over the Check field when the Check ID is not supported.
388 | * Returns true once the whole Check field has been skipped over.
389 | */
390 | static bool check_skip(struct xz_dec *s, struct xz_buf *b)
391 | {
392 | while (s->pos < check_sizes[s->check_type]) {
393 | if (b->in_pos == b->in_size)
394 | return false;
395 |
396 | ++b->in_pos;
397 | ++s->pos;
398 | }
399 |
400 | s->pos = 0;
401 |
402 | return true;
403 | }
404 | #endif
405 |
406 | /* Decode the Stream Header field (the first 12 bytes of the .xz Stream). */
407 | static enum xz_ret dec_stream_header(struct xz_dec *s)
408 | {
409 | if (!memeq(s->temp.buf, HEADER_MAGIC, HEADER_MAGIC_SIZE))
410 | return XZ_FORMAT_ERROR;
411 |
412 | if (xz_crc32(s->temp.buf + HEADER_MAGIC_SIZE, 2, 0)
413 | != get_le32(s->temp.buf + HEADER_MAGIC_SIZE + 2))
414 | return XZ_DATA_ERROR;
415 |
416 | if (s->temp.buf[HEADER_MAGIC_SIZE] != 0)
417 | return XZ_OPTIONS_ERROR;
418 |
419 | /*
420 | * Of integrity checks, we support none (Check ID = 0),
421 | * CRC32 (Check ID = 1), and optionally CRC64 (Check ID = 4).
422 | * However, if XZ_DEC_ANY_CHECK is defined, we will accept other
423 | * check types too, but then the check won't be verified and
424 | * a warning (XZ_UNSUPPORTED_CHECK) will be given.
425 | */
426 | s->check_type = s->temp.buf[HEADER_MAGIC_SIZE + 1];
427 |
428 | #ifdef XZ_DEC_ANY_CHECK
429 | if (s->check_type > XZ_CHECK_MAX)
430 | return XZ_OPTIONS_ERROR;
431 |
432 | if (s->check_type > XZ_CHECK_CRC32 && !IS_CRC64(s->check_type))
433 | return XZ_UNSUPPORTED_CHECK;
434 | #else
435 | if (s->check_type > XZ_CHECK_CRC32 && !IS_CRC64(s->check_type))
436 | return XZ_OPTIONS_ERROR;
437 | #endif
438 |
439 | return XZ_OK;
440 | }
441 |
442 | /* Decode the Stream Footer field (the last 12 bytes of the .xz Stream) */
443 | static enum xz_ret dec_stream_footer(struct xz_dec *s)
444 | {
445 | if (!memeq(s->temp.buf + 10, FOOTER_MAGIC, FOOTER_MAGIC_SIZE))
446 | return XZ_DATA_ERROR;
447 |
448 | if (xz_crc32(s->temp.buf + 4, 6, 0) != get_le32(s->temp.buf))
449 | return XZ_DATA_ERROR;
450 |
451 | /*
452 | * Validate Backward Size. Note that we never added the size of the
453 | * Index CRC32 field to s->index.size, thus we use s->index.size / 4
454 | * instead of s->index.size / 4 - 1.
455 | */
456 | if ((s->index.size >> 2) != get_le32(s->temp.buf + 4))
457 | return XZ_DATA_ERROR;
458 |
459 | if (s->temp.buf[8] != 0 || s->temp.buf[9] != s->check_type)
460 | return XZ_DATA_ERROR;
461 |
462 | /*
463 | * Use XZ_STREAM_END instead of XZ_OK to be more convenient
464 | * for the caller.
465 | */
466 | return XZ_STREAM_END;
467 | }
468 |
469 | /* Decode the Block Header and initialize the filter chain. */
470 | static enum xz_ret dec_block_header(struct xz_dec *s)
471 | {
472 | enum xz_ret ret;
473 |
474 | /*
475 | * Validate the CRC32. We know that the temp buffer is at least
476 | * eight bytes so this is safe.
477 | */
478 | s->temp.size -= 4;
479 | if (xz_crc32(s->temp.buf, s->temp.size, 0)
480 | != get_le32(s->temp.buf + s->temp.size))
481 | return XZ_DATA_ERROR;
482 |
483 | s->temp.pos = 2;
484 |
485 | /*
486 | * Catch unsupported Block Flags. We support only one or two filters
487 | * in the chain, so we catch that with the same test.
488 | */
489 | #ifdef XZ_DEC_BCJ
490 | if (s->temp.buf[1] & 0x3E)
491 | #else
492 | if (s->temp.buf[1] & 0x3F)
493 | #endif
494 | return XZ_OPTIONS_ERROR;
495 |
496 | /* Compressed Size */
497 | if (s->temp.buf[1] & 0x40) {
498 | if (dec_vli(s, s->temp.buf, &s->temp.pos, s->temp.size)
499 | != XZ_STREAM_END)
500 | return XZ_DATA_ERROR;
501 |
502 | s->block_header.compressed = s->vli;
503 | } else {
504 | s->block_header.compressed = VLI_UNKNOWN;
505 | }
506 |
507 | /* Uncompressed Size */
508 | if (s->temp.buf[1] & 0x80) {
509 | if (dec_vli(s, s->temp.buf, &s->temp.pos, s->temp.size)
510 | != XZ_STREAM_END)
511 | return XZ_DATA_ERROR;
512 |
513 | s->block_header.uncompressed = s->vli;
514 | } else {
515 | s->block_header.uncompressed = VLI_UNKNOWN;
516 | }
517 |
518 | #ifdef XZ_DEC_BCJ
519 | /* If there are two filters, the first one must be a BCJ filter. */
520 | s->bcj_active = s->temp.buf[1] & 0x01;
521 | if (s->bcj_active) {
522 | if (s->temp.size - s->temp.pos < 2)
523 | return XZ_OPTIONS_ERROR;
524 |
525 | ret = xz_dec_bcj_reset(s->bcj, s->temp.buf[s->temp.pos++]);
526 | if (ret != XZ_OK)
527 | return ret;
528 |
529 | /*
530 | * We don't support custom start offset,
531 | * so Size of Properties must be zero.
532 | */
533 | if (s->temp.buf[s->temp.pos++] != 0x00)
534 | return XZ_OPTIONS_ERROR;
535 | }
536 | #endif
537 |
538 | /* Valid Filter Flags always take at least two bytes. */
539 | if (s->temp.size - s->temp.pos < 2)
540 | return XZ_DATA_ERROR;
541 |
542 | /* Filter ID = LZMA2 */
543 | if (s->temp.buf[s->temp.pos++] != 0x21)
544 | return XZ_OPTIONS_ERROR;
545 |
546 | /* Size of Properties = 1-byte Filter Properties */
547 | if (s->temp.buf[s->temp.pos++] != 0x01)
548 | return XZ_OPTIONS_ERROR;
549 |
550 | /* Filter Properties contains LZMA2 dictionary size. */
551 | if (s->temp.size - s->temp.pos < 1)
552 | return XZ_DATA_ERROR;
553 |
554 | ret = xz_dec_lzma2_reset(s->lzma2, s->temp.buf[s->temp.pos++]);
555 | if (ret != XZ_OK)
556 | return ret;
557 |
558 | /* The rest must be Header Padding. */
559 | while (s->temp.pos < s->temp.size)
560 | if (s->temp.buf[s->temp.pos++] != 0x00)
561 | return XZ_OPTIONS_ERROR;
562 |
563 | s->temp.pos = 0;
564 | s->block.compressed = 0;
565 | s->block.uncompressed = 0;
566 |
567 | return XZ_OK;
568 | }
569 |
570 | static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b)
571 | {
572 | enum xz_ret ret;
573 |
574 | /*
575 | * Store the start position for the case when we are in the middle
576 | * of the Index field.
577 | */
578 | s->in_start = b->in_pos;
579 |
580 | while (true) {
581 | switch (s->sequence) {
582 | case SEQ_STREAM_HEADER:
583 | /*
584 | * Stream Header is copied to s->temp, and then
585 | * decoded from there. This way if the caller
586 | * gives us only little input at a time, we can
587 | * still keep the Stream Header decoding code
588 | * simple. Similar approach is used in many places
589 | * in this file.
590 | */
591 | if (!fill_temp(s, b))
592 | return XZ_OK;
593 |
594 | /*
595 | * If dec_stream_header() returns
596 | * XZ_UNSUPPORTED_CHECK, it is still possible
597 | * to continue decoding if working in multi-call
598 | * mode. Thus, update s->sequence before calling
599 | * dec_stream_header().
600 | */
601 | s->sequence = SEQ_BLOCK_START;
602 |
603 | ret = dec_stream_header(s);
604 | if (ret != XZ_OK)
605 | return ret;
606 |
607 | case SEQ_BLOCK_START:
608 | /* We need one byte of input to continue. */
609 | if (b->in_pos == b->in_size)
610 | return XZ_OK;
611 |
612 | /* See if this is the beginning of the Index field. */
613 | if (b->in[b->in_pos] == 0) {
614 | s->in_start = b->in_pos++;
615 | s->sequence = SEQ_INDEX;
616 | break;
617 | }
618 |
619 | /*
620 | * Calculate the size of the Block Header and
621 | * prepare to decode it.
622 | */
623 | s->block_header.size
624 | = ((uint32_t)b->in[b->in_pos] + 1) * 4;
625 |
626 | s->temp.size = s->block_header.size;
627 | s->temp.pos = 0;
628 | s->sequence = SEQ_BLOCK_HEADER;
629 |
630 | case SEQ_BLOCK_HEADER:
631 | if (!fill_temp(s, b))
632 | return XZ_OK;
633 |
634 | ret = dec_block_header(s);
635 | if (ret != XZ_OK)
636 | return ret;
637 |
638 | s->sequence = SEQ_BLOCK_UNCOMPRESS;
639 |
640 | case SEQ_BLOCK_UNCOMPRESS:
641 | ret = dec_block(s, b);
642 | if (ret != XZ_STREAM_END)
643 | return ret;
644 |
645 | s->sequence = SEQ_BLOCK_PADDING;
646 |
647 | case SEQ_BLOCK_PADDING:
648 | /*
649 | * Size of Compressed Data + Block Padding
650 | * must be a multiple of four. We don't need
651 | * s->block.compressed for anything else
652 | * anymore, so we use it here to test the size
653 | * of the Block Padding field.
654 | */
655 | while (s->block.compressed & 3) {
656 | if (b->in_pos == b->in_size)
657 | return XZ_OK;
658 |
659 | if (b->in[b->in_pos++] != 0)
660 | return XZ_DATA_ERROR;
661 |
662 | ++s->block.compressed;
663 | }
664 |
665 | s->sequence = SEQ_BLOCK_CHECK;
666 |
667 | case SEQ_BLOCK_CHECK:
668 | if (s->check_type == XZ_CHECK_CRC32) {
669 | ret = crc_validate(s, b, 32);
670 | if (ret != XZ_STREAM_END)
671 | return ret;
672 | }
673 | else if (IS_CRC64(s->check_type)) {
674 | ret = crc_validate(s, b, 64);
675 | if (ret != XZ_STREAM_END)
676 | return ret;
677 | }
678 | #ifdef XZ_DEC_ANY_CHECK
679 | else if (!check_skip(s, b)) {
680 | return XZ_OK;
681 | }
682 | #endif
683 |
684 | s->sequence = SEQ_BLOCK_START;
685 | break;
686 |
687 | case SEQ_INDEX:
688 | ret = dec_index(s, b);
689 | if (ret != XZ_STREAM_END)
690 | return ret;
691 |
692 | s->sequence = SEQ_INDEX_PADDING;
693 |
694 | case SEQ_INDEX_PADDING:
695 | while ((s->index.size + (b->in_pos - s->in_start))
696 | & 3) {
697 | if (b->in_pos == b->in_size) {
698 | index_update(s, b);
699 | return XZ_OK;
700 | }
701 |
702 | if (b->in[b->in_pos++] != 0)
703 | return XZ_DATA_ERROR;
704 | }
705 |
706 | /* Finish the CRC32 value and Index size. */
707 | index_update(s, b);
708 |
709 | /* Compare the hashes to validate the Index field. */
710 | if (!memeq(&s->block.hash, &s->index.hash,
711 | sizeof(s->block.hash)))
712 | return XZ_DATA_ERROR;
713 |
714 | s->sequence = SEQ_INDEX_CRC32;
715 |
716 | case SEQ_INDEX_CRC32:
717 | ret = crc_validate(s, b, 32);
718 | if (ret != XZ_STREAM_END)
719 | return ret;
720 |
721 | s->temp.size = STREAM_HEADER_SIZE;
722 | s->sequence = SEQ_STREAM_FOOTER;
723 |
724 | case SEQ_STREAM_FOOTER:
725 | if (!fill_temp(s, b))
726 | return XZ_OK;
727 |
728 | return dec_stream_footer(s);
729 | }
730 | }
731 |
732 | /* Never reached */
733 | }
734 |
735 | /*
736 | * xz_dec_run() is a wrapper for dec_main() to handle some special cases in
737 | * multi-call and single-call decoding.
738 | *
739 | * In multi-call mode, we must return XZ_BUF_ERROR when it seems clear that we
740 | * are not going to make any progress anymore. This is to prevent the caller
741 | * from calling us infinitely when the input file is truncated or otherwise
742 | * corrupt. Since zlib-style API allows that the caller fills the input buffer
743 | * only when the decoder doesn't produce any new output, we have to be careful
744 | * to avoid returning XZ_BUF_ERROR too easily: XZ_BUF_ERROR is returned only
745 | * after the second consecutive call to xz_dec_run() that makes no progress.
746 | *
747 | * In single-call mode, if we couldn't decode everything and no error
748 | * occurred, either the input is truncated or the output buffer is too small.
749 | * Since we know that the last input byte never produces any output, we know
750 | * that if all the input was consumed and decoding wasn't finished, the file
751 | * must be corrupt. Otherwise the output buffer has to be too small or the
752 | * file is corrupt in a way that decoding it produces too big output.
753 | *
754 | * If single-call decoding fails, we reset b->in_pos and b->out_pos back to
755 | * their original values. This is because with some filter chains there won't
756 | * be any valid uncompressed data in the output buffer unless the decoding
757 | * actually succeeds (that's the price to pay of using the output buffer as
758 | * the workspace).
759 | */
760 | XZ_EXTERN enum xz_ret xz_dec_run(struct xz_dec *s, struct xz_buf *b)
761 | {
762 | size_t in_start;
763 | size_t out_start;
764 | enum xz_ret ret;
765 |
766 | if (DEC_IS_SINGLE(s->mode))
767 | xz_dec_reset(s);
768 |
769 | in_start = b->in_pos;
770 | out_start = b->out_pos;
771 | ret = dec_main(s, b);
772 |
773 | if (DEC_IS_SINGLE(s->mode)) {
774 | if (ret == XZ_OK)
775 | ret = b->in_pos == b->in_size
776 | ? XZ_DATA_ERROR : XZ_BUF_ERROR;
777 |
778 | if (ret != XZ_STREAM_END) {
779 | b->in_pos = in_start;
780 | b->out_pos = out_start;
781 | }
782 |
783 | } else if (ret == XZ_OK && in_start == b->in_pos
784 | && out_start == b->out_pos) {
785 | if (s->allow_buf_error)
786 | ret = XZ_BUF_ERROR;
787 |
788 | s->allow_buf_error = true;
789 | } else {
790 | s->allow_buf_error = false;
791 | }
792 |
793 | return ret;
794 | }
795 |
796 | XZ_EXTERN struct xz_dec *xz_dec_init(enum xz_mode mode, uint32_t dict_max)
797 | {
798 | struct xz_dec *s = kmalloc(sizeof(*s), GFP_KERNEL);
799 | if (s == NULL)
800 | return NULL;
801 |
802 | s->mode = mode;
803 |
804 | #ifdef XZ_DEC_BCJ
805 | s->bcj = xz_dec_bcj_create(DEC_IS_SINGLE(mode));
806 | if (s->bcj == NULL)
807 | goto error_bcj;
808 | #endif
809 |
810 | s->lzma2 = xz_dec_lzma2_create(mode, dict_max);
811 | if (s->lzma2 == NULL)
812 | goto error_lzma2;
813 |
814 | xz_dec_reset(s);
815 | return s;
816 |
817 | error_lzma2:
818 | #ifdef XZ_DEC_BCJ
819 | xz_dec_bcj_end(s->bcj);
820 | error_bcj:
821 | #endif
822 | kfree(s);
823 | return NULL;
824 | }
825 |
826 | XZ_EXTERN void xz_dec_reset(struct xz_dec *s)
827 | {
828 | s->sequence = SEQ_STREAM_HEADER;
829 | s->allow_buf_error = false;
830 | s->pos = 0;
831 | s->crc = 0;
832 | memzero(&s->block, sizeof(s->block));
833 | memzero(&s->index, sizeof(s->index));
834 | s->temp.pos = 0;
835 | s->temp.size = STREAM_HEADER_SIZE;
836 | }
837 |
838 | XZ_EXTERN void xz_dec_end(struct xz_dec *s)
839 | {
840 | if (s != NULL) {
841 | xz_dec_lzma2_end(s->lzma2);
842 | #ifdef XZ_DEC_BCJ
843 | xz_dec_bcj_end(s->bcj);
844 | #endif
845 | kfree(s);
846 | }
847 | }
848 |
--------------------------------------------------------------------------------
/xz/xz_lzma2.h:
--------------------------------------------------------------------------------
1 | /*
2 | * LZMA2 definitions
3 | *
4 | * Authors: Lasse Collin
5 | * Igor Pavlov
6 | *
7 | * This file has been put into the public domain.
8 | * You can do whatever you want with this file.
9 | */
10 |
11 | #ifndef XZ_LZMA2_H
12 | #define XZ_LZMA2_H
13 |
14 | /* Range coder constants */
15 | #define RC_SHIFT_BITS 8
16 | #define RC_TOP_BITS 24
17 | #define RC_TOP_VALUE (1 << RC_TOP_BITS)
18 | #define RC_BIT_MODEL_TOTAL_BITS 11
19 | #define RC_BIT_MODEL_TOTAL (1 << RC_BIT_MODEL_TOTAL_BITS)
20 | #define RC_MOVE_BITS 5
21 |
22 | /*
23 | * Maximum number of position states. A position state is the lowest pb
24 | * number of bits of the current uncompressed offset. In some places there
25 | * are different sets of probabilities for different position states.
26 | */
27 | #define POS_STATES_MAX (1 << 4)
28 |
29 | /*
30 | * This enum is used to track which LZMA symbols have occurred most recently
31 | * and in which order. This information is used to predict the next symbol.
32 | *
33 | * Symbols:
34 | * - Literal: One 8-bit byte
35 | * - Match: Repeat a chunk of data at some distance
36 | * - Long repeat: Multi-byte match at a recently seen distance
37 | * - Short repeat: One-byte repeat at a recently seen distance
38 | *
39 | * The symbol names are in from STATE_oldest_older_previous. REP means
40 | * either short or long repeated match, and NONLIT means any non-literal.
41 | */
42 | enum lzma_state {
43 | STATE_LIT_LIT,
44 | STATE_MATCH_LIT_LIT,
45 | STATE_REP_LIT_LIT,
46 | STATE_SHORTREP_LIT_LIT,
47 | STATE_MATCH_LIT,
48 | STATE_REP_LIT,
49 | STATE_SHORTREP_LIT,
50 | STATE_LIT_MATCH,
51 | STATE_LIT_LONGREP,
52 | STATE_LIT_SHORTREP,
53 | STATE_NONLIT_MATCH,
54 | STATE_NONLIT_REP
55 | };
56 |
57 | /* Total number of states */
58 | #define STATES 12
59 |
60 | /* The lowest 7 states indicate that the previous state was a literal. */
61 | #define LIT_STATES 7
62 |
63 | /* Indicate that the latest symbol was a literal. */
64 | static inline void lzma_state_literal(enum lzma_state *state)
65 | {
66 | if (*state <= STATE_SHORTREP_LIT_LIT)
67 | *state = STATE_LIT_LIT;
68 | else if (*state <= STATE_LIT_SHORTREP)
69 | *state -= 3;
70 | else
71 | *state -= 6;
72 | }
73 |
74 | /* Indicate that the latest symbol was a match. */
75 | static inline void lzma_state_match(enum lzma_state *state)
76 | {
77 | *state = *state < LIT_STATES ? STATE_LIT_MATCH : STATE_NONLIT_MATCH;
78 | }
79 |
80 | /* Indicate that the latest state was a long repeated match. */
81 | static inline void lzma_state_long_rep(enum lzma_state *state)
82 | {
83 | *state = *state < LIT_STATES ? STATE_LIT_LONGREP : STATE_NONLIT_REP;
84 | }
85 |
86 | /* Indicate that the latest symbol was a short match. */
87 | static inline void lzma_state_short_rep(enum lzma_state *state)
88 | {
89 | *state = *state < LIT_STATES ? STATE_LIT_SHORTREP : STATE_NONLIT_REP;
90 | }
91 |
92 | /* Test if the previous symbol was a literal. */
93 | static inline bool lzma_state_is_literal(enum lzma_state state)
94 | {
95 | return state < LIT_STATES;
96 | }
97 |
98 | /* Each literal coder is divided in three sections:
99 | * - 0x001-0x0FF: Without match byte
100 | * - 0x101-0x1FF: With match byte; match bit is 0
101 | * - 0x201-0x2FF: With match byte; match bit is 1
102 | *
103 | * Match byte is used when the previous LZMA symbol was something else than
104 | * a literal (that is, it was some kind of match).
105 | */
106 | #define LITERAL_CODER_SIZE 0x300
107 |
108 | /* Maximum number of literal coders */
109 | #define LITERAL_CODERS_MAX (1 << 4)
110 |
111 | /* Minimum length of a match is two bytes. */
112 | #define MATCH_LEN_MIN 2
113 |
114 | /* Match length is encoded with 4, 5, or 10 bits.
115 | *
116 | * Length Bits
117 | * 2-9 4 = Choice=0 + 3 bits
118 | * 10-17 5 = Choice=1 + Choice2=0 + 3 bits
119 | * 18-273 10 = Choice=1 + Choice2=1 + 8 bits
120 | */
121 | #define LEN_LOW_BITS 3
122 | #define LEN_LOW_SYMBOLS (1 << LEN_LOW_BITS)
123 | #define LEN_MID_BITS 3
124 | #define LEN_MID_SYMBOLS (1 << LEN_MID_BITS)
125 | #define LEN_HIGH_BITS 8
126 | #define LEN_HIGH_SYMBOLS (1 << LEN_HIGH_BITS)
127 | #define LEN_SYMBOLS (LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS + LEN_HIGH_SYMBOLS)
128 |
129 | /*
130 | * Maximum length of a match is 273 which is a result of the encoding
131 | * described above.
132 | */
133 | #define MATCH_LEN_MAX (MATCH_LEN_MIN + LEN_SYMBOLS - 1)
134 |
135 | /*
136 | * Different sets of probabilities are used for match distances that have
137 | * very short match length: Lengths of 2, 3, and 4 bytes have a separate
138 | * set of probabilities for each length. The matches with longer length
139 | * use a shared set of probabilities.
140 | */
141 | #define DIST_STATES 4
142 |
143 | /*
144 | * Get the index of the appropriate probability array for decoding
145 | * the distance slot.
146 | */
147 | static inline uint32_t lzma_get_dist_state(uint32_t len)
148 | {
149 | return len < DIST_STATES + MATCH_LEN_MIN
150 | ? len - MATCH_LEN_MIN : DIST_STATES - 1;
151 | }
152 |
153 | /*
154 | * The highest two bits of a 32-bit match distance are encoded using six bits.
155 | * This six-bit value is called a distance slot. This way encoding a 32-bit
156 | * value takes 6-36 bits, larger values taking more bits.
157 | */
158 | #define DIST_SLOT_BITS 6
159 | #define DIST_SLOTS (1 << DIST_SLOT_BITS)
160 |
161 | /* Match distances up to 127 are fully encoded using probabilities. Since
162 | * the highest two bits (distance slot) are always encoded using six bits,
163 | * the distances 0-3 don't need any additional bits to encode, since the
164 | * distance slot itself is the same as the actual distance. DIST_MODEL_START
165 | * indicates the first distance slot where at least one additional bit is
166 | * needed.
167 | */
168 | #define DIST_MODEL_START 4
169 |
170 | /*
171 | * Match distances greater than 127 are encoded in three pieces:
172 | * - distance slot: the highest two bits
173 | * - direct bits: 2-26 bits below the highest two bits
174 | * - alignment bits: four lowest bits
175 | *
176 | * Direct bits don't use any probabilities.
177 | *
178 | * The distance slot value of 14 is for distances 128-191.
179 | */
180 | #define DIST_MODEL_END 14
181 |
182 | /* Distance slots that indicate a distance <= 127. */
183 | #define FULL_DISTANCES_BITS (DIST_MODEL_END / 2)
184 | #define FULL_DISTANCES (1 << FULL_DISTANCES_BITS)
185 |
186 | /*
187 | * For match distances greater than 127, only the highest two bits and the
188 | * lowest four bits (alignment) is encoded using probabilities.
189 | */
190 | #define ALIGN_BITS 4
191 | #define ALIGN_SIZE (1 << ALIGN_BITS)
192 | #define ALIGN_MASK (ALIGN_SIZE - 1)
193 |
194 | /* Total number of all probability variables */
195 | #define PROBS_TOTAL (1846 + LITERAL_CODERS_MAX * LITERAL_CODER_SIZE)
196 |
197 | /*
198 | * LZMA remembers the four most recent match distances. Reusing these
199 | * distances tends to take less space than re-encoding the actual
200 | * distance value.
201 | */
202 | #define REPS 4
203 |
204 | #endif
205 |
--------------------------------------------------------------------------------
/xz/xz_private.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Private includes and definitions
3 | *
4 | * Author: Lasse Collin
5 | *
6 | * This file has been put into the public domain.
7 | * You can do whatever you want with this file.
8 | */
9 |
10 | #ifndef XZ_PRIVATE_H
11 | #define XZ_PRIVATE_H
12 |
13 | #ifdef __KERNEL__
14 | # include
15 | # include
16 | # include
17 | /* XZ_PREBOOT may be defined only via decompress_unxz.c. */
18 | # ifndef XZ_PREBOOT
19 | # include
20 | # include
21 | # include
22 | # ifdef CONFIG_XZ_DEC_X86
23 | # define XZ_DEC_X86
24 | # endif
25 | # ifdef CONFIG_XZ_DEC_POWERPC
26 | # define XZ_DEC_POWERPC
27 | # endif
28 | # ifdef CONFIG_XZ_DEC_IA64
29 | # define XZ_DEC_IA64
30 | # endif
31 | # ifdef CONFIG_XZ_DEC_ARM
32 | # define XZ_DEC_ARM
33 | # endif
34 | # ifdef CONFIG_XZ_DEC_ARMTHUMB
35 | # define XZ_DEC_ARMTHUMB
36 | # endif
37 | # ifdef CONFIG_XZ_DEC_SPARC
38 | # define XZ_DEC_SPARC
39 | # endif
40 | # define memeq(a, b, size) (memcmp(a, b, size) == 0)
41 | # define memzero(buf, size) memset(buf, 0, size)
42 | # endif
43 | # define get_le32(p) le32_to_cpup((const uint32_t *)(p))
44 | #else
45 | /*
46 | * For userspace builds, use a separate header to define the required
47 | * macros and functions. This makes it easier to adapt the code into
48 | * different environments and avoids clutter in the Linux kernel tree.
49 | */
50 | # include "xz_config.h"
51 | #endif
52 |
53 | /* If no specific decoding mode is requested, enable support for all modes. */
54 | #if !defined(XZ_DEC_SINGLE) && !defined(XZ_DEC_PREALLOC) \
55 | && !defined(XZ_DEC_DYNALLOC)
56 | # define XZ_DEC_SINGLE
57 | # define XZ_DEC_PREALLOC
58 | # define XZ_DEC_DYNALLOC
59 | #endif
60 |
61 | /*
62 | * The DEC_IS_foo(mode) macros are used in "if" statements. If only some
63 | * of the supported modes are enabled, these macros will evaluate to true or
64 | * false at compile time and thus allow the compiler to omit unneeded code.
65 | */
66 | #ifdef XZ_DEC_SINGLE
67 | # define DEC_IS_SINGLE(mode) ((mode) == XZ_SINGLE)
68 | #else
69 | # define DEC_IS_SINGLE(mode) (false)
70 | #endif
71 |
72 | #ifdef XZ_DEC_PREALLOC
73 | # define DEC_IS_PREALLOC(mode) ((mode) == XZ_PREALLOC)
74 | #else
75 | # define DEC_IS_PREALLOC(mode) (false)
76 | #endif
77 |
78 | #ifdef XZ_DEC_DYNALLOC
79 | # define DEC_IS_DYNALLOC(mode) ((mode) == XZ_DYNALLOC)
80 | #else
81 | # define DEC_IS_DYNALLOC(mode) (false)
82 | #endif
83 |
84 | #if !defined(XZ_DEC_SINGLE)
85 | # define DEC_IS_MULTI(mode) (true)
86 | #elif defined(XZ_DEC_PREALLOC) || defined(XZ_DEC_DYNALLOC)
87 | # define DEC_IS_MULTI(mode) ((mode) != XZ_SINGLE)
88 | #else
89 | # define DEC_IS_MULTI(mode) (false)
90 | #endif
91 |
92 | /*
93 | * If any of the BCJ filter decoders are wanted, define XZ_DEC_BCJ.
94 | * XZ_DEC_BCJ is used to enable generic support for BCJ decoders.
95 | */
96 | #ifndef XZ_DEC_BCJ
97 | # if defined(XZ_DEC_X86) || defined(XZ_DEC_POWERPC) \
98 | || defined(XZ_DEC_IA64) || defined(XZ_DEC_ARM) \
99 | || defined(XZ_DEC_ARM) || defined(XZ_DEC_ARMTHUMB) \
100 | || defined(XZ_DEC_SPARC)
101 | # define XZ_DEC_BCJ
102 | # endif
103 | #endif
104 |
105 | /*
106 | * Allocate memory for LZMA2 decoder. xz_dec_lzma2_reset() must be used
107 | * before calling xz_dec_lzma2_run().
108 | */
109 | XZ_EXTERN struct xz_dec_lzma2 *xz_dec_lzma2_create(enum xz_mode mode,
110 | uint32_t dict_max);
111 |
112 | /*
113 | * Decode the LZMA2 properties (one byte) and reset the decoder. Return
114 | * XZ_OK on success, XZ_MEMLIMIT_ERROR if the preallocated dictionary is not
115 | * big enough, and XZ_OPTIONS_ERROR if props indicates something that this
116 | * decoder doesn't support.
117 | */
118 | XZ_EXTERN enum xz_ret xz_dec_lzma2_reset(struct xz_dec_lzma2 *s,
119 | uint8_t props);
120 |
121 | /* Decode raw LZMA2 stream from b->in to b->out. */
122 | XZ_EXTERN enum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s,
123 | struct xz_buf *b);
124 |
125 | /* Free the memory allocated for the LZMA2 decoder. */
126 | XZ_EXTERN void xz_dec_lzma2_end(struct xz_dec_lzma2 *s);
127 |
128 | #ifdef XZ_DEC_BCJ
129 | /*
130 | * Allocate memory for BCJ decoders. xz_dec_bcj_reset() must be used before
131 | * calling xz_dec_bcj_run().
132 | */
133 | XZ_EXTERN struct xz_dec_bcj *xz_dec_bcj_create(bool single_call);
134 |
135 | /*
136 | * Decode the Filter ID of a BCJ filter. This implementation doesn't
137 | * support custom start offsets, so no decoding of Filter Properties
138 | * is needed. Returns XZ_OK if the given Filter ID is supported.
139 | * Otherwise XZ_OPTIONS_ERROR is returned.
140 | */
141 | XZ_EXTERN enum xz_ret xz_dec_bcj_reset(struct xz_dec_bcj *s, uint8_t id);
142 |
143 | /*
144 | * Decode raw BCJ + LZMA2 stream. This must be used only if there actually is
145 | * a BCJ filter in the chain. If the chain has only LZMA2, xz_dec_lzma2_run()
146 | * must be called directly.
147 | */
148 | XZ_EXTERN enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s,
149 | struct xz_dec_lzma2 *lzma2,
150 | struct xz_buf *b);
151 |
152 | /* Free the memory allocated for the BCJ filters. */
153 | #define xz_dec_bcj_end(s) kfree(s)
154 | #endif
155 |
156 | #endif
157 |
--------------------------------------------------------------------------------
/xz/xz_stream.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Definitions for handling the .xz file format
3 | *
4 | * Author: Lasse Collin
5 | *
6 | * This file has been put into the public domain.
7 | * You can do whatever you want with this file.
8 | */
9 |
10 | #ifndef XZ_STREAM_H
11 | #define XZ_STREAM_H
12 |
13 | #if defined(__KERNEL__) && !XZ_INTERNAL_CRC32
14 | # include
15 | # undef crc32
16 | # define xz_crc32(buf, size, crc) \
17 | (~crc32_le(~(uint32_t)(crc), buf, size))
18 | #endif
19 |
20 | /*
21 | * See the .xz file format specification at
22 | * http://tukaani.org/xz/xz-file-format.txt
23 | * to understand the container format.
24 | */
25 |
26 | #define STREAM_HEADER_SIZE 12
27 |
28 | #define HEADER_MAGIC "\3757zXZ"
29 | #define HEADER_MAGIC_SIZE 6
30 |
31 | #define FOOTER_MAGIC "YZ"
32 | #define FOOTER_MAGIC_SIZE 2
33 |
34 | /*
35 | * Variable-length integer can hold a 63-bit unsigned integer or a special
36 | * value indicating that the value is unknown.
37 | *
38 | * Experimental: vli_type can be defined to uint32_t to save a few bytes
39 | * in code size (no effect on speed). Doing so limits the uncompressed and
40 | * compressed size of the file to less than 256 MiB and may also weaken
41 | * error detection slightly.
42 | */
43 | typedef uint64_t vli_type;
44 |
45 | #define VLI_MAX ((vli_type)-1 / 2)
46 | #define VLI_UNKNOWN ((vli_type)-1)
47 |
48 | /* Maximum encoded size of a VLI */
49 | #define VLI_BYTES_MAX (sizeof(vli_type) * 8 / 7)
50 |
51 | /* Integrity Check types */
52 | enum xz_check {
53 | XZ_CHECK_NONE = 0,
54 | XZ_CHECK_CRC32 = 1,
55 | XZ_CHECK_CRC64 = 4,
56 | XZ_CHECK_SHA256 = 10
57 | };
58 |
59 | /* Maximum possible Check ID */
60 | #define XZ_CHECK_MAX 15
61 |
62 | #endif
63 |
--------------------------------------------------------------------------------