ReactOS 0.4.15-dev-7788-g1ad9096
chmc.c
Go to the documentation of this file.
1/*
2
3 Copyright(C) 2010 Alex Andreotti <alex.andreotti@gmail.com>
4
5 This file is part of chmc.
6
7 chmc is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 chmc is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with chmc. If not, see <http://www.gnu.org/licenses/>.
19
20*/
21#include "chmc.h"
22
23#include <fcntl.h>
24
25#include <errno.h>
26#include <string.h>
27#include <assert.h>
28
29#include <stdlib.h>
30#include <sys/types.h>
31#include <sys/stat.h>
32#include "../../port/port.h"
33
34#ifdef _WIN32
35 #include <io.h>
36#else
37 #include <unistd.h>
38#endif
39
40#include "err.h"
41
42
43#include "encint.h"
44
45#include <stdint.h>
46#include "../lzx_compress/lzx_config.h"
47#include "../lzx_compress/lzx_compress.h"
48
49#define PACKAGE_STRING "hhpcomp development version"
50
51/* if O_BINARY is not defined, the system is probably not expecting any such flag */
52#ifndef O_BINARY
53#define O_BINARY 0
54#endif
55
56int chmc_section_add(struct chmcFile *chm, const char *name);
57struct chmcSection * chmc_section_create(struct chmcFile *chm,
58 const char *name);
59void chmc_reset_table_init(struct chmcLzxcResetTable *reset_table);
61int chmc_namelist_create(struct chmcFile *chm, int len);
62struct chmcTreeNode * chmc_add_meta(struct chmcFile *chm,
63 const char *metaname, int sect_id,
65struct chmcTreeNode *chmc_add_entry(struct chmcFile *chm, const char *name,
68void chmc_sections_free(struct chmcFile *chm);
70void chmc_pmgi_free(struct chmcFile *chm);
71void chmc_pmgl_free(struct chmcFile *chm);
74void chmc_entries_free(struct chmcFile *chm);
76int chmc_add_tree(struct chmcFile *chm, const char *dir);
77struct chmcTreeNode *chmc_add_file(struct chmcFile *chm, const char *filename,
79 UInt64 len);
80struct chmcTreeNode *chmc_add_dir(struct chmcFile *chm, const char *dir);
81struct chmcTreeNode *chmc_add_empty(struct chmcFile *chm, const char *file);
82
83int chmc_crunch_lzx(struct chmcFile *chm, int sect_id);
84static int _lzx_at_eof(void *arg);
85static int _lzx_put_bytes(void *arg, int n, void *buf);
86static void _lzx_mark_frame(void *arg, uint32_t uncomp, uint32_t comp);
87static int _lzx_get_bytes(void *arg, int n, void *buf);
88
89int chmc_compressed_add_mark(struct chmcFile *chm, UInt64 at);
90int chmc_control_data_done(struct chmcFile *chm);
91int chmc_reset_table_done(struct chmcFile *chm);
92void chmc_pmgl_done(struct chmcFile *chm);
93
94void chmc_entries_qsort(struct chmcFile *chm);
95static int _entry_cmp(const void *pva, const void *pvb);
96
97struct chmcSection *chmc_section_lookup(struct chmcFile *chm, int id);
98
100void chmc_pmgl_add(struct chmcFile *chm, struct chmcPmglChunkNode *pmgl);
102int chmc_pmgi_add_entry(struct chmcFile *chm, const char *name, int pmgl_id);
103void chmc_pmgi_add(struct chmcFile *chm, struct chmcPmgiChunkNode *pmgi);
105
106#ifdef __REACTOS__
107int chmc_uncompressed_done(struct chmcFile *chm);
108int chmc_pmgi_done(struct chmcFile *chm);
109int chmc_write(struct chmcFile *chm);
110int chmc_appendfile(struct chmcFile *chm, const char *filename, void *buf,
111 size_t size );
112int chmc_pmgl_add_entry(struct chmcFile *chm, struct chmcTreeNode *entry);
113#endif /* __REACTOS__ */
114
116{
117 struct chmcFile *chm;
119 int fd;
123 struct list_head *pos;
124 int error;
125 int eof;
126};
127
128static const short chmc_transform_list[] = {
129 0x7b, 0x37, 0x46, 0x43, 0x32, 0x38, 0x39,
130 0x34, 0x30, 0x2d, 0x39, 0x44, 0x33, 0x31,
131 0x2d, 0x31, 0x31, 0x44, 0x30 };
132
133int chmc_init(struct chmcFile *chm, const char *filename,
134 struct chmcConfig *config)
135{
136 struct chmcItsfHeader *itsf = &chm->itsf;
137 struct chmcSect0 *sect0 = &chm->sect0;
138 struct chmcItspHeader *itsp = &chm->itsp;
139 struct chmcSystem *system = &chm->system;
140 struct chmcSystemInfo *sysinfo = &chm->system.info;
141 struct chmcIndexHeader *idxhdr = &chm->idxhdr;
142
143 assert(chm);
145
147
148 memset(chm, 0, sizeof(struct chmcFile));
149
150 chm->config = config;
151
152 if (strcmp(filename, "-") != 0) {
153 chm->fd = open(filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0644);
154 if (chm->fd < 0) {
156 chmcerr_return_msg("creat file '%s'", filename);
157 }
158 } else {
159 chm->fd = fileno(stdout);
160 }
161
162 memcpy(itsf->signature, "ITSF", 4);
163 itsf->version = 3;
165 itsf->unknown_000c = 1;
166
167 itsf->lang_id = chm->config->language;
168 memcpy(itsf->dir_uuid, CHMC_DIR_UUID, 16);
171
174
178
179 sect0->unknown_0000 = 510;
180
181 memcpy(itsp->signature, "ITSP", 4);
182 itsp->version = 1;
184 itsp->unknown_000c = 10;
187 itsp->index_depth = 2;
188
189 itsp->unknown_0028 = -1;
193 memset(itsp->unknown_0048, -1, 12);
194
195 system->version = 3;
196 system->_size = _CHMC_SYSTEM_HDR_LEN + sizeof(struct chmcIndexHeader);
197
199
200 memcpy(idxhdr->signature, "T#SM", 4);
201 idxhdr->unknown_4 = 28582569; // FIXME got from some chm
202 idxhdr->unknown_8 = 1;
203 // idxhdr->full_search = 1;
204 // idxhdr->klinks = 1;
205 // idxhdr->alinks = 0;
206 // idxhdr->timestamp = ???;
207
208 // idxhdr->num_of_topic = 2; // sorry??
209 idxhdr->off_img_list = -1;
210 // idxhdr->img_type_folder;
211 idxhdr->background = -1;
212 idxhdr->foreground = -1;
213 idxhdr->off_font = -1;
214 idxhdr->win_style = -1;
215 idxhdr->ex_win_style = -1;
216 idxhdr->unknown_34 = -1;
217 idxhdr->off_frame_name = -1;
218 idxhdr->off_win_name = -1;
219 // idxhdr->num_of_info;
220 idxhdr->unknown_44 = 1;
221 // idxhdr->num_of_merge_files;
222 // idxhdr->unknown_4c;
223
228
229 chm->strings = malloc(4096);
230 memset(chm->strings, 0, 4096);
231 chm->strings_len = 4096;
232 chm->strings_offset = 1;
233
234 if (chmc_section_add(chm, "Uncompressed") != CHMC_NOERR)
235 chmcerr_return_msg("adding section: Uncompressed");
236
237 if (chmc_section_add(chm, "MSCompressed") != CHMC_NOERR)
238 chmcerr_return_msg("adding section: MSCompressed");
239
241
242 return CHMC_NOERR;
243}
244
245int chmc_section_add(struct chmcFile *chm, const char *name)
246{
247 struct chmcSection *section;
248
249 assert(chm);
250 assert(name);
251
253 if (!section)
254 return chmcerr_code();
255
256 list_add_tail(&section->list, &chm->sections_list);
257 chm->sections_num++;
258
259 return CHMC_NOERR;
260}
261
263 const char *name)
264{
265 struct chmcSection *section;
266
267 assert(name);
268
269 section = calloc(1, sizeof(struct chmcSection));
270 if (section) {
271 const char *tmpdir;
272 int len;
273
274 len = strlen(name);
275 memcpy(section->name, name, len + 1);
276 section->offset = 0;
277 section->len = 0;
278
279 tmpdir = NULL;
280 if (chm->config != NULL)
281 tmpdir = chm->config->tmpdir;
282 if (tmpdir == NULL)
283 tmpdir = "/tmp/";
284
285 len = strlen(tmpdir);
286 if (len >= PATH_MAX - 12) {
288 chmcerr_msg("tmpdir too long: '%s'", tmpdir);
289 goto fail;
290 }
291
292 strcat(section->filename, tmpdir);
293 if (section->filename[len - 1] != '/')
294 strcat(section->filename, "/");
295
296 if (strcmp("MSCompressed", name) == 0)
297 strcat(section->filename, "chmcCXXXXXX");
298 else
299 strcat(section->filename, "chmcUXXXXXX");
300
301 section->fd = mkstemps(section->filename, 0);
302 fprintf(stderr, "temp file: %s\n", section->filename);
303 if (section->fd < 0) {
305 chmcerr_msg("creat() file '%s'", section->filename);
306 goto fail;
307 }
308 else if (strcmp(section->name, "MSCompressed") == 0) {
309 chmc_reset_table_init(&section->reset_table_header);
310 chmc_control_data_init(&section->control_data);
311 INIT_LIST_HEAD(&section->mark_list);
312 section->mark_count = 0;
313 }
314 } else {
316 chmcerr_msg("section '%s' allocation failed", name);
317 }
318
319 return section;
320
321 fail:
322 free(section);
323 return NULL;
324}
325
327{
328 reset_table->version = 2;
329 reset_table->block_count = 0;
330 reset_table->entry_size = 8;
332 reset_table->uncompressed_len = 0;
333 reset_table->compressed_len = 0;
334 reset_table->block_len = 0x8000;
335}
336
338{
339 control_data->size = 6;
340 memcpy(control_data->signature, "LZXC", 4);
341 control_data->version = 2;
342 control_data->resetInterval = 2;
343 control_data->windowSize = 2;
344 control_data->windowsPerReset = 1;
345 control_data->unknown_18 = 0;
346}
347
349{
350 int len;
351 int i;
352
353 assert(chm);
354
355 chm->sections = malloc(sizeof(struct chmcSection *) * chm->sections_num);
356 if (chm->sections) {
357 struct chmcSection *section;
358 struct list_head *pos;
359
360 i = 0;
361 len = 4;
364 len += 4 + strlen(section->name) * 2;
365 chm->sections[i++] = section;
366 }
368 } else
369 BUG_ON("FIXME: %s: %d\n", __FILE__, __LINE__);
370}
371
372int chmc_namelist_create(struct chmcFile *chm, int len)
373{
374 UInt16 *namelist;
375
376 namelist = malloc(len);
377 if (namelist) {
378 struct chmcSection *section;
379 int i, j, k, name_len;
380
381 k = 0;
382 namelist[k++] = len >> 1;
383 namelist[k++] = chm->sections_num;
384 for( i=0; i < chm->sections_num; i++ ) {
385 section = chm->sections[i];
386
387 name_len = strlen(section->name);
388 namelist[k++] = name_len;
389 for( j=0; j < name_len; j++ )
390 namelist[k++] = section->name[j];
391 namelist[k++] = 0;
392 }
393 chmc_add_meta(chm, "::DataSpace/NameList", 0, (UChar *)namelist, len);
394 }
395 else
396 return CHMC_ENOMEM;
397
398 return CHMC_NOERR;
399}
400
401struct chmcTreeNode *chmc_add_empty(struct chmcFile *chm, const char *file)
402{
403 assert(chm);
404 return chmc_add_entry(chm, file, 0, 0, NULL, 0, 0);
405}
406
407struct chmcTreeNode *chmc_add_meta(struct chmcFile *chm, const char *metaname,
408 int sect_id,
410{
411 struct chmcSection *section;
412 struct chmcTreeNode *node;
413
414 assert(chm);
415
416 if (sect_id >= chm->sections_num)
417 return NULL;
418
419 section = chm->sections[sect_id];
420
421 node = chmc_add_entry(chm, metaname, 0, sect_id, buf, section->offset, len);
422
423 if ((node) && (len > 0))
424 section->offset += len;
425
426 return node;
427}
428
429struct chmcTreeNode *chmc_add_entry(struct chmcFile *chm, const char *name,
432{
433 struct chmcTreeNode *node;
434
435 assert(chm);
436
437 if (sect_id >= (chm->sections_num)) {
438 fprintf(stderr,"sect_id %d >= chm->sections_num %d\n",
439 sect_id, chm->sections_num);
440 return NULL;
441 }
442
443 node = malloc(sizeof(struct chmcTreeNode));
444 if (node) {
445 node->flags = 0;
446 node->name = strdup( name );
447 node->prefixlen = prefixlen;
448 node->sect_id = sect_id;
449 node->buf = buf;
450 node->offset = offset;
451 node->len = len;
452 list_add_tail(&node->list, &chm->entries_list);
453 chm->entries_num++;
454 }
455 else
456 BUG_ON("FIXME: %s: %d\n", __FILE__, __LINE__);
457
458 return node;
459}
460
461void chmc_term(struct chmcFile *chm)
462{
463 assert(chm);
464 assert(chm->fd > -1);
465
466 free(chm->strings);
467
469 chmc_pmgl_free(chm);
470 chmc_pmgi_free(chm);
471 if (chm->sections)
472 free(chm->sections);
474
475 if (chm->fd != fileno(stdout))
476 close(chm->fd);
477}
478
480{
481 struct chmcSection *section;
482 struct list_head *pos, *q;
483
484 assert(chm);
485
488 list_del(pos);
490 }
491}
492
494{
496 assert(section->fd > -1);
497
498 if (strcmp(section->name, "MSCompressed") == 0) {
499 struct list_head *pos, *q;
500 struct chmcResetTableMark *mark;
501
502 list_for_each_safe(pos, q, &section->mark_list) {
503 mark = list_entry(pos, struct chmcResetTableMark, list);
504 list_del(pos);
505 free(mark);
506 }
507 }
508
509 close(section->fd);
510 unlink(section->filename);
511 free(section);
512}
513
514void chmc_pmgi_free(struct chmcFile *chm)
515{
516 struct chmcPmgiChunkNode *node;
517 struct list_head *pos, *q;
518
519 assert(chm);
520
523 list_del(pos);
525 }
526}
527
528void chmc_pmgl_free(struct chmcFile *chm)
529{
530 struct chmcPmglChunkNode *node;
531 struct list_head *pos, *q;
532
533 assert(chm);
534
537 list_del(pos);
539 }
540}
541
542void chmc_entries_free( struct chmcFile *chm )
543{
544 struct chmcTreeNode *node;
545 struct list_head *pos, *q;
546
547 assert(chm);
548
550 node = list_entry(pos, struct chmcTreeNode, list);
551 list_del(pos);
553 }
554
555 free(chm->sort_entries);
556}
557
558UInt32 chmc_strings_add( struct chmcFile *chm, const char *s)
559{
560 UInt32 len, off;
561
562 /* FIXME null are errors */
563
564 if (!s || *s == '\0')
565 return 0;
566
567 len = strlen(s);
568
569 off = chm->strings_offset;
570
571 if (off + len + 1 < chm->strings_len) {
572
573 memcpy(&chm->strings[off], s, len + 1);
574 chm->strings_offset += len + 1;
575
576 } else {
577 /* realloc strings */
578 /* if the string truncate copy til end of chunk
579 then re-copy from 0 of new */
580 BUG_ON("FIXME: %s: %d: handle more chunk for strings\n",
581 __FILE__, __LINE__);
582 }
583
584 return off;
585}
586
588{
589 assert(node);
590 assert(node->name);
591
592 free(node->name);
593 if (node->buf && !(node->flags & CHMC_TNFL_STATIC))
594 free(node->buf);
595 free(node);
596}
597
598struct chmcTreeNode *chmc_add_file(struct chmcFile *chm, const char *filename,
600 UInt64 len)
601{
602 struct chmcSection *section;
603 struct chmcTreeNode *node;
604
605 assert(chm);
606
607 if (sect_id >= chm->sections_num)
608 return NULL;
609
610 section = chm->sections[sect_id];
611
613 section->offset, len);
614
615 if ((node) && (len > 0))
616 section->offset += len;
617
618 return node;
619}
620
621struct chmcTreeNode *chmc_add_dir(struct chmcFile *chm, const char *dir)
622{
623 assert(chm);
624
625 return chmc_add_entry(chm, dir, 0, 0, NULL, 0, 0);
626}
627
628static inline void *chmc_syscat_mem(void *d, void *s, unsigned long len)
629{
630 memcpy(d, s, len);
631
632 return (char *)d + len;
633}
634
635static void *chmc_syscat_entry(Int16 code, void *d, void *s, Int16 len)
636{
637 d = chmc_syscat_mem(d, &code, 2);
638 d = chmc_syscat_mem(d, &len, 2);
639
640 return chmc_syscat_mem(d, s, len);
641}
642
643/* #define DEFAULT_TOPIC "index.htm" */
644/* #define TITLE "hello world" */
645/* #define LCASEFILE "test" */
646
648{
649 struct chmcSystem *system;
650 struct chmcSystemInfo *sysinfo;
651 struct chmcIndexHeader *idxhdr;
652 void *sysp, *p;
653
654 assert(chm);
655
656 system = &chm->system;
657 sysinfo = &system->info;
658 idxhdr = &chm->idxhdr;
659
660 // TODO should be set from application
661 // system->_size += (_CHMC_SYS_ENTRY_HDR_LEN + sizeof(UInt32)) /* timestamp */
662 // + (_CHMC_SYS_ENTRY_HDR_LEN + sizeof(PACKAGE_STRING)) /* compiler */
663 // + (_CHMC_SYS_ENTRY_HDR_LEN + sizeof(UInt32)) /* eof */
664 // + (_CHMC_SYS_ENTRY_HDR_LEN + sizeof(DEFAULT_TOPIC))
665 // + (_CHMC_SYS_ENTRY_HDR_LEN + sizeof(TITLE))
666 // + 32;
667
668 sysp = malloc(16384);
669 if (sysp) {
670 UInt32 val;
671#ifndef __REACTOS__
672 UInt16 code, len;
673#endif
674 const char *entry_val;
675
676 p = chmc_syscat_mem(sysp, &system->version, sizeof(system->version));
677
678 val = 0;
679 p = chmc_syscat_entry(SIEC_TIMESTAMP, p, &val, sizeof(val));
681 /*"HHA Version 4.74.8702"*/
683 sizeof(PACKAGE_STRING)
684 /*strlen("HHA Version 4.74.8702")+1*/);
686 sysinfo, sizeof(struct chmcSystemInfo));
687
688 if (chm->config != NULL && chm->config->deftopic != NULL)
689 entry_val = chm->config->deftopic;
690 else
691 entry_val = "index.htm";
692 p = chmc_syscat_entry(SIEC_DEFTOPIC, p, (void *)entry_val,
693 strlen(entry_val)+1);
694
695 if (chm->config != NULL && chm->config->title != NULL)
696 entry_val = chm->config->title;
697 else
698 entry_val = "untitled";
699 p = chmc_syscat_entry(SIEC_TITLE, p, (void *)entry_val,
700 strlen(entry_val)+1);
701 // p = chmc_syscat_entry(SIEC_DEFFONT, p, &val, sizeof(val));
702 p = chmc_syscat_entry(SIEC_LCASEFILE, p, "siec_lcasefile",
703 strlen("siec_lcasefile")+1);
705 "MsdnHelp", strlen("MsdnHelp")+1);
706
707 val = 0;
709
711 idxhdr, sizeof(struct chmcIndexHeader));
712
713
714 val = 0;
716
717 system->_size = (char *)p - (char *)sysp;
718 chmc_add_meta(chm, "/#SYSTEM", 0, sysp, system->_size);
719 return CHMC_NOERR;
720 }
721
722 chmcerr_set(CHMC_ENOMEM, "system done: malloc %d bytes",
723 system->_size);
724
725 return CHMC_ENOMEM;
726}
727
728int chmc_tree_done( struct chmcFile *chm )
729{
730 struct chmcItsfHeader *itsf;
731 struct chmcSect0 *sect0;
732 struct chmcItspHeader *itsp;
733 struct chmcTreeNode *ctrl;
734 UInt32 str_index;
735 const char *val;
736
737 assert(chm);
738
739 itsf = &chm->itsf;
740 sect0 = &chm->sect0;
741 itsp = &chm->itsp;
742
743 chmc_add_dir(chm, "/");
744
745 ctrl = chmc_add_meta(chm, "::DataSpace/Storage/MSCompressed/Transform/List",
747 sizeof(chmc_transform_list));
748 if (ctrl)
749 ctrl->flags |= CHMC_TNFL_STATIC;
750
751 chmc_system_done(chm);
752
753 if (chm->config != NULL && chm->config->deftopic != NULL)
754 val = chm->config->deftopic;
755 else
756 val = "index.htm";
757
758 str_index = chmc_strings_add(chm, val);
759
760#if 0
761 // FIXME just a test
762 {
763 UChar *p;
764 int len;
765 struct chmcTopicEntry topicEntry;
766 // struct chmcUrlStrEntry urlStrEntry;
767
768 p = malloc(4096);
769 if (p) {
770 memset(p, 0, 4096);
771 len = 0;
772
773 topicEntry.tocidx_offset = 4096;
774 topicEntry.strings_offset = -1;
775 topicEntry.urltbl_offset = 0;
776 topicEntry.in_content = 6;
777 topicEntry.unknown = 0;
778
779 memcpy(p, &topicEntry, sizeof(struct chmcTopicEntry));
780 len += sizeof(struct chmcTopicEntry);
781
782 chm->idxhdr.num_of_topic++;
783
784 chmc_add_meta(chm, "/#TOPICS", 1, (UChar *)p, len);
785 } else
786 BUG_ON("FIXME: %s: %d\n", __FILE__, __LINE__);
787 }
788#endif
789
790 ctrl = chmc_add_meta(chm, "/#IDXHDR", 1, (void *)&chm->idxhdr,
791 sizeof(struct chmcIndexHeader));
792 if (ctrl)
793 ctrl->flags |= CHMC_TNFL_STATIC;
794
795 {
796 UInt32 *p;
797 p = malloc(8+196);
798 if (p) {
799 const char *val;
800 memset(p+2, 0, 196);
801
802 p[0] = 1;
803 p[1] = 196;
804
805 p[2+0] = 196;
806 // p[2+2] = 1;
807 // p[2+3] = 0x00000532;
808 // p[2+4] = 0x00062520;
809
810 // p[2+8] = 86;
811 // p[2+9] = 51;
812 // p[2+10] = 872;
813 // p[2+11] = 558;
814
815 // p[2+19] = 220;
816
817 // p[2+27] = 0x00000041;
818 // p[2+28] = 14462;
819
820 if (chm->config != NULL && chm->config->title != NULL)
821 val = chm->config->title;
822 else
823 val = "untitled";
824 p[2+5] = chmc_strings_add(chm, val);
825
826 if (chm->config != NULL && chm->config->hhc != NULL)
827 val = chm->config->hhc;
828 else
829 val = "toc.hhc";
830 p[2+24] = chmc_strings_add(chm, val);
831
832 if (chm->config != NULL && chm->config->hhk != NULL)
833 val = chm->config->hhc;
834 else
835 val = "toc.hhk";
836 p[2+25] = chmc_strings_add(chm, val);
837 p[2+26] = str_index;
838
839 chmc_add_meta(chm, "/#WINDOWS", 1, (UChar *)p, 8+196);
840 } else
841 BUG_ON("FIXME: %s: %d\n", __FILE__, __LINE__);
842 }
843
844 ctrl = chmc_add_meta(chm, "/#STRINGS", 1, (void *)chm->strings,
845 chm->strings_len);
846 if (ctrl)
847 ctrl->flags |= CHMC_TNFL_STATIC;
848
849#if 0
850 // FIXME just a test
851 {
852 UChar *p;
853 int len;
854 struct chmcUrlStrEntry urlStrEntry;
855
856 urlStrEntry.url_offset = 0;
857 urlStrEntry.framename_offset = 0;
858
859 p = malloc(4096);
860 if (p) {
861 memset(p, 0, 4096);
862 *p = 0x42;
863 len = 1;
864
865 memcpy(p + len, &urlStrEntry, sizeof(struct chmcUrlStrEntry));
866 len += sizeof(struct chmcUrlStrEntry);
867 len += sprintf(p + len, "index.htm" ) + 1;
868
869 memcpy(p + len, &urlStrEntry, sizeof(struct chmcUrlStrEntry));
870 len += sizeof(struct chmcUrlStrEntry);
871 len += sprintf(p + len, "test.htm" ) + 1;
872
873 chmc_add_meta(chm, "/#URLSTR", 1, (UChar *)p, len);
874 } else
875 BUG_ON("FIXME: %s: %d\n", __FILE__, __LINE__);
876 }
877#endif
878
879 // chmc_add_entry(chm, "/#URLTBL", 0, 1, NULL, 0, 0);
880 // chmc_add_entry(chm, "/#TOPICS", 0, 1, NULL, 0, 0);
881
882 // NOTE NOTE NOTE add any meta compressed before crunch ;-)
883
884 chmc_crunch_lzx(chm, 1);
885
888
889 chmc_add_empty(chm, "/#ITBITS");
890
891 // NOTE in this implementation compressed Content should be the last file
892 // added to section 0
893
894 chmc_add_meta(chm, "::DataSpace/Storage/MSCompressed/Content", 0, NULL,
895 chm->sections[1]->offset);
896
899 chmc_pmgl_done(chm);
900
901 chmc_pmgi_done(chm);
902
904 + (_CHMC_CHUNK_LEN * itsp->num_blocks);
905
909 + (_CHMC_CHUNK_LEN * itsp->num_blocks);
910
911 sect0->file_len += _CHMC_CHUNK_LEN * itsp->num_blocks;
912
913 chmc_write(chm);
914
915 {
916 struct chmcSection *section;
917 struct list_head *pos;
918 UChar buf[4096];
919
922 chmc_appendfile(chm, section->filename, buf, 4096);
923 }
924 }
925
926 return CHMC_NOERR;
927}
928
929int chmc_crunch_lzx(struct chmcFile *chm, int sect_id)
930{
931 struct chmcLzxInfo lzx_info;
932
933 lzx_data *lzxd;
934 int subd_ok = 1;
935 int do_reset = 1;
936 int block_size;
937 lzx_results lzxr;
938 int wsize_code = 16;
939
940 assert(chm);
941
942#ifndef __REACTOS__
943 if ((wsize_code < 15) || (wsize_code > 21)) {
944 fprintf(stderr, "window size must be between 15 and 21 inclusive\n");
945 return CHMC_EINVAL;
946 }
947#endif
948
949 lzx_info.chm = chm;
950 lzx_info.section = chm->sections[sect_id];
951 lzx_info.done = 0;
952 lzx_info.todo = lzx_info.section->offset;
953 lzx_info.pos = chm->entries_list.next;
954 lzx_info.error = 0;
955 lzx_info.eof = 0;
956
957 lzx_info.fd = -1;
958 lzx_info.fd_offset = 0;
959
960 chmc_compressed_add_mark(lzx_info.chm, 0);
961 lzx_info.section->reset_table_header.block_count++;
962
963 /* undocumented fact, according to Caie --
964 block size cannot exceed window size. (why not?) */
965 /* The block size must not be larger than the window size.
966 While the compressor will create apparently-valid LZX files
967 if this restriction is violated, some decompressors
968 will not handle them. */
969
970 block_size = 1 << wsize_code;
971
972 // lzx_info.section->control_data.windowSize = wsize_code;
973 // lzx_info.section->control_data.windowsPerReset = block_size;
974
975 lzx_init(&lzxd, wsize_code,
976 _lzx_get_bytes, &lzx_info, _lzx_at_eof,
977 _lzx_put_bytes, &lzx_info,
978 _lzx_mark_frame, &lzx_info);
979
980 while(! _lzx_at_eof(&lzx_info)) {
981 if (do_reset)
982 lzx_reset(lzxd);
983 lzx_compress_block(lzxd, block_size, subd_ok);
984 }
985 lzx_finish(lzxd, &lzxr);
986
987 return CHMC_NOERR;
988}
989
990static int _lzx_at_eof(void *arg)
991{
992 struct chmcLzxInfo *lzx_info = (struct chmcLzxInfo *)arg;
993
994 return lzx_info->error || lzx_info->done >= lzx_info->todo || lzx_info->eof;
995}
996
997static int _lzx_put_bytes(void *arg, int n, void *buf)
998{
999 struct chmcLzxInfo *lzx_info = (struct chmcLzxInfo *)arg;
1000 struct chmcSect0 *sect0 = &lzx_info->chm->sect0;
1001 int wx;
1002 static int counter = 0;
1003
1004 counter += n;
1005 wx = write(lzx_info->section->fd, buf, n);
1006 sect0->file_len += wx;
1007 lzx_info->section->len += wx;
1008
1009 return wx;
1010}
1011
1012static void _lzx_mark_frame(void *arg, uint32_t uncomp, uint32_t comp)
1013{
1014 struct chmcLzxInfo *lzx_info = (struct chmcLzxInfo *)arg;
1015 struct chmcSection *section = lzx_info->chm->sections[1];
1016
1017 UInt64 compressed;
1018
1019 chmc_dump( "Aligned data at %d(in compressed stream, %d) (%lu/%lu)\n",
1020 uncomp, comp, (unsigned long)lzx_info->done, (unsigned long)lzx_info->todo );
1021
1022 compressed = comp;
1023
1024 section->reset_table_header.block_count++;
1025
1026 chmc_compressed_add_mark( lzx_info->chm, compressed );
1027
1028 section->reset_table_header.uncompressed_len = uncomp;
1029 section->reset_table_header.compressed_len = comp;
1030}
1031
1032static int _lzx_get_bytes(void *arg, int n, void *buf)
1033{
1034 struct chmcLzxInfo *lzx_info = (struct chmcLzxInfo *)arg;
1035 struct chmcFile *chm = lzx_info->chm;
1036 struct chmcTreeNode *node;
1037
1038 int todo;
1039 int done;
1040 int toread;
1041 int rx;
1042
1043 todo = n;
1044 done = 0;
1045
1046 // compression state machine
1047 // lzx compressor ask for block input bytes
1048 // need to keep current entry file and offset trought blocks
1049 // until last entry
1050 while (todo) {
1051 // end of entries reached?
1052 if (lzx_info->pos == &chm->entries_list) {
1053 lzx_info->eof = 1;
1054 break;
1055 }
1056
1057 node = list_entry( lzx_info->pos, struct chmcTreeNode, list );
1058
1059 // skip empty files and directories
1060 if (node->len == 0
1061 || strcmp("MSCompressed", chm->sections[node->sect_id]->name)) {
1062 lzx_info->pos = lzx_info->pos->next;
1063 continue;
1064 }
1065 else
1066 if (node->buf) {
1067 // have len and buffer, it's mallocated not file
1068 }
1069 else
1070 if (lzx_info->fd == -1) {
1071 // open file if it isn't
1072 lzx_info->fd = open(node->name, O_RDONLY | O_BINARY);
1073 if (lzx_info->fd < 0) {
1074 chmc_error("%s: %d: error %d: '%s' %s\n",
1075 __FILE__, __LINE__,
1076 errno, node->name, strerror(errno));
1077 lzx_info->error = 1;
1078 break;
1079 }
1080 }
1081
1082 // read till the end of the file or till the lzx buffer is filled
1083 toread = node->len - lzx_info->fd_offset;
1084 if (toread > todo)
1085 toread = todo;
1086
1087 if (toread <= 0)
1088 continue;
1089
1090 // read input
1091 if (node->buf) {
1092 memcpy((char *)buf + (n - todo), &node->buf[lzx_info->fd_offset], toread);
1093 rx = toread;
1094 }
1095 else
1096 {
1097 rx = read(lzx_info->fd, (char *)buf + (n - todo), toread);
1098 if (rx <= 0) {
1099 int temp = errno;
1100 chmc_error("read error %s \n", strerror(temp));
1101 lzx_info->error = 2;
1102 break;
1103 }
1104 }
1105
1106 todo -= rx;
1107 lzx_info->fd_offset += rx;
1108 done += rx;
1109 lzx_info->done += rx;
1110
1111 // end of current file reached, goto next entry
1112 if (lzx_info->fd_offset == node->len) {
1113 if (lzx_info->fd > -1)
1114 close(lzx_info->fd);
1115 lzx_info->fd = -1;
1116 lzx_info->fd_offset = 0;
1117 lzx_info->pos = lzx_info->pos->next;
1118 }
1119 }
1120
1121 return done;
1122}
1123
1125{
1126 struct chmcSection *section;
1127 struct chmcResetTableMark *mark;
1128
1129 assert(chm);
1130
1131 section = chm->sections[1];
1132
1133 mark = malloc(_CHMC_RSTTBL_MARK);
1134 if (mark) {
1135 mark->at = at;
1136 chmc_dump("[%d] at: %jd\n", section->mark_count, at);
1137 list_add_tail(&mark->list, &section->mark_list);
1138 section->mark_count++;
1139 return CHMC_NOERR;
1140 }
1141
1142 return CHMC_ENOMEM;
1143}
1144
1146{
1147 struct chmcTreeNode *ctrl;
1148
1149 ctrl = chmc_add_meta(chm, "::DataSpace/Storage/MSCompressed/ControlData",
1150 0, (UChar *)&chm->sections[1]->control_data,
1152
1153 if (ctrl) {
1154 ctrl->flags |= CHMC_TNFL_STATIC;
1155 return CHMC_NOERR;
1156 }
1157
1158 return CHMC_ENOMEM;
1159}
1160
1162{
1163 struct chmcSection *section;
1164 struct chmcLzxcResetTable *reset_table;
1165 struct list_head *pos;
1166 struct chmcResetTableMark *mark;
1167
1168 UInt64 *at;
1169 int i, len;
1170
1171 section = chm->sections[1];
1172
1173 len = _CHMC_LZXC_RESETTABLE_V1_LEN + (section->mark_count * sizeof(UInt64));
1174
1175 reset_table = malloc(len);
1176
1177 if (reset_table) {
1178 memcpy(reset_table, &section->reset_table_header,
1180 at = (void *)((char *)reset_table + _CHMC_LZXC_RESETTABLE_V1_LEN);
1181
1182 i = 0;
1183 list_for_each(pos, &section->mark_list) {
1184 mark = list_entry(pos, struct chmcResetTableMark, list);
1185 at[i++] = mark->at;
1186 }
1187
1188 chmc_add_dir(chm, "::DataSpace/Storage/MSCompressed/Transform/"
1189 "{7FC28940-9D31-11D0-9B27-00A0C91E9C7C}/InstanceData/");
1190 chmc_add_meta(chm, "::DataSpace/Storage/MSCompressed/Transform/"
1191 "{7FC28940-9D31-11D0-9B27-00A0C91E9C7C}"
1192 "/InstanceData/ResetTable",
1193 0, (UChar *)reset_table, len);
1194
1195 { // TODO FIXME do better
1196 UInt64 *uncompressed_len = malloc(8);
1197 if (uncompressed_len) {
1198 *uncompressed_len = reset_table->uncompressed_len;
1199 chmc_add_meta(chm, "::DataSpace/Storage/MSCompressed/SpanInfo",
1200 0, (UChar *)uncompressed_len, 8);
1201 }
1202 }
1203
1204 return CHMC_NOERR;
1205 }
1206
1207 return CHMC_ENOMEM;
1208}
1209
1211{
1212 struct chmcTreeNode *node;
1213 struct list_head *pos;
1214 int i;
1215
1216 assert(chm);
1217
1218 chm->sort_entries = malloc(sizeof(struct chmcTreeNode *)
1219 * chm->entries_num);
1220
1221 i = 0;
1223 node = list_entry(pos, struct chmcTreeNode, list);
1224 chm->sort_entries[i++] = node;
1225 }
1226
1227 qsort(chm->sort_entries, chm->entries_num, sizeof(struct chmcTreeNode *),
1228 _entry_cmp);
1229}
1230
1231static int _entry_cmp(const void *pva, const void *pvb)
1232{
1233 const struct chmcTreeNode * const *pa = pva;
1234 const struct chmcTreeNode * const *pb = pvb;
1235 const struct chmcTreeNode *a = *pa, *b = *pb;
1236
1237 return strcmp( &a->name[a->prefixlen], &b->name[b->prefixlen] );
1238}
1239
1241{
1242 struct chmcSect0 *sect0 = &chm->sect0;
1243 struct chmcTreeNode *node;
1244 struct list_head *pos;
1245 int wx;
1246
1248 node = list_entry( pos, struct chmcTreeNode, list );
1249
1250 if (strcmp( "MSCompressed", chm->sections[node->sect_id]->name ) == 0)
1251 continue;
1252
1253 if ((node->buf) && (node->len > 0)) {
1254 wx = write(chm->sections[node->sect_id]->fd, node->buf, node->len);
1255 sect0->file_len += wx;
1256 }
1257 }
1258
1259 return CHMC_NOERR;
1260}
1261
1262void chmc_pmgl_done(struct chmcFile *chm)
1263{
1264 struct chmcTreeNode *entry;
1265 int i;
1266
1267 assert(chm);
1268
1269 for(i=0; i < chm->entries_num; i++) {
1270 entry = chm->sort_entries[i];
1272 }
1273}
1274
1276{
1277 struct chmcPmglChunkNode *pmgl;
1278 struct chmcPmglChunk *chunk;
1279 struct chmcSection *section;
1280 struct chmcItspHeader *itsp = &chm->itsp;
1281
1282 UChar *p;
1283 UInt16 *idx;
1284 int name_len;
1285 int outlen;
1286 int should_idx, idx_intlv;
1287 int free;
1288
1289 assert(chm);
1290 assert(entry);
1291
1292 // check section bound
1293 section = chmc_section_lookup(chm, entry->sect_id);
1294 if (!section)
1295 chmcerr_set_return(CHMC_ENOMEM, "section %d lookup failed: ",
1296 entry->sect_id);
1297
1298 // check chunk space for new entry
1299 name_len = strlen(&entry->name[entry->prefixlen]);
1300
1301 outlen = chmc_encint_len(name_len);
1302 outlen += name_len;
1303 outlen += chmc_encint_len(entry->sect_id);
1304 outlen += chmc_encint_len(entry->offset);
1305 outlen += chmc_encint_len(entry->len);
1306
1307 // look for current pmgl chunk, create if doesn't exist
1308 if (!chm->pmgl_last) {
1309 pmgl = chmc_pmgl_create();
1310 if (pmgl)
1311 chmc_pmgl_add(chm, pmgl);
1312 else
1313 chmcerr_set_return(CHMC_ENOMEM, "pmgl chunk: ");
1314 }
1315 else
1316 pmgl = chm->pmgl_last;
1317
1318 do {
1319
1320 chunk = &chm->pmgl_last->chunk;
1321
1322 idx_intlv = 1 + ( 1 << itsp->blockidx_intvl );
1323 should_idx = ( ( chunk->entries_count > 0 )
1324 && ! ( ( chunk->entries_count + 1 ) % idx_intlv )
1325 ? 2 : 0 );
1326
1327 free = sizeof(chunk->data) - pmgl->data_len - pmgl->index_len
1328 - should_idx;
1329
1330 // current(last) chunk doesn't have enough room? force new one
1331 if (outlen + should_idx > free) {
1332 //chm->pmgl_last = NULL;
1333 pmgl = chmc_pmgl_create();
1334 if ( pmgl )
1335 chmc_pmgl_add(chm, pmgl);
1336 else
1337 chmcerr_set_return(CHMC_ENOMEM, "pmgl chunk: ");
1338
1339 continue;
1340 }
1341
1342 p = (void *)&chunk->data[pmgl->data_len];
1343
1344 if (should_idx) {
1345 idx = (void *)((char *)&chunk->data[CHMC_PMGL_DATA_LEN] - pmgl->index_len);
1346 *idx = (char *)p - (char *)&chunk->data;
1347 }
1348
1349 p += chmc_encint(name_len, p);
1350 memcpy(p, &entry->name[entry->prefixlen], name_len);
1351 p += name_len;
1352 p += chmc_encint(entry->sect_id, p);
1353 p += chmc_encint(entry->offset, p);
1354 p += chmc_encint(entry->len, p);
1355
1356 pmgl->data_len += outlen;
1357 pmgl->index_len += should_idx;
1358
1359 chunk->entries_count++;
1360 chunk->header.free_space -= outlen;
1361 break;
1362
1363 } while (1);
1364
1365 return CHMC_NOERR;
1366}
1367
1368struct chmcSection *chmc_section_lookup(struct chmcFile *chm, int id)
1369{
1370 struct chmcSection *current;
1371 struct list_head *pos;
1372 int i;
1373
1374 assert(chm);
1375
1376 i = 0;
1379 if (i == id)
1380 return current;
1381 i++;
1382 }
1383
1384 return NULL;
1385}
1386
1388{
1389 struct chmcPmglChunkNode *node;
1390
1391 node = malloc(sizeof(struct chmcPmglChunkNode));
1392 if (node)
1394
1395 return node;
1396}
1397
1399{
1400 struct chmcPmglChunk *chunk;
1401
1402 assert(node);
1403
1404 node->data_len = 0;
1405 node->index_len = 0;
1406
1407 chunk = &node->chunk;
1408
1409 memcpy(chunk->header.signature, "PMGL", 4);
1410
1411 // FIXME check it is the right len
1412 chunk->header.free_space = CHMC_PMGL_DATA_LEN + 2;
1413 chunk->header.unknown_0008 = 0;
1414 chunk->header.block_prev = -1;
1415 chunk->header.block_next = -1;
1416
1417 memset(chunk->data, 0, CHMC_PMGL_DATA_LEN);
1418}
1419
1421{
1422 struct chmcPmgiChunk *chunk;
1423
1424 assert(node);
1425
1426 node->data_len = 0;
1427 node->index_len = 0;
1428
1429 chunk = &node->chunk;
1430
1431 memcpy(chunk->header.signature, "PMGI", 4);
1432
1433 // FIXME check it is the right len
1434 chunk->header.free_space = CHMC_PMGI_DATA_LEN + 2;
1435 // chunk->header.unknown_0008 = 0;
1436 // chunk->header.block_prev = -1;
1437 // chunk->header.block_next = -1;
1438
1439 memset(chunk->data, 0, CHMC_PMGI_DATA_LEN);
1440}
1441
1442
1443
1445{
1446 struct chmcPmgiChunkNode *node;
1447
1448 node = malloc(sizeof(struct chmcPmgiChunkNode));
1449 if (node)
1451
1452 return node;
1453}
1454
1456{
1457 assert(node);
1458 free(node);
1459}
1460
1462{
1463 assert(node);
1464 free(node);
1465}
1466
1467void chmc_pmgl_add(struct chmcFile *chm, struct chmcPmglChunkNode *pmgl)
1468{
1469 struct chmcItspHeader *itsp = &chm->itsp;
1470 struct chmcPmglHeader *hdr;
1471
1472 assert(chm);
1473 assert(pmgl);
1474
1475 list_add_tail(&pmgl->list, &chm->pmgl_list);
1476
1477 itsp->index_last = itsp->num_blocks;
1478
1479 hdr = &pmgl->chunk.header;
1480 hdr->block_prev = itsp->num_blocks - 1;
1481
1482 if (chm->pmgl_last) {
1483 hdr = &chm->pmgl_last->chunk.header;
1484 hdr->block_next = itsp->num_blocks;
1485 }
1486
1487 itsp->num_blocks++;
1488
1489 chm->pmgl_last = pmgl;
1490}
1491
1492int chmc_pmgi_done(struct chmcFile *chm)
1493{
1494 struct chmcItspHeader *itsp = &chm->itsp;
1495 struct chmcPmglChunkNode *pmgl;
1496 struct list_head *pos;
1497
1498 int i, j;
1499 char name[256]; //FIXME use malloc
1500 UInt32 name_len;
1501
1502 assert(chm);
1503
1504 // only one pml, omitted pmgi
1505 if (itsp->num_blocks == 1) {
1506 itsp->index_depth = 1;
1507 itsp->index_root = -1;
1508 itsp->index_last = 0;
1509 return CHMC_NOERR;
1510 }
1511
1512 itsp->index_root = itsp->num_blocks;
1513
1514 i = 0;
1515 list_for_each(pos, &chm->pmgl_list) {
1516 pmgl = list_entry(pos, struct chmcPmglChunkNode, list);
1517 j = chmc_decint(&pmgl->chunk.data[0], &name_len);
1518 if (name_len <= 255) {
1519 memcpy(name, &pmgl->chunk.data[j], name_len);
1520 name[name_len] = '\0';
1521 chmc_pmgi_add_entry(chm, name, i);
1522 }
1523 else
1524 BUG_ON("name_len >= 255(%lu) %.*s\n", (unsigned long)name_len, 255,
1525 &pmgl->chunk.data[j]);
1526 i++;
1527 }
1528
1529 return CHMC_NOERR;
1530}
1531
1532int chmc_pmgi_add_entry(struct chmcFile *chm, const char *name, int pmgl_id)
1533{
1534 struct chmcPmgiChunkNode *pmgi;
1535 struct chmcPmgiChunk *chunk;
1536 struct chmcItspHeader *itsp = &chm->itsp;
1537
1538 UChar *p;
1539 UInt16 *idx;
1540 int name_len;
1541 int outlen;
1542 int should_idx, idx_intlv;
1543 int free;
1544
1545 assert(chm);
1546
1547 // check chunk space for new entry
1548 name_len = strlen(name);
1549
1550 outlen = chmc_encint_len(name_len);
1551 outlen += name_len;
1552 outlen += chmc_encint_len(pmgl_id);
1553
1554 // look for current pmgi chunk, create if doesn't exist
1555 if (!chm->pmgi_last) {
1556 pmgi = chmc_pmgi_create();
1557 if (pmgi)
1558 chmc_pmgi_add(chm, pmgi);
1559 else
1560 chmcerr_set_return(CHMC_ENOMEM, "pmgi chunk: ");
1561 }
1562 else
1563 pmgi = chm->pmgi_last;
1564
1565 do {
1566
1567 chunk = &chm->pmgi_last->chunk;
1568
1569 idx_intlv = 1 + ( 1 << itsp->blockidx_intvl );
1570 should_idx = ( ( chunk->entries_count > 0 )
1571 && ! ( ( chunk->entries_count + 1 ) % idx_intlv )
1572 ? 2 : 0 );
1573
1574 free = sizeof(chunk->data) - pmgi->data_len -
1575 pmgi->index_len - should_idx;
1576
1577 // current(last) chunk doesn't have enough room? force new one
1578 if (outlen + should_idx > free) {
1579 pmgi = chmc_pmgi_create();
1580 if (pmgi)
1581 chmc_pmgi_add(chm, pmgi);
1582 else
1583 chmcerr_set_return(CHMC_ENOMEM, "pmgi chunk: ");
1584
1585 continue;
1586 }
1587
1588 p = (void *)&chunk->data[pmgi->data_len];
1589
1590 if (should_idx) {
1591 idx = (void *)((char *)&chunk->data[CHMC_PMGI_DATA_LEN] - pmgi->index_len);
1592 *idx = (char *)p - (char *)&chunk->data;
1593 }
1594
1595 p += chmc_encint(name_len, p);
1596 memcpy(p, name, name_len);
1597 p += name_len;
1598 p += chmc_encint(pmgl_id, p);
1599
1600 pmgi->data_len += outlen;
1601 pmgi->index_len += should_idx;
1602
1603 chunk->entries_count++;
1604 chunk->header.free_space -= outlen;
1605 break;
1606
1607 } while (1);
1608
1609 return CHMC_NOERR;
1610}
1611
1612void chmc_pmgi_add(struct chmcFile *chm, struct chmcPmgiChunkNode *pmgi)
1613{
1614 struct chmcItspHeader *itsp = &chm->itsp;
1615
1616 assert(chm);
1617 assert(pmgi);
1618
1619 list_add_tail(&pmgi->list, &chm->pmgi_list);
1620 itsp->num_blocks++;
1621
1622 chm->pmgi_last = pmgi;
1623}
1624
1625int chmc_write(struct chmcFile *chm)
1626{
1627 struct chmcItsfHeader *itsf = &chm->itsf;
1628 struct chmcSect0 *sect0 = &chm->sect0;
1629 struct chmcItspHeader *itsp = &chm->itsp;
1630
1631 struct chmcPmglChunkNode *pmgl;
1632 struct chmcPmgiChunkNode *pmgi;
1633 struct list_head *pos;
1634
1635 assert(chm);
1636
1637 chmc_dump("write itsf %d\n", _CHMC_ITSF_V3_LEN);
1638 write(chm->fd, itsf, _CHMC_ITSF_V3_LEN);
1639 chmc_dump("write sect0 %d\n", _CHMC_SECT0_LEN);
1640 write(chm->fd, sect0, _CHMC_SECT0_LEN);
1641 chmc_dump("write itsp %d\n", _CHMC_ITSP_V1_LEN);
1642 write(chm->fd, itsp, _CHMC_ITSP_V1_LEN);
1643
1644 list_for_each(pos, &chm->pmgl_list) {
1645 pmgl = list_entry(pos, struct chmcPmglChunkNode, list);
1646 chmc_dump("write pmgl %d\n", _CHMC_CHUNK_LEN);
1647 write(chm->fd, &pmgl->chunk, _CHMC_CHUNK_LEN);
1648 }
1649
1650 chmc_dump("itsp->num_blocks %d", itsp->num_blocks);
1651 if (itsp->num_blocks > 1) {
1652 list_for_each( pos, &chm->pmgi_list ) {
1653 pmgi = list_entry(pos, struct chmcPmgiChunkNode, list);
1654 chmc_dump("write pmgi %d\n", _CHMC_CHUNK_LEN);
1655 write(chm->fd, &pmgi->chunk, _CHMC_CHUNK_LEN);
1656 }
1657 }
1658
1659 return CHMC_NOERR;
1660}
1661
1662int chmc_appendfile(struct chmcFile *chm, const char *filename, void *buf,
1663 size_t size )
1664{
1665 struct stat statbuf;
1666 int in;
1667 off_t todo, toread;
1668 int rx;
1669
1670 if (stat(filename, &statbuf) < 0)
1671 return errno;
1672
1674 if (in >= 0) {
1675 todo = statbuf.st_size;
1676
1677 while (todo) {
1678 toread = size;
1679 if (toread > todo)
1680 toread = todo;
1681
1682 rx = read(in, buf, toread);
1683 if (rx > 0) {
1684 write(chm->fd, buf, rx);
1685 todo -= rx;
1686 }
1687 }
1688
1689 close(in);
1690 }
1691 else
1692 BUG_ON("open %s\n", filename);
1693
1694 return CHMC_NOERR;
1695}
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define stat
Definition: acwin.h:99
#define O_CREAT
Definition: acwin.h:110
#define fileno
Definition: acwin.h:102
#define read
Definition: acwin.h:96
#define O_RDONLY
Definition: acwin.h:108
#define open
Definition: acwin.h:95
#define close
Definition: acwin.h:98
#define write
Definition: acwin.h:97
#define O_TRUNC
Definition: acwin.h:112
unsigned int dir
Definition: maze.c:112
#define PATH_MAX
Definition: types.h:280
#define list_for_each(entry, head)
Definition: list.h:36
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
#define _CHMC_ITSP_V1_LEN
Definition: chm.h:118
#define _CHMC_LZXC_RESETTABLE_V1_LEN
Definition: chm.h:156
#define _CHMC_LZXC_V2_LEN
Definition: chm.h:169
#define _CHMC_ITSF_V3_LEN
Definition: chm.h:89
#define _CHMC_SECT0_LEN
Definition: chm.h:106
#define CHM_IDX_INTVL
Definition: chm.h:115
USHORT UInt16
Definition: chm_lib.c:102
DWORD UInt32
Definition: chm_lib.c:104
SHORT Int16
Definition: chm_lib.c:101
BYTE UChar
Definition: chm_lib.c:100
ULONGLONG UInt64
Definition: chm_lib.c:106
int chmc_appendfile(struct chmcFile *chm, const char *filename, void *buf, size_t size)
Definition: chmc.c:1662
struct chmcTreeNode * chmc_add_dir(struct chmcFile *chm, const char *dir)
Definition: chmc.c:621
int chmc_namelist_create(struct chmcFile *chm, int len)
Definition: chmc.c:372
int chmc_add_tree(struct chmcFile *chm, const char *dir)
void chmc_reset_table_init(struct chmcLzxcResetTable *reset_table)
Definition: chmc.c:326
static void _lzx_mark_frame(void *arg, uint32_t uncomp, uint32_t comp)
Definition: chmc.c:1012
void chmc_pmgi_destroy(struct chmcPmgiChunkNode *node)
Definition: chmc.c:1461
void chmc_term(struct chmcFile *chm)
Definition: chmc.c:461
static int _lzx_get_bytes(void *arg, int n, void *buf)
Definition: chmc.c:1032
void chmc_pmgl_add(struct chmcFile *chm, struct chmcPmglChunkNode *pmgl)
Definition: chmc.c:1467
int chmc_compressed_add_mark(struct chmcFile *chm, UInt64 at)
Definition: chmc.c:1124
int chmc_write(struct chmcFile *chm)
Definition: chmc.c:1625
static void * chmc_syscat_mem(void *d, void *s, unsigned long len)
Definition: chmc.c:628
int chmc_crunch_lzx(struct chmcFile *chm, int sect_id)
Definition: chmc.c:929
#define O_BINARY
Definition: chmc.c:53
void chmc_string_init(struct chmcStringChunk *node)
int chmc_reset_table_done(struct chmcFile *chm)
Definition: chmc.c:1161
void chmc_pmgl_free(struct chmcFile *chm)
Definition: chmc.c:528
void chmc_sections_free(struct chmcFile *chm)
Definition: chmc.c:479
void chmc_pmgl_destroy(struct chmcPmglChunkNode *node)
Definition: chmc.c:1455
int chmc_tree_done(struct chmcFile *chm)
Definition: chmc.c:728
void chmc_control_data_init(struct chmcLzxcControlData *control_data)
Definition: chmc.c:337
struct chmcTreeNode * chmc_add_empty(struct chmcFile *chm, const char *file)
Definition: chmc.c:401
static int _lzx_put_bytes(void *arg, int n, void *buf)
Definition: chmc.c:997
void chmc_pmgl_init(struct chmcPmglChunkNode *node)
Definition: chmc.c:1398
static int _entry_cmp(const void *pva, const void *pvb)
Definition: chmc.c:1231
struct chmcPmglChunkNode * chmc_pmgl_create(void)
Definition: chmc.c:1387
void chmc_pmgi_init(struct chmcPmgiChunkNode *node)
Definition: chmc.c:1420
int chmc_init(struct chmcFile *chm, const char *filename, struct chmcConfig *config)
Definition: chmc.c:133
struct chmcTreeNode * chmc_add_meta(struct chmcFile *chm, const char *metaname, int sect_id, UChar *buf, UInt64 len)
Definition: chmc.c:407
void chmc_pmgi_add(struct chmcFile *chm, struct chmcPmgiChunkNode *pmgi)
Definition: chmc.c:1612
int chmc_pmgi_add_entry(struct chmcFile *chm, const char *name, int pmgl_id)
Definition: chmc.c:1532
struct chmcPmgiChunkNode * chmc_pmgi_create(void)
Definition: chmc.c:1444
int chmc_uncompressed_done(struct chmcFile *chm)
Definition: chmc.c:1240
static const short chmc_transform_list[]
Definition: chmc.c:128
void chmc_entries_qsort(struct chmcFile *chm)
Definition: chmc.c:1210
void chmc_entries_free(struct chmcFile *chm)
Definition: chmc.c:542
struct chmcTreeNode * chmc_add_file(struct chmcFile *chm, const char *filename, UInt16 prefixlen, int sect_id, UChar *buf, UInt64 len)
Definition: chmc.c:598
void chmc_sections_done(struct chmcFile *chm)
Definition: chmc.c:348
int chmc_pmgi_done(struct chmcFile *chm)
Definition: chmc.c:1492
int chmc_pmgl_add_entry(struct chmcFile *chm, struct chmcTreeNode *entry)
Definition: chmc.c:1275
void chmc_entry_destroy(struct chmcTreeNode *node)
Definition: chmc.c:587
int chmc_section_add(struct chmcFile *chm, const char *name)
Definition: chmc.c:245
int chmc_control_data_done(struct chmcFile *chm)
Definition: chmc.c:1145
#define PACKAGE_STRING
Definition: chmc.c:49
struct chmcSection * chmc_section_create(struct chmcFile *chm, const char *name)
Definition: chmc.c:262
int chmc_system_done(struct chmcFile *chm)
Definition: chmc.c:647
struct chmcSection * chmc_section_lookup(struct chmcFile *chm, int id)
Definition: chmc.c:1368
static void * chmc_syscat_entry(Int16 code, void *d, void *s, Int16 len)
Definition: chmc.c:635
void chmc_pmgi_free(struct chmcFile *chm)
Definition: chmc.c:514
UInt32 chmc_strings_add(struct chmcFile *chm, const char *s)
Definition: chmc.c:558
struct chmcTreeNode * chmc_add_entry(struct chmcFile *chm, const char *name, UInt16 prefixlen, int sect_id, UChar *buf, UInt64 offset, UInt64 len)
Definition: chmc.c:429
void chmc_pmgl_done(struct chmcFile *chm)
Definition: chmc.c:1262
void chmc_section_destroy(struct chmcSection *section)
Definition: chmc.c:493
static int _lzx_at_eof(void *arg)
Definition: chmc.c:990
#define CHMC_TNFL_STATIC
Definition: chmc.h:164
#define SIEC_LCASEFILE
Definition: chmc.h:68
#define SIEC_NUMOFINFOT
Definition: chmc.h:75
#define SIEC_INFOCHKSUM
Definition: chmc.h:80
#define SIEC_SYSINFO
Definition: chmc.h:85
#define SIEC_DEFTOPIC
Definition: chmc.h:66
#define SIEC_TITLE
Definition: chmc.h:67
#define _CHMC_RSTTBL_MARK
Definition: chmc.h:230
#define SIEC_IDXHDR
Definition: chmc.h:78
#define CHMC_SYSTEM_UUID
Definition: chmc.h:38
#define _CHMC_CHUNK_LEN
Definition: chmc.h:133
#define SIEC_DEFWINDOW
Definition: chmc.h:69
#define _CHMC_SYSTEM_HDR_LEN
Definition: chmc.h:123
#define SIEC_COMPVER
Definition: chmc.h:84
#define CHMC_MS_LCID_EN_US
Definition: chmc.h:121
#define CHMC_PMGL_DATA_LEN
Definition: chmc.h:134
#define CHMC_STREAM_UUID
Definition: chmc.h:36
#define CHMC_DIR_UUID
Definition: chmc.h:34
#define CHMC_PMGI_DATA_LEN
Definition: chmc.h:149
#define chmc_dump(fmt,...)
Definition: chmc.h:263
#define SIEC_TIMESTAMP
Definition: chmc.h:83
Definition: list.h:37
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
struct config_s config
#define NULL
Definition: types.h:112
UINT32 uint32_t
Definition: types.h:75
unsigned int idx
Definition: utils.c:41
SYSTEM_INFO sysinfo
Definition: dbghelp.c:76
#define assert(x)
Definition: debug.h:53
#define INIT_LIST_HEAD(ptr)
Definition: list.h:24
#define list_entry(ptr, type, member)
Definition: list.h:185
#define list_for_each_safe(pos, n, head)
Definition: list.h:211
static void list_del(struct list_head *entry)
Definition: list.h:89
__kernel_off_t off_t
Definition: linux.h:201
static int chmc_encint(const UInt32 val, UChar *out)
Definition: encint.h:46
static int chmc_decint(const UChar *in, UInt32 *value)
Definition: encint.h:78
static int chmc_encint_len(const UInt32 val)
Definition: encint.h:28
GLdouble s
Definition: gl.h:2039
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLsizeiptr size
Definition: glext.h:5919
GLdouble n
Definition: glext.h:7729
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint in
Definition: glext.h:9616
GLuint GLfloat * val
Definition: glext.h:7180
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLintptr offset
Definition: glext.h:5920
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define O_RDWR
Definition: fcntl.h:36
#define stdout
Definition: stdio.h:99
#define stderr
Definition: stdio.h:100
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
const char * filename
Definition: ioapi.h:137
char hdr[14]
Definition: iptest.cpp:33
uint32_t entry
Definition: isohybrid.c:63
static DWORD block_size(DWORD block)
Definition: jsutils.c:66
#define d
Definition: ke_i.h:81
#define unlink
Definition: syshdrs.h:54
if(dx< 0)
Definition: linetemp.h:194
int lzx_finish(struct lzx_data *lzxd, struct lzx_results *lzxr)
Definition: lzx_layer.c:1236
int lzx_init(struct lzx_data **lzxdp, int wsize_code, lzx_get_bytes_t get_bytes, void *get_bytes_arg, lzx_at_eof_t at_eof, lzx_put_bytes_t put_bytes, void *put_bytes_arg, lzx_mark_frame_t mark_frame, void *mark_frame_arg)
Definition: lzx_layer.c:1189
int lzx_compress_block(lzx_data *lzxd, int block_size, int subdivide)
Definition: lzx_layer.c:1062
void lzx_reset(lzx_data *lzxd)
Definition: lzx_layer.c:1053
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
struct task_struct * current
Definition: linux.c:32
#define BUG_ON(c)
Definition: module.h:255
#define sprintf(buf, format,...)
Definition: sprintf.c:55
BOOL todo
Definition: filedlg.c:313
static int ** pa
Definition: server.c:126
#define ctrl
Definition: input.c:1756
int mkstemps(char *template, int suffix_len)
Definition: mkstemps.c:73
const char * strerror(int err)
Definition: compat_str.c:23
int k
Definition: mpi.c:3369
#define calloc
Definition: rosglue.h:14
static calc_node_t temp
Definition: rpn_ieee.c:38
#define errno
Definition: errno.h:18
int __cdecl system(_In_opt_z_ const char *_Command)
_Check_return_ _CRTIMP char *__cdecl strdup(_In_opt_z_ const char *_Src)
#define memset(x, y, z)
Definition: compat.h:39
int chmcerr_code(void)
Definition: err.c:42
void chmcerr_set(int code, const char *fmt,...)
Definition: err.c:50
void chmcerr_clean(void)
Definition: err.c:37
#define CHMC_NOERR
Definition: err.h:39
#define chmc_error(fmt,...)
Definition: err.h:48
#define chmcerr_set_return(code, fmt,...)
Definition: err.h:67
#define chmcerr_return_msg(fmt,...)
Definition: err.h:50
#define CHMC_ENOMEM
Definition: err.h:40
#define CHMC_EINVAL
Definition: err.h:41
#define chmcerr_msg(fmt,...)
Definition: err.h:59
void __cdecl qsort(_Inout_updates_bytes_(_NumOfElements *_SizeOfElements) void *_Base, _In_ size_t _NumOfElements, _In_ size_t _SizeOfElements, _In_ int(__cdecl *_PtFuncCompare)(const void *, const void *))
static char tmpdir[MAX_PATH]
Definition: shlexec.c:52
Definition: chmc.h:192
int entries_num
Definition: chmc.h:203
struct list_head entries_list
Definition: chmc.h:202
struct chmcSection ** sections
Definition: chmc.h:199
struct chmcItsfHeader itsf
Definition: chmc.h:194
struct chmcSystem system
Definition: chmc.h:207
int fd
Definition: chmc.h:193
struct chmcConfig * config
Definition: chmc.h:212
struct chmcPmglChunkNode * pmgl_last
Definition: chmc.h:201
struct chmcTreeNode ** sort_entries
Definition: chmc.h:204
struct list_head pmgl_list
Definition: chmc.h:200
UInt32 strings_offset
Definition: chmc.h:210
struct chmcSect0 sect0
Definition: chmc.h:195
struct chmcIndexHeader idxhdr
Definition: chmc.h:208
struct chmcPmgiChunkNode * pmgi_last
Definition: chmc.h:206
int sections_num
Definition: chmc.h:197
struct chmcItspHeader itsp
Definition: chmc.h:196
struct list_head sections_list
Definition: chmc.h:198
UChar * strings
Definition: chmc.h:209
UInt32 strings_len
Definition: chmc.h:211
struct list_head pmgi_list
Definition: chmc.h:205
Int32 win_style
Definition: chmc.h:53
Int32 unknown_4
Definition: chmc.h:43
Int32 unknown_8
Definition: chmc.h:44
Int32 ex_win_style
Definition: chmc.h:54
Int32 background
Definition: chmc.h:50
Int32 off_img_list
Definition: chmc.h:47
Int32 foreground
Definition: chmc.h:51
Int32 off_font
Definition: chmc.h:52
Int32 unknown_44
Definition: chmc.h:59
char signature[4]
Definition: chmc.h:42
Int32 off_frame_name
Definition: chmc.h:56
Int32 off_win_name
Definition: chmc.h:57
Int32 unknown_34
Definition: chmc.h:55
Int32 unknown_000c
Definition: chm.h:94
Int32 version
Definition: chm.h:92
UInt64 sect0_offset
Definition: chm.h:99
UChar stream_uuid[16]
Definition: chm.h:98
UInt64 dir_offset
Definition: chm.h:101
UInt64 data_offset
Definition: chm.h:103
char signature[4]
Definition: chm.h:91
UChar dir_uuid[16]
Definition: chm.h:97
UInt64 dir_len
Definition: chm.h:102
UInt32 lang_id
Definition: chm.h:96
Int32 header_len
Definition: chm.h:93
UInt64 sect0_len
Definition: chm.h:100
char signature[4]
Definition: chm.h:120
UInt32 block_len
Definition: chm.h:124
UInt32 num_blocks
Definition: chm.h:131
Int32 version
Definition: chm.h:121
Int32 index_depth
Definition: chm.h:126
UInt32 header_len2
Definition: chm.h:134
Int32 unknown_000c
Definition: chm.h:123
UInt32 lang_id
Definition: chm.h:132
UChar unknown_0048[12]
Definition: chm.h:135
Int32 index_root
Definition: chm.h:127
Int32 header_len
Definition: chm.h:122
Int32 unknown_0028
Definition: chm.h:130
UChar system_uuid[16]
Definition: chm.h:133
Int32 index_last
Definition: chm.h:129
Int32 blockidx_intvl
Definition: chm.h:125
UInt32 done
Definition: chmc.c:121
struct chmcSection * section
Definition: chmc.c:118
UInt32 fd_offset
Definition: chmc.c:120
int eof
Definition: chmc.c:125
int error
Definition: chmc.c:124
struct chmcFile * chm
Definition: chmc.c:117
int fd
Definition: chmc.c:119
UInt32 todo
Definition: chmc.c:122
struct list_head * pos
Definition: chmc.c:123
UInt32 version
Definition: chm.h:158
UInt32 entry_size
Definition: chm.h:160
UInt64 compressed_len
Definition: chm.h:163
UInt32 table_offset
Definition: chm.h:161
UInt64 uncompressed_len
Definition: chm.h:162
UInt32 block_count
Definition: chm.h:159
UInt64 block_len
Definition: chm.h:164
struct list_head list
Definition: chmc.h:158
struct chmcPmgiChunk chunk
Definition: chmc.h:161
struct chmcPmglChunk chunk
Definition: chmc.h:146
struct list_head list
Definition: chmc.h:143
struct list_head list
Definition: chmc.h:234
Definition: chm.h:107
UInt64 file_len
Definition: chm.h:110
Int32 unknown_0000
Definition: chm.h:108
struct chmcLzxcControlData control_data
Definition: chmc.h:225
UInt32 strings_offset
Definition: chmc.h:250
short unknown
Definition: chmc.h:253
UInt32 urltbl_offset
Definition: chmc.h:251
short in_content
Definition: chmc.h:252
UInt32 tocidx_offset
Definition: chmc.h:249
UInt32 sect_id
Definition: chmc.h:169
UInt16 prefixlen
Definition: chmc.h:171
UInt32 framename_offset
Definition: chmc.h:239
UInt32 url_offset
Definition: chmc.h:238
Definition: inflate.c:139
Definition: fci.c:127
Definition: list.h:15
Definition: name.c:39
Definition: parser.c:56
const WCHAR * name
Definition: parser.c:57
Definition: stat.h:55
_off_t st_size
Definition: stat.h:63
Definition: dlist.c:348