ReactOS  0.4.15-dev-489-g75a0787
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 
56 int chmc_section_add(struct chmcFile *chm, const char *name);
57 struct chmcSection * chmc_section_create(struct chmcFile *chm,
58  const char *name);
59 void chmc_reset_table_init(struct chmcLzxcResetTable *reset_table);
61 int chmc_namelist_create(struct chmcFile *chm, int len);
62 struct chmcTreeNode * chmc_add_meta(struct chmcFile *chm,
63  const char *metaname, int sect_id,
64  UChar *buf, UInt64 len);
65 struct chmcTreeNode *chmc_add_entry(struct chmcFile *chm, const char *name,
68 void chmc_sections_free(struct chmcFile *chm);
70 void chmc_pmgi_free(struct chmcFile *chm);
71 void chmc_pmgl_free(struct chmcFile *chm);
74 void chmc_entries_free(struct chmcFile *chm);
76 int chmc_add_tree(struct chmcFile *chm, const char *dir);
77 struct chmcTreeNode *chmc_add_file(struct chmcFile *chm, const char *filename,
79  UInt64 len);
80 struct chmcTreeNode *chmc_add_dir(struct chmcFile *chm, const char *dir);
81 struct chmcTreeNode *chmc_add_empty(struct chmcFile *chm, const char *file);
82 
83 int chmc_crunch_lzx(struct chmcFile *chm, int sect_id);
84 static int _lzx_at_eof(void *arg);
85 static int _lzx_put_bytes(void *arg, int n, void *buf);
86 static void _lzx_mark_frame(void *arg, uint32_t uncomp, uint32_t comp);
87 static int _lzx_get_bytes(void *arg, int n, void *buf);
88 
89 int chmc_compressed_add_mark(struct chmcFile *chm, UInt64 at);
90 int chmc_control_data_done(struct chmcFile *chm);
91 int chmc_reset_table_done(struct chmcFile *chm);
92 void chmc_pmgl_done(struct chmcFile *chm);
93 
94 void chmc_entries_qsort(struct chmcFile *chm);
95 static int _entry_cmp(const void *pva, const void *pvb);
96 
97 struct chmcSection *chmc_section_lookup(struct chmcFile *chm, int id);
98 
100 void chmc_pmgl_add(struct chmcFile *chm, struct chmcPmglChunkNode *pmgl);
102 int chmc_pmgi_add_entry(struct chmcFile *chm, const char *name, int pmgl_id);
103 void chmc_pmgi_add(struct chmcFile *chm, struct chmcPmgiChunkNode *pmgi);
105 
106 #ifdef __REACTOS__
107 int chmc_uncompressed_done(struct chmcFile *chm);
108 int chmc_pmgi_done(struct chmcFile *chm);
109 int chmc_write(struct chmcFile *chm);
110 int chmc_appendfile(struct chmcFile *chm, const char *filename, void *buf,
111  size_t size );
112 int 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 
128 static 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 
133 int 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);
144  assert(filename);
145 
146  chmcerr_clean();
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);
169  memcpy(itsf->stream_uuid, CHMC_STREAM_UUID, 16);
171 
173  itsf->sect0_len = _CHMC_SECT0_LEN;
174 
175  sect0->file_len = _CHMC_ITSF_V3_LEN
178 
179  sect0->unknown_0000 = 510;
180 
181  memcpy(itsp->signature, "ITSP", 4);
182  itsp->version = 1;
184  itsp->unknown_000c = 10;
185  itsp->block_len = _CHMC_CHUNK_LEN;
187  itsp->index_depth = 2;
188 
189  itsp->unknown_0028 = -1;
190  itsp->lang_id = CHMC_MS_LCID_EN_US;
191  memcpy(itsp->system_uuid, CHMC_SYSTEM_UUID, 16);
193  memset(itsp->unknown_0048, -1, 12);
194 
195  system->version = 3;
196  system->_size = _CHMC_SYSTEM_HDR_LEN + sizeof(struct chmcIndexHeader);
197 
198  sysinfo->lcid = CHMC_MS_LCID_EN_US;
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 
225  INIT_LIST_HEAD(&chm->pmgl_list);
227  INIT_LIST_HEAD(&chm->pmgi_list);
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 
240  chmc_sections_done(chm);
241 
242  return CHMC_NOERR;
243 }
244 
245 int 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 
326 void chmc_reset_table_init(struct chmcLzxcResetTable *reset_table)
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 
348 void chmc_sections_done(struct chmcFile *chm)
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;
363  section = list_entry(pos, struct chmcSection, list);
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 
372 int 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 
401 struct 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 
407 struct chmcTreeNode *chmc_add_meta(struct chmcFile *chm, const char *metaname,
408  int sect_id,
409  UChar *buf, UInt64 len)
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 
429 struct 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 
461 void chmc_term(struct chmcFile *chm)
462 {
463  assert(chm);
464  assert(chm->fd > -1);
465 
466  free(chm->strings);
467 
468  chmc_entries_free(chm);
469  chmc_pmgl_free(chm);
470  chmc_pmgi_free(chm);
471  if (chm->sections)
472  free(chm->sections);
473  chmc_sections_free(chm);
474 
475  if (chm->fd != fileno(stdout))
476  close(chm->fd);
477 }
478 
479 void chmc_sections_free(struct chmcFile *chm)
480 {
481  struct chmcSection *section;
482  struct list_head *pos, *q;
483 
484  assert(chm);
485 
487  section = list_entry(pos, struct chmcSection, list);
488  list_del(pos);
490  }
491 }
492 
494 {
495  assert(section);
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 
514 void chmc_pmgi_free(struct chmcFile *chm)
515 {
516  struct chmcPmgiChunkNode *node;
517  struct list_head *pos, *q;
518 
519  assert(chm);
520 
521  list_for_each_safe(pos, q, &chm->pmgi_list) {
523  list_del(pos);
525  }
526 }
527 
528 void chmc_pmgl_free(struct chmcFile *chm)
529 {
530  struct chmcPmglChunkNode *node;
531  struct list_head *pos, *q;
532 
533  assert(chm);
534 
535  list_for_each_safe(pos, q, &chm->pmgl_list) {
537  list_del(pos);
539  }
540 }
541 
542 void 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 
558 UInt32 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 
598 struct 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 
621 struct 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 
628 static 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 
635 static 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 
647 int chmc_system_done(struct chmcFile *chm)
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;
708  p = chmc_syscat_entry(SIEC_NUMOFINFOT, p, &val, sizeof(val));
709 
711  idxhdr, sizeof(struct chmcIndexHeader));
712 
713 
714  val = 0;
715  p = chmc_syscat_entry(SIEC_INFOCHKSUM, p, &val, sizeof(val));
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 
728 int 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 
897  chmc_entries_qsort(chm);
899  chmc_pmgl_done(chm);
900 
901  chmc_pmgi_done(chm);
902 
903  itsf->dir_len = _CHMC_ITSP_V1_LEN
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 
921  section = list_entry(pos, struct chmcSection, list);
922  chmc_appendfile(chm, section->filename, buf, 4096);
923  }
924  }
925 
926  return CHMC_NOERR;
927 }
928 
929 int 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  if ((wsize_code < 15) || (wsize_code > 21)) {
943  fprintf(stderr, "window size must be between 15 and 21 inclusive\n");
944  return CHMC_EINVAL;
945  }
946 
947  lzx_info.chm = chm;
948  lzx_info.section = chm->sections[sect_id];
949  lzx_info.done = 0;
950  lzx_info.todo = lzx_info.section->offset;
951  lzx_info.pos = chm->entries_list.next;
952  lzx_info.error = 0;
953  lzx_info.eof = 0;
954 
955  lzx_info.fd = -1;
956  lzx_info.fd_offset = 0;
957 
958  chmc_compressed_add_mark(lzx_info.chm, 0);
959  lzx_info.section->reset_table_header.block_count++;
960 
961  /* undocumented fact, according to Caie --
962  block size cannot exceed window size. (why not?) */
963  /* The block size must not be larger than the window size.
964  While the compressor will create apparently-valid LZX files
965  if this restriction is violated, some decompressors
966  will not handle them. */
967 
968  block_size = 1 << wsize_code;
969 
970  // lzx_info.section->control_data.windowSize = wsize_code;
971  // lzx_info.section->control_data.windowsPerReset = block_size;
972 
973  lzx_init(&lzxd, wsize_code,
974  _lzx_get_bytes, &lzx_info, _lzx_at_eof,
975  _lzx_put_bytes, &lzx_info,
976  _lzx_mark_frame, &lzx_info);
977 
978  while(! _lzx_at_eof(&lzx_info)) {
979  if (do_reset)
980  lzx_reset(lzxd);
981  lzx_compress_block(lzxd, block_size, subd_ok);
982  }
983  lzx_finish(lzxd, &lzxr);
984 
985  return CHMC_NOERR;
986 }
987 
988 static int _lzx_at_eof(void *arg)
989 {
990  struct chmcLzxInfo *lzx_info = (struct chmcLzxInfo *)arg;
991 
992  return lzx_info->error || lzx_info->done >= lzx_info->todo || lzx_info->eof;
993 }
994 
995 static int _lzx_put_bytes(void *arg, int n, void *buf)
996 {
997  struct chmcLzxInfo *lzx_info = (struct chmcLzxInfo *)arg;
998  struct chmcSect0 *sect0 = &lzx_info->chm->sect0;
999  int wx;
1000  static int counter = 0;
1001 
1002  counter += n;
1003  wx = write(lzx_info->section->fd, buf, n);
1004  sect0->file_len += wx;
1005  lzx_info->section->len += wx;
1006 
1007  return wx;
1008 }
1009 
1010 static void _lzx_mark_frame(void *arg, uint32_t uncomp, uint32_t comp)
1011 {
1012  struct chmcLzxInfo *lzx_info = (struct chmcLzxInfo *)arg;
1013  struct chmcSection *section = lzx_info->chm->sections[1];
1014 
1015  UInt64 compressed;
1016 
1017  chmc_dump( "Aligned data at %d(in compressed stream, %d) (%lu/%lu)\n",
1018  uncomp, comp, (unsigned long)lzx_info->done, (unsigned long)lzx_info->todo );
1019 
1020  compressed = comp;
1021 
1022  section->reset_table_header.block_count++;
1023 
1024  chmc_compressed_add_mark( lzx_info->chm, compressed );
1025 
1026  section->reset_table_header.uncompressed_len = uncomp;
1027  section->reset_table_header.compressed_len = comp;
1028 }
1029 
1030 static int _lzx_get_bytes(void *arg, int n, void *buf)
1031 {
1032  struct chmcLzxInfo *lzx_info = (struct chmcLzxInfo *)arg;
1033  struct chmcFile *chm = lzx_info->chm;
1034  struct chmcTreeNode *node;
1035 
1036  int todo;
1037  int done;
1038  int toread;
1039  int rx;
1040 
1041  todo = n;
1042  done = 0;
1043 
1044  // compression state machine
1045  // lzx compressor ask for block input bytes
1046  // need to keep current entry file and offset trought blocks
1047  // until last entry
1048  while (todo) {
1049  // end of entries reached?
1050  if (lzx_info->pos == &chm->entries_list) {
1051  lzx_info->eof = 1;
1052  break;
1053  }
1054 
1055  node = list_entry( lzx_info->pos, struct chmcTreeNode, list );
1056 
1057  // skip empty files and directories
1058  if (node->len == 0
1059  || strcmp("MSCompressed", chm->sections[node->sect_id]->name)) {
1060  lzx_info->pos = lzx_info->pos->next;
1061  continue;
1062  }
1063  else
1064  if (node->buf) {
1065  // have len and buffer, it's mallocated not file
1066  }
1067  else
1068  if (lzx_info->fd == -1) {
1069  // open file if it isn't
1070  lzx_info->fd = open(node->name, O_RDONLY | O_BINARY);
1071  if (lzx_info->fd < 0) {
1072  chmc_error("%s: %d: error %d: '%s' %s\n",
1073  __FILE__, __LINE__,
1074  errno, node->name, strerror(errno));
1075  lzx_info->error = 1;
1076  break;
1077  }
1078  }
1079 
1080  // read till the end of the file or till the lzx buffer is filled
1081  toread = node->len - lzx_info->fd_offset;
1082  if (toread > todo)
1083  toread = todo;
1084 
1085  if (toread <= 0)
1086  continue;
1087 
1088  // read input
1089  if (node->buf) {
1090  memcpy((char *)buf + (n - todo), &node->buf[lzx_info->fd_offset], toread);
1091  rx = toread;
1092  }
1093  else
1094  {
1095  rx = read(lzx_info->fd, (char *)buf + (n - todo), toread);
1096  if (rx <= 0) {
1097  int temp = errno;
1098  chmc_error("read error %s \n", strerror(temp));
1099  lzx_info->error = 2;
1100  break;
1101  }
1102  }
1103 
1104  todo -= rx;
1105  lzx_info->fd_offset += rx;
1106  done += rx;
1107  lzx_info->done += rx;
1108 
1109  // end of current file reached, goto next entry
1110  if (lzx_info->fd_offset == node->len) {
1111  if (lzx_info->fd > -1)
1112  close(lzx_info->fd);
1113  lzx_info->fd = -1;
1114  lzx_info->fd_offset = 0;
1115  lzx_info->pos = lzx_info->pos->next;
1116  }
1117  }
1118 
1119  return done;
1120 }
1121 
1123 {
1124  struct chmcSection *section;
1125  struct chmcResetTableMark *mark;
1126 
1127  assert(chm);
1128 
1129  section = chm->sections[1];
1130 
1131  mark = malloc(_CHMC_RSTTBL_MARK);
1132  if (mark) {
1133  mark->at = at;
1134  chmc_dump("[%d] at: %jd\n", section->mark_count, at);
1135  list_add_tail(&mark->list, &section->mark_list);
1136  section->mark_count++;
1137  return CHMC_NOERR;
1138  }
1139 
1140  return CHMC_ENOMEM;
1141 }
1142 
1144 {
1145  struct chmcTreeNode *ctrl;
1146 
1147  ctrl = chmc_add_meta(chm, "::DataSpace/Storage/MSCompressed/ControlData",
1148  0, (UChar *)&chm->sections[1]->control_data,
1150 
1151  if (ctrl) {
1152  ctrl->flags |= CHMC_TNFL_STATIC;
1153  return CHMC_NOERR;
1154  }
1155 
1156  return CHMC_ENOMEM;
1157 }
1158 
1160 {
1161  struct chmcSection *section;
1162  struct chmcLzxcResetTable *reset_table;
1163  struct list_head *pos;
1164  struct chmcResetTableMark *mark;
1165 
1166  UInt64 *at;
1167  int i, len;
1168 
1169  section = chm->sections[1];
1170 
1171  len = _CHMC_LZXC_RESETTABLE_V1_LEN + (section->mark_count * sizeof(UInt64));
1172 
1173  reset_table = malloc(len);
1174 
1175  if (reset_table) {
1176  memcpy(reset_table, &section->reset_table_header,
1178  at = (void *)((char *)reset_table + _CHMC_LZXC_RESETTABLE_V1_LEN);
1179 
1180  i = 0;
1181  list_for_each(pos, &section->mark_list) {
1182  mark = list_entry(pos, struct chmcResetTableMark, list);
1183  at[i++] = mark->at;
1184  }
1185 
1186  chmc_add_dir(chm, "::DataSpace/Storage/MSCompressed/Transform/"
1187  "{7FC28940-9D31-11D0-9B27-00A0C91E9C7C}/InstanceData/");
1188  chmc_add_meta(chm, "::DataSpace/Storage/MSCompressed/Transform/"
1189  "{7FC28940-9D31-11D0-9B27-00A0C91E9C7C}"
1190  "/InstanceData/ResetTable",
1191  0, (UChar *)reset_table, len);
1192 
1193  { // TODO FIXME do better
1194  UInt64 *uncompressed_len = malloc(8);
1195  if (uncompressed_len) {
1196  *uncompressed_len = reset_table->uncompressed_len;
1197  chmc_add_meta(chm, "::DataSpace/Storage/MSCompressed/SpanInfo",
1198  0, (UChar *)uncompressed_len, 8);
1199  }
1200  }
1201 
1202  return CHMC_NOERR;
1203  }
1204 
1205  return CHMC_ENOMEM;
1206 }
1207 
1208 void chmc_entries_qsort(struct chmcFile *chm)
1209 {
1210  struct chmcTreeNode *node;
1211  struct list_head *pos;
1212  int i;
1213 
1214  assert(chm);
1215 
1216  chm->sort_entries = malloc(sizeof(struct chmcTreeNode *)
1217  * chm->entries_num);
1218 
1219  i = 0;
1220  list_for_each(pos, &chm->entries_list) {
1221  node = list_entry(pos, struct chmcTreeNode, list);
1222  chm->sort_entries[i++] = node;
1223  }
1224 
1225  qsort(chm->sort_entries, chm->entries_num, sizeof(struct chmcTreeNode *),
1226  _entry_cmp);
1227 }
1228 
1229 static int _entry_cmp(const void *pva, const void *pvb)
1230 {
1231  const struct chmcTreeNode * const *pa = pva;
1232  const struct chmcTreeNode * const *pb = pvb;
1233  const struct chmcTreeNode *a = *pa, *b = *pb;
1234 
1235  return strcmp( &a->name[a->prefixlen], &b->name[b->prefixlen] );
1236 }
1237 
1239 {
1240  struct chmcSect0 *sect0 = &chm->sect0;
1241  struct chmcTreeNode *node;
1242  struct list_head *pos;
1243  int wx;
1244 
1245  list_for_each(pos, &chm->entries_list) {
1246  node = list_entry( pos, struct chmcTreeNode, list );
1247 
1248  if (strcmp( "MSCompressed", chm->sections[node->sect_id]->name ) == 0)
1249  continue;
1250 
1251  if ((node->buf) && (node->len > 0)) {
1252  wx = write(chm->sections[node->sect_id]->fd, node->buf, node->len);
1253  sect0->file_len += wx;
1254  }
1255  }
1256 
1257  return CHMC_NOERR;
1258 }
1259 
1260 void chmc_pmgl_done(struct chmcFile *chm)
1261 {
1262  struct chmcTreeNode *entry;
1263  int i;
1264 
1265  assert(chm);
1266 
1267  for(i=0; i < chm->entries_num; i++) {
1268  entry = chm->sort_entries[i];
1269  chmc_pmgl_add_entry(chm, entry);
1270  }
1271 }
1272 
1274 {
1275  struct chmcPmglChunkNode *pmgl;
1276  struct chmcPmglChunk *chunk;
1277  struct chmcSection *section;
1278  struct chmcItspHeader *itsp = &chm->itsp;
1279 
1280  UChar *p;
1281  UInt16 *idx;
1282  int name_len;
1283  int outlen;
1284  int should_idx, idx_intlv;
1285  int free;
1286 
1287  assert(chm);
1288  assert(entry);
1289 
1290  // check section bound
1291  section = chmc_section_lookup(chm, entry->sect_id);
1292  if (!section)
1293  chmcerr_set_return(CHMC_ENOMEM, "section %d lookup failed: ",
1294  entry->sect_id);
1295 
1296  // check chunk space for new entry
1297  name_len = strlen(&entry->name[entry->prefixlen]);
1298 
1299  outlen = chmc_encint_len(name_len);
1300  outlen += name_len;
1301  outlen += chmc_encint_len(entry->sect_id);
1302  outlen += chmc_encint_len(entry->offset);
1303  outlen += chmc_encint_len(entry->len);
1304 
1305  // look for current pmgl chunk, create if doesn't exist
1306  if (!chm->pmgl_last) {
1307  pmgl = chmc_pmgl_create();
1308  if (pmgl)
1309  chmc_pmgl_add(chm, pmgl);
1310  else
1311  chmcerr_set_return(CHMC_ENOMEM, "pmgl chunk: ");
1312  }
1313  else
1314  pmgl = chm->pmgl_last;
1315 
1316  do {
1317 
1318  chunk = &chm->pmgl_last->chunk;
1319 
1320  idx_intlv = 1 + ( 1 << itsp->blockidx_intvl );
1321  should_idx = ( ( chunk->entries_count > 0 )
1322  && ! ( ( chunk->entries_count + 1 ) % idx_intlv )
1323  ? 2 : 0 );
1324 
1325  free = sizeof(chunk->data) - pmgl->data_len - pmgl->index_len
1326  - should_idx;
1327 
1328  // current(last) chunk doesn't have enough room? force new one
1329  if (outlen + should_idx > free) {
1330  //chm->pmgl_last = NULL;
1331  pmgl = chmc_pmgl_create();
1332  if ( pmgl )
1333  chmc_pmgl_add(chm, pmgl);
1334  else
1335  chmcerr_set_return(CHMC_ENOMEM, "pmgl chunk: ");
1336 
1337  continue;
1338  }
1339 
1340  p = (void *)&chunk->data[pmgl->data_len];
1341 
1342  if (should_idx) {
1343  idx = (void *)((char *)&chunk->data[CHMC_PMGL_DATA_LEN] - pmgl->index_len);
1344  *idx = (char *)p - (char *)&chunk->data;
1345  }
1346 
1347  p += chmc_encint(name_len, p);
1348  memcpy(p, &entry->name[entry->prefixlen], name_len);
1349  p += name_len;
1350  p += chmc_encint(entry->sect_id, p);
1351  p += chmc_encint(entry->offset, p);
1352  p += chmc_encint(entry->len, p);
1353 
1354  pmgl->data_len += outlen;
1355  pmgl->index_len += should_idx;
1356 
1357  chunk->entries_count++;
1358  chunk->header.free_space -= outlen;
1359  break;
1360 
1361  } while (1);
1362 
1363  return CHMC_NOERR;
1364 }
1365 
1366 struct chmcSection *chmc_section_lookup(struct chmcFile *chm, int id)
1367 {
1368  struct chmcSection *current;
1369  struct list_head *pos;
1370  int i;
1371 
1372  assert(chm);
1373 
1374  i = 0;
1375  list_for_each(pos, &chm->sections_list) {
1376  current = list_entry(pos, struct chmcSection, list);
1377  if (i == id)
1378  return current;
1379  i++;
1380  }
1381 
1382  return NULL;
1383 }
1384 
1386 {
1387  struct chmcPmglChunkNode *node;
1388 
1389  node = malloc(sizeof(struct chmcPmglChunkNode));
1390  if (node)
1392 
1393  return node;
1394 }
1395 
1397 {
1398  struct chmcPmglChunk *chunk;
1399 
1400  assert(node);
1401 
1402  node->data_len = 0;
1403  node->index_len = 0;
1404 
1405  chunk = &node->chunk;
1406 
1407  memcpy(chunk->header.signature, "PMGL", 4);
1408 
1409  // FIXME check it is the right len
1410  chunk->header.free_space = CHMC_PMGL_DATA_LEN + 2;
1411  chunk->header.unknown_0008 = 0;
1412  chunk->header.block_prev = -1;
1413  chunk->header.block_next = -1;
1414 
1415  memset(chunk->data, 0, CHMC_PMGL_DATA_LEN);
1416 }
1417 
1419 {
1420  struct chmcPmgiChunk *chunk;
1421 
1422  assert(node);
1423 
1424  node->data_len = 0;
1425  node->index_len = 0;
1426 
1427  chunk = &node->chunk;
1428 
1429  memcpy(chunk->header.signature, "PMGI", 4);
1430 
1431  // FIXME check it is the right len
1432  chunk->header.free_space = CHMC_PMGI_DATA_LEN + 2;
1433  // chunk->header.unknown_0008 = 0;
1434  // chunk->header.block_prev = -1;
1435  // chunk->header.block_next = -1;
1436 
1437  memset(chunk->data, 0, CHMC_PMGI_DATA_LEN);
1438 }
1439 
1440 
1441 
1443 {
1444  struct chmcPmgiChunkNode *node;
1445 
1446  node = malloc(sizeof(struct chmcPmgiChunkNode));
1447  if (node)
1449 
1450  return node;
1451 }
1452 
1454 {
1455  assert(node);
1456  free(node);
1457 }
1458 
1460 {
1461  assert(node);
1462  free(node);
1463 }
1464 
1465 void chmc_pmgl_add(struct chmcFile *chm, struct chmcPmglChunkNode *pmgl)
1466 {
1467  struct chmcItspHeader *itsp = &chm->itsp;
1468  struct chmcPmglHeader *hdr;
1469 
1470  assert(chm);
1471  assert(pmgl);
1472 
1473  list_add_tail(&pmgl->list, &chm->pmgl_list);
1474 
1475  itsp->index_last = itsp->num_blocks;
1476 
1477  hdr = &pmgl->chunk.header;
1478  hdr->block_prev = itsp->num_blocks - 1;
1479 
1480  if (chm->pmgl_last) {
1481  hdr = &chm->pmgl_last->chunk.header;
1482  hdr->block_next = itsp->num_blocks;
1483  }
1484 
1485  itsp->num_blocks++;
1486 
1487  chm->pmgl_last = pmgl;
1488 }
1489 
1490 int chmc_pmgi_done(struct chmcFile *chm)
1491 {
1492  struct chmcItspHeader *itsp = &chm->itsp;
1493  struct chmcPmglChunkNode *pmgl;
1494  struct list_head *pos;
1495 
1496  int i, j;
1497  char name[256]; //FIXME use malloc
1498  UInt32 name_len;
1499 
1500  assert(chm);
1501 
1502  // only one pml, omitted pmgi
1503  if (itsp->num_blocks == 1) {
1504  itsp->index_depth = 1;
1505  itsp->index_root = -1;
1506  itsp->index_last = 0;
1507  return CHMC_NOERR;
1508  }
1509 
1510  itsp->index_root = itsp->num_blocks;
1511 
1512  i = 0;
1513  list_for_each(pos, &chm->pmgl_list) {
1514  pmgl = list_entry(pos, struct chmcPmglChunkNode, list);
1515  j = chmc_decint(&pmgl->chunk.data[0], &name_len);
1516  if (name_len <= 255) {
1517  memcpy(name, &pmgl->chunk.data[j], name_len);
1518  name[name_len] = '\0';
1519  chmc_pmgi_add_entry(chm, name, i);
1520  }
1521  else
1522  BUG_ON("name_len >= 255(%lu) %.*s\n", (unsigned long)name_len, 255,
1523  &pmgl->chunk.data[j]);
1524  i++;
1525  }
1526 
1527  return CHMC_NOERR;
1528 }
1529 
1530 int chmc_pmgi_add_entry(struct chmcFile *chm, const char *name, int pmgl_id)
1531 {
1532  struct chmcPmgiChunkNode *pmgi;
1533  struct chmcPmgiChunk *chunk;
1534  struct chmcItspHeader *itsp = &chm->itsp;
1535 
1536  UChar *p;
1537  UInt16 *idx;
1538  int name_len;
1539  int outlen;
1540  int should_idx, idx_intlv;
1541  int free;
1542 
1543  assert(chm);
1544 
1545  // check chunk space for new entry
1546  name_len = strlen(name);
1547 
1548  outlen = chmc_encint_len(name_len);
1549  outlen += name_len;
1550  outlen += chmc_encint_len(pmgl_id);
1551 
1552  // look for current pmgi chunk, create if doesn't exist
1553  if (!chm->pmgi_last) {
1554  pmgi = chmc_pmgi_create();
1555  if (pmgi)
1556  chmc_pmgi_add(chm, pmgi);
1557  else
1558  chmcerr_set_return(CHMC_ENOMEM, "pmgi chunk: ");
1559  }
1560  else
1561  pmgi = chm->pmgi_last;
1562 
1563  do {
1564 
1565  chunk = &chm->pmgi_last->chunk;
1566 
1567  idx_intlv = 1 + ( 1 << itsp->blockidx_intvl );
1568  should_idx = ( ( chunk->entries_count > 0 )
1569  && ! ( ( chunk->entries_count + 1 ) % idx_intlv )
1570  ? 2 : 0 );
1571 
1572  free = sizeof(chunk->data) - pmgi->data_len -
1573  pmgi->index_len - should_idx;
1574 
1575  // current(last) chunk doesn't have enough room? force new one
1576  if (outlen + should_idx > free) {
1577  pmgi = chmc_pmgi_create();
1578  if (pmgi)
1579  chmc_pmgi_add(chm, pmgi);
1580  else
1581  chmcerr_set_return(CHMC_ENOMEM, "pmgi chunk: ");
1582 
1583  continue;
1584  }
1585 
1586  p = (void *)&chunk->data[pmgi->data_len];
1587 
1588  if (should_idx) {
1589  idx = (void *)((char *)&chunk->data[CHMC_PMGI_DATA_LEN] - pmgi->index_len);
1590  *idx = (char *)p - (char *)&chunk->data;
1591  }
1592 
1593  p += chmc_encint(name_len, p);
1594  memcpy(p, name, name_len);
1595  p += name_len;
1596  p += chmc_encint(pmgl_id, p);
1597 
1598  pmgi->data_len += outlen;
1599  pmgi->index_len += should_idx;
1600 
1601  chunk->entries_count++;
1602  chunk->header.free_space -= outlen;
1603  break;
1604 
1605  } while (1);
1606 
1607  return CHMC_NOERR;
1608 }
1609 
1610 void chmc_pmgi_add(struct chmcFile *chm, struct chmcPmgiChunkNode *pmgi)
1611 {
1612  struct chmcItspHeader *itsp = &chm->itsp;
1613 
1614  assert(chm);
1615  assert(pmgi);
1616 
1617  list_add_tail(&pmgi->list, &chm->pmgi_list);
1618  itsp->num_blocks++;
1619 
1620  chm->pmgi_last = pmgi;
1621 }
1622 
1623 int chmc_write(struct chmcFile *chm)
1624 {
1625  struct chmcItsfHeader *itsf = &chm->itsf;
1626  struct chmcSect0 *sect0 = &chm->sect0;
1627  struct chmcItspHeader *itsp = &chm->itsp;
1628 
1629  struct chmcPmglChunkNode *pmgl;
1630  struct chmcPmgiChunkNode *pmgi;
1631  struct list_head *pos;
1632 
1633  assert(chm);
1634 
1635  chmc_dump("write itsf %d\n", _CHMC_ITSF_V3_LEN);
1636  write(chm->fd, itsf, _CHMC_ITSF_V3_LEN);
1637  chmc_dump("write sect0 %d\n", _CHMC_SECT0_LEN);
1638  write(chm->fd, sect0, _CHMC_SECT0_LEN);
1639  chmc_dump("write itsp %d\n", _CHMC_ITSP_V1_LEN);
1640  write(chm->fd, itsp, _CHMC_ITSP_V1_LEN);
1641 
1642  list_for_each(pos, &chm->pmgl_list) {
1643  pmgl = list_entry(pos, struct chmcPmglChunkNode, list);
1644  chmc_dump("write pmgl %d\n", _CHMC_CHUNK_LEN);
1645  write(chm->fd, &pmgl->chunk, _CHMC_CHUNK_LEN);
1646  }
1647 
1648  chmc_dump("itsp->num_blocks %d", itsp->num_blocks);
1649  if (itsp->num_blocks > 1) {
1650  list_for_each( pos, &chm->pmgi_list ) {
1651  pmgi = list_entry(pos, struct chmcPmgiChunkNode, list);
1652  chmc_dump("write pmgi %d\n", _CHMC_CHUNK_LEN);
1653  write(chm->fd, &pmgi->chunk, _CHMC_CHUNK_LEN);
1654  }
1655  }
1656 
1657  return CHMC_NOERR;
1658 }
1659 
1660 int chmc_appendfile(struct chmcFile *chm, const char *filename, void *buf,
1661  size_t size )
1662 {
1663  struct stat statbuf;
1664  int in;
1665  off_t todo, toread;
1666  int rx;
1667 
1668  if (stat(filename, &statbuf) < 0)
1669  return errno;
1670 
1672  if (in >= 0) {
1673  todo = statbuf.st_size;
1674 
1675  while (todo) {
1676  toread = size;
1677  if (toread > todo)
1678  toread = todo;
1679 
1680  rx = read(in, buf, toread);
1681  if (rx > 0) {
1682  write(chm->fd, buf, rx);
1683  todo -= rx;
1684  }
1685  }
1686 
1687  close(in);
1688  }
1689  else
1690  BUG_ON("open %s\n", filename);
1691 
1692  return CHMC_NOERR;
1693 }
UInt32 tocidx_offset
Definition: chmc.h:249
#define CHMC_ENOMEM
Definition: err.h:40
struct list_head entries_list
Definition: chmc.h:202
#define SIEC_TITLE
Definition: chmc.h:67
static int _entry_cmp(const void *pva, const void *pvb)
Definition: chmc.c:1229
void chmc_term(struct chmcFile *chm)
Definition: chmc.c:461
Int32 off_font
Definition: chmc.h:52
char hdr[14]
Definition: iptest.cpp:33
int eof
Definition: chmc.c:125
struct config_s config
static const short chmc_transform_list[]
Definition: chmc.c:128
#define list_for_each_safe(pos, n, head)
Definition: list.h:211
int entries_num
Definition: chmc.h:203
int chmc_reset_table_done(struct chmcFile *chm)
Definition: chmc.c:1159
int chmc_pmgi_done(struct chmcFile *chm)
Definition: chmc.c:1490
struct chmcLzxcControlData control_data
Definition: chmc.h:225
UInt64 uncompressed_len
Definition: chm.h:159
#define chmc_error(fmt,...)
Definition: err.h:48
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
#define CHM_IDX_INTVL
Definition: chm.h:112
Int32 header_len
Definition: chm.h:90
struct chmcPmglChunk chunk
Definition: chmc.h:146
static void list_del(struct list_head *entry)
Definition: list.h:89
int chmc_write(struct chmcFile *chm)
Definition: chmc.c:1623
UInt32 strings_offset
Definition: chmc.h:210
#define open
Definition: acwin.h:95
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
struct chmcPmgiChunkNode * pmgi_last
Definition: chmc.h:206
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
static int _lzx_at_eof(void *arg)
Definition: chmc.c:988
UInt32 lang_id
Definition: chm.h:93
struct list_head pmgi_list
Definition: chmc.h:205
struct chmcConfig * config
Definition: chmc.h:212
#define chmcerr_set_return(code, fmt,...)
Definition: err.h:67
DWORD UInt32
Definition: chm_lib.c:104
void chmcerr_set(int code, const char *fmt,...)
Definition: err.c:50
void chmc_string_init(struct chmcStringChunk *node)
UInt32 strings_len
Definition: chmc.h:211
#define free
Definition: debug_ros.c:5
__kernel_off_t off_t
Definition: linux.h:201
#define _CHMC_LZXC_RESETTABLE_V1_LEN
Definition: chm.h:153
int chmc_init(struct chmcFile *chm, const char *filename, struct chmcConfig *config)
Definition: chmc.c:133
#define INIT_LIST_HEAD(ptr)
Definition: list.h:24
void chmc_entries_free(struct chmcFile *chm)
Definition: chmc.c:542
struct chmcSection * chmc_section_lookup(struct chmcFile *chm, int id)
Definition: chmc.c:1366
GLintptr offset
Definition: glext.h:5920
Int32 index_last
Definition: chm.h:126
UInt32 chmc_strings_add(struct chmcFile *chm, const char *s)
Definition: chmc.c:558
ULONGLONG UInt64
Definition: chm_lib.c:106
UInt32 strings_offset
Definition: chmc.h:250
BOOL todo
Definition: filedlg.c:313
GLdouble n
Definition: glext.h:7729
#define unlink
Definition: syshdrs.h:54
#define _CHMC_CHUNK_LEN
Definition: chmc.h:133
#define assert(x)
Definition: debug.h:53
Int32 unknown_44
Definition: chmc.h:59
struct chmcSection ** sections
Definition: chmc.h:199
UInt64 compressed_len
Definition: chm.h:160
UInt32 sect_id
Definition: chmc.h:169
void chmc_pmgl_init(struct chmcPmglChunkNode *node)
Definition: chmc.c:1396
BYTE UChar
Definition: chm_lib.c:100
UInt64 block_len
Definition: chm.h:161
USHORT UInt16
Definition: chm_lib.c:102
int errno
void chmc_sections_done(struct chmcFile *chm)
Definition: chmc.c:348
Definition: parser.c:55
#define chmcerr_return_msg(fmt,...)
Definition: err.h:50
Int32 win_style
Definition: chmc.h:53
int chmc_section_add(struct chmcFile *chm, const char *name)
Definition: chmc.c:245
void chmc_pmgi_add(struct chmcFile *chm, struct chmcPmgiChunkNode *pmgi)
Definition: chmc.c:1610
const char * filename
Definition: ioapi.h:135
#define SIEC_NUMOFINFOT
Definition: chmc.h:75
#define CHMC_MS_LCID_EN_US
Definition: chmc.h:121
const char * strerror(int err)
Definition: compat_str.c:23
UInt32 fd_offset
Definition: chmc.c:120
int chmc_appendfile(struct chmcFile *chm, const char *filename, void *buf, size_t size)
Definition: chmc.c:1660
#define CHMC_SYSTEM_UUID
Definition: chmc.h:38
FILE * stdout
#define list_entry(ptr, type, member)
Definition: list.h:185
static IMAGE_SECTION_HEADER section
Definition: loader.c:152
const WCHAR * name
Definition: parser.c:57
static DWORD block_size(DWORD block)
Definition: jsutils.c:66
int fd
Definition: chmc.h:193
Definition: list.h:15
#define sprintf(buf, format,...)
Definition: sprintf.c:55
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
UInt32 urltbl_offset
Definition: chmc.h:251
struct node node
#define write
Definition: acwin.h:97
int chmcerr_code(void)
Definition: err.c:42
void chmc_pmgl_add(struct chmcFile *chm, struct chmcPmglChunkNode *pmgl)
Definition: chmc.c:1465
UInt32 block_count
Definition: chm.h:156
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
int error
Definition: chmc.c:124
struct chmcPmgiChunkNode * chmc_pmgi_create(void)
Definition: chmc.c:1442
UInt32 done
Definition: chmc.c:121
Int32 unknown_000c
Definition: chm.h:91
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define list_for_each(entry, head)
Definition: list.h:36
_Check_return_ _CRTIMP char *__cdecl strdup(_In_opt_z_ const char *_Src)
int chmc_control_data_done(struct chmcFile *chm)
Definition: chmc.c:1143
#define _CHMC_ITSF_V3_LEN
Definition: chm.h:86
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 *))
UInt32 entry_size
Definition: chm.h:157
unsigned int idx
Definition: utils.c:41
void chmc_pmgi_init(struct chmcPmgiChunkNode *node)
Definition: chmc.c:1418
static int chmc_decint(const UChar *in, UInt32 *value)
Definition: encint.h:78
UInt32 lang_id
Definition: chm.h:129
Int32 unknown_000c
Definition: chm.h:120
int chmc_compressed_add_mark(struct chmcFile *chm, UInt64 at)
Definition: chmc.c:1122
char signature[4]
Definition: chm.h:117
smooth NULL
Definition: ftsmooth.c:416
#define SIEC_IDXHDR
Definition: chmc.h:78
Int32 unknown_4
Definition: chmc.h:43
void chmc_pmgl_destroy(struct chmcPmglChunkNode *node)
Definition: chmc.c:1453
#define chmcerr_msg(fmt,...)
Definition: err.h:59
Int32 unknown_0028
Definition: chm.h:127
int __cdecl system(_In_opt_z_ const char *_Command)
unsigned int dir
Definition: maze.c:112
UInt32 todo
Definition: chmc.c:122
struct chmcSystem system
Definition: chmc.h:207
int chmc_system_done(struct chmcFile *chm)
Definition: chmc.c:647
char signature[4]
Definition: chm.h:88
#define _CHMC_SYSTEM_HDR_LEN
Definition: chmc.h:123
void chmcerr_clean(void)
Definition: err.c:37
#define ctrl
Definition: input.c:1757
UInt64 sect0_offset
Definition: chm.h:96
GLuint GLfloat * val
Definition: glext.h:7180
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
UInt32 url_offset
Definition: chmc.h:238
static int ** pa
Definition: server.c:126
int chmc_uncompressed_done(struct chmcFile *chm)
Definition: chmc.c:1238
#define BUG_ON(c)
Definition: module.h:253
int lzx_compress_block(lzx_data *lzxd, int block_size, int subdivide)
Definition: lzx_layer.c:1062
struct chmcTreeNode * chmc_add_empty(struct chmcFile *chm, const char *file)
Definition: chmc.c:401
#define SIEC_DEFWINDOW
Definition: chmc.h:69
UChar * strings
Definition: chmc.h:209
void chmc_reset_table_init(struct chmcLzxcResetTable *reset_table)
Definition: chmc.c:326
struct chmcSection * chmc_section_create(struct chmcFile *chm, const char *name)
Definition: chmc.c:262
#define CHMC_EINVAL
Definition: err.h:41
struct chmcPmgiChunk chunk
Definition: chmc.h:161
UInt32 version
Definition: chm.h:155
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLsizeiptr size
Definition: glext.h:5919
static char tmpdir[MAX_PATH]
Definition: shlexec.c:52
UInt32 framename_offset
Definition: chmc.h:239
#define d
Definition: ke_i.h:81
Int32 version
Definition: chm.h:118
_Check_return_ _CRTIMP int __cdecl fileno(_In_ FILE *_File)
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define PACKAGE_STRING
Definition: chmc.c:49
int chmc_add_tree(struct chmcFile *chm, const char *dir)
#define SIEC_DEFTOPIC
Definition: chmc.h:66
static int chmc_encint_len(const UInt32 val)
Definition: encint.h:28
void chmc_entry_destroy(struct chmcTreeNode *node)
Definition: chmc.c:587
#define CHMC_TNFL_STATIC
Definition: chmc.h:164
void chmc_pmgl_free(struct chmcFile *chm)
Definition: chmc.c:528
Definition: chmc.h:192
Int32 off_frame_name
Definition: chmc.h:56
int lzx_finish(struct lzx_data *lzxd, struct lzx_results *lzxr)
Definition: lzx_layer.c:1236
Int32 background
Definition: chmc.h:50
struct list_head sections_list
Definition: chmc.h:198
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
void lzx_reset(lzx_data *lzxd)
Definition: lzx_layer.c:1053
#define SIEC_TIMESTAMP
Definition: chmc.h:83
#define SIEC_INFOCHKSUM
Definition: chmc.h:80
#define PATH_MAX
Definition: types.h:280
UChar stream_uuid[16]
Definition: chm.h:95
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
UInt32 lcid
Definition: chmc.h:109
struct chmcFile * chm
Definition: chmc.c:117
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
Int32 off_img_list
Definition: chmc.h:47
static void * chmc_syscat_mem(void *d, void *s, unsigned long len)
Definition: chmc.c:628
int sections_num
Definition: chmc.h:197
static int _lzx_put_bytes(void *arg, int n, void *buf)
Definition: chmc.c:995
void chmc_sections_free(struct chmcFile *chm)
Definition: chmc.c:479
Int32 ex_win_style
Definition: chmc.h:54
struct chmcIndexHeader idxhdr
Definition: chmc.h:208
#define CHMC_STREAM_UUID
Definition: chmc.h:36
static void * chmc_syscat_entry(Int16 code, void *d, void *s, Int16 len)
Definition: chmc.c:635
Int32 foreground
Definition: chmc.h:51
int chmc_pmgl_add_entry(struct chmcFile *chm, struct chmcTreeNode *entry)
Definition: chmc.c:1273
#define _CHMC_SECT0_LEN
Definition: chm.h:103
short unknown
Definition: chmc.h:253
Definition: stat.h:55
uint32_t entry
Definition: isohybrid.c:63
struct chmcItsfHeader itsf
Definition: chmc.h:194
Definition: chm.h:104
UInt32 block_len
Definition: chm.h:121
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
static void _lzx_mark_frame(void *arg, uint32_t uncomp, uint32_t comp)
Definition: chmc.c:1010
GLdouble s
Definition: gl.h:2039
Int32 header_len
Definition: chm.h:119
Definition: _list.h:228
#define O_TRUNC
Definition: acwin.h:112
#define close
Definition: acwin.h:98
UInt64 dir_len
Definition: chm.h:99
#define O_BINARY
Definition: chmc.c:53
int code
Definition: i386-dis.c:3591
#define CHMC_NOERR
Definition: err.h:39
UChar system_uuid[16]
Definition: chm.h:130
Int32 unknown_0000
Definition: chm.h:105
UInt64 sect0_len
Definition: chm.h:97
struct chmcTreeNode * chmc_add_dir(struct chmcFile *chm, const char *dir)
Definition: chmc.c:621
char signature[4]
Definition: chmc.h:42
int chmc_crunch_lzx(struct chmcFile *chm, int sect_id)
Definition: chmc.c:929
int chmc_tree_done(struct chmcFile *chm)
Definition: chmc.c:728
#define _CHMC_LZXC_V2_LEN
Definition: chm.h:166
void chmc_pmgi_destroy(struct chmcPmgiChunkNode *node)
Definition: chmc.c:1459
struct list_head list
Definition: chmc.h:234
_CRTIMP int __cdecl stat(const char *_Filename, struct stat *_Stat)
Definition: stat.h:345
UInt32 header_len2
Definition: chm.h:131
struct chmcSect0 sect0
Definition: chmc.h:195
Int32 off_win_name
Definition: chmc.h:57
struct chmcTreeNode * chmc_add_file(struct chmcFile *chm, const char *filename, UInt16 prefixlen, int sect_id, UChar *buf, UInt64 len)
Definition: chmc.c:598
GLuint in
Definition: glext.h:9616
static calc_node_t temp
Definition: rpn_ieee.c:38
Int32 unknown_34
Definition: chmc.h:55
int chmc_pmgi_add_entry(struct chmcFile *chm, const char *name, int pmgl_id)
Definition: chmc.c:1530
#define O_RDWR
Definition: fcntl.h:36
Int32 index_root
Definition: chm.h:124
SHORT Int16
Definition: chm_lib.c:101
Int32 blockidx_intvl
Definition: chm.h:122
int fd
Definition: chmc.c:119
struct chmcPmglChunkNode * pmgl_last
Definition: chmc.h:201
#define _CHMC_RSTTBL_MARK
Definition: chmc.h:230
static int chmc_encint(const UInt32 val, UChar *out)
Definition: encint.h:46
#define CHMC_PMGI_DATA_LEN
Definition: chmc.h:149
#define SIEC_COMPVER
Definition: chmc.h:84
int mkstemps(char *template, int suffix_len)
Definition: mkstemps.c:73
UInt64 data_offset
Definition: chm.h:100
UInt64 file_len
Definition: chm.h:107
#define SIEC_SYSINFO
Definition: chmc.h:85
struct chmcTreeNode ** sort_entries
Definition: chmc.h:204
UINT32 uint32_t
Definition: types.h:75
UChar dir_uuid[16]
Definition: chm.h:94
void chmc_pmgi_free(struct chmcFile *chm)
Definition: chmc.c:514
UInt16 prefixlen
Definition: chmc.h:171
void chmc_control_data_init(struct chmcLzxcControlData *control_data)
Definition: chmc.c:337
static int _lzx_get_bytes(void *arg, int n, void *buf)
Definition: chmc.c:1030
Definition: name.c:38
#define calloc
Definition: rosglue.h:14
void chmc_entries_qsort(struct chmcFile *chm)
Definition: chmc.c:1208
Int32 version
Definition: chm.h:89
struct list_head * pos
Definition: chmc.c:123
FILE * stderr
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
void chmc_section_destroy(struct chmcSection *section)
Definition: chmc.c:493
short in_content
Definition: chmc.h:252
struct list_head list
Definition: chmc.h:143
struct chmcSection * section
Definition: chmc.c:118
#define malloc
Definition: debug_ros.c:4
Int32 index_depth
Definition: chm.h:123
#define SIEC_LCASEFILE
Definition: chmc.h:68
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLfloat GLfloat p
Definition: glext.h:8902
UInt64 dir_offset
Definition: chm.h:98
UInt32 num_blocks
Definition: chm.h:128
#define memset(x, y, z)
Definition: compat.h:39
struct chmcTreeNode * chmc_add_meta(struct chmcFile *chm, const char *metaname, int sect_id, UChar *buf, UInt64 len)
Definition: chmc.c:407
#define _CHMC_ITSP_V1_LEN
Definition: chm.h:115
#define O_CREAT
Definition: acwin.h:110
#define CHMC_DIR_UUID
Definition: chmc.h:34
int k
Definition: mpi.c:3369
#define chmc_dump(fmt,...)
Definition: chmc.h:263
#define CHMC_PMGL_DATA_LEN
Definition: chmc.h:134
struct chmcItspHeader itsp
Definition: chmc.h:196
UChar unknown_0048[12]
Definition: chm.h:132
UInt32 table_offset
Definition: chm.h:158
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)
int chmc_namelist_create(struct chmcFile *chm, int len)
Definition: chmc.c:372
struct task_struct * current
Definition: linux.c:32
struct list_head pmgl_list
Definition: chmc.h:200
_off_t st_size
Definition: stat.h:63
struct chmcPmglChunkNode * chmc_pmgl_create(void)
Definition: chmc.c:1385
Int32 unknown_8
Definition: chmc.h:44
void chmc_pmgl_done(struct chmcFile *chm)
Definition: chmc.c:1260
Definition: dlist.c:348
struct list_head list
Definition: chmc.h:158
#define O_RDONLY
Definition: acwin.h:108
off
Definition: i386-dis.c:3909
Definition: fci.c:126