ReactOS  0.4.14-dev-297-g23e575c
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  UInt16 code, len;
672  const char *entry_val;
673 
674  p = chmc_syscat_mem(sysp, &system->version, sizeof(system->version));
675 
676  val = 0;
677  p = chmc_syscat_entry(SIEC_TIMESTAMP, p, &val, sizeof(val));
679  /*"HHA Version 4.74.8702"*/
681  sizeof(PACKAGE_STRING)
682  /*strlen("HHA Version 4.74.8702")+1*/);
684  sysinfo, sizeof(struct chmcSystemInfo));
685 
686  if (chm->config != NULL && chm->config->deftopic != NULL)
687  entry_val = chm->config->deftopic;
688  else
689  entry_val = "index.htm";
690  p = chmc_syscat_entry(SIEC_DEFTOPIC, p, (void *)entry_val,
691  strlen(entry_val)+1);
692 
693  if (chm->config != NULL && chm->config->title != NULL)
694  entry_val = chm->config->title;
695  else
696  entry_val = "untitled";
697  p = chmc_syscat_entry(SIEC_TITLE, p, (void *)entry_val,
698  strlen(entry_val)+1);
699  // p = chmc_syscat_entry(SIEC_DEFFONT, p, &val, sizeof(val));
700  p = chmc_syscat_entry(SIEC_LCASEFILE, p, "siec_lcasefile",
701  strlen("siec_lcasefile")+1);
703  "MsdnHelp", strlen("MsdnHelp")+1);
704 
705  val = 0;
706  p = chmc_syscat_entry(SIEC_NUMOFINFOT, p, &val, sizeof(val));
707 
709  idxhdr, sizeof(struct chmcIndexHeader));
710 
711 
712  val = 0;
713  p = chmc_syscat_entry(SIEC_INFOCHKSUM, p, &val, sizeof(val));
714 
715  system->_size = (char *)p - (char *)sysp;
716  chmc_add_meta(chm, "/#SYSTEM", 0, sysp, system->_size);
717  return CHMC_NOERR;
718  }
719 
720  chmcerr_set(CHMC_ENOMEM, "system done: malloc %d bytes",
721  system->_size);
722 
723  return CHMC_ENOMEM;
724 }
725 
726 int chmc_tree_done( struct chmcFile *chm )
727 {
728  struct chmcItsfHeader *itsf;
729  struct chmcSect0 *sect0;
730  struct chmcItspHeader *itsp;
731  struct chmcTreeNode *ctrl;
732  UInt32 str_index;
733  const char *val;
734 
735  assert(chm);
736 
737  itsf = &chm->itsf;
738  sect0 = &chm->sect0;
739  itsp = &chm->itsp;
740 
741  chmc_add_dir(chm, "/");
742 
743  ctrl = chmc_add_meta(chm, "::DataSpace/Storage/MSCompressed/Transform/List",
745  sizeof(chmc_transform_list));
746  if (ctrl)
747  ctrl->flags |= CHMC_TNFL_STATIC;
748 
749  chmc_system_done(chm);
750 
751  if (chm->config != NULL && chm->config->deftopic != NULL)
752  val = chm->config->deftopic;
753  else
754  val = "index.htm";
755 
756  str_index = chmc_strings_add(chm, val);
757 
758 #if 0
759  // FIXME just a test
760  {
761  UChar *p;
762  int len;
763  struct chmcTopicEntry topicEntry;
764  // struct chmcUrlStrEntry urlStrEntry;
765 
766  p = malloc(4096);
767  if (p) {
768  memset(p, 0, 4096);
769  len = 0;
770 
771  topicEntry.tocidx_offset = 4096;
772  topicEntry.strings_offset = -1;
773  topicEntry.urltbl_offset = 0;
774  topicEntry.in_content = 6;
775  topicEntry.unknown = 0;
776 
777  memcpy(p, &topicEntry, sizeof(struct chmcTopicEntry));
778  len += sizeof(struct chmcTopicEntry);
779 
780  chm->idxhdr.num_of_topic++;
781 
782  chmc_add_meta(chm, "/#TOPICS", 1, (UChar *)p, len);
783  } else
784  BUG_ON("FIXME: %s: %d\n", __FILE__, __LINE__);
785  }
786 #endif
787 
788  ctrl = chmc_add_meta(chm, "/#IDXHDR", 1, (void *)&chm->idxhdr,
789  sizeof(struct chmcIndexHeader));
790  if (ctrl)
791  ctrl->flags |= CHMC_TNFL_STATIC;
792 
793  {
794  UInt32 *p;
795  p = malloc(8+196);
796  if (p) {
797  const char *val;
798  memset(p+2, 0, 196);
799 
800  p[0] = 1;
801  p[1] = 196;
802 
803  p[2+0] = 196;
804  // p[2+2] = 1;
805  // p[2+3] = 0x00000532;
806  // p[2+4] = 0x00062520;
807 
808  // p[2+8] = 86;
809  // p[2+9] = 51;
810  // p[2+10] = 872;
811  // p[2+11] = 558;
812 
813  // p[2+19] = 220;
814 
815  // p[2+27] = 0x00000041;
816  // p[2+28] = 14462;
817 
818  if (chm->config != NULL && chm->config->title != NULL)
819  val = chm->config->title;
820  else
821  val = "untitled";
822  p[2+5] = chmc_strings_add(chm, val);
823 
824  if (chm->config != NULL && chm->config->hhc != NULL)
825  val = chm->config->hhc;
826  else
827  val = "toc.hhc";
828  p[2+24] = chmc_strings_add(chm, val);
829 
830  if (chm->config != NULL && chm->config->hhk != NULL)
831  val = chm->config->hhc;
832  else
833  val = "toc.hhk";
834  p[2+25] = chmc_strings_add(chm, val);
835  p[2+26] = str_index;
836 
837  chmc_add_meta(chm, "/#WINDOWS", 1, (UChar *)p, 8+196);
838  } else
839  BUG_ON("FIXME: %s: %d\n", __FILE__, __LINE__);
840  }
841 
842  ctrl = chmc_add_meta(chm, "/#STRINGS", 1, (void *)chm->strings,
843  chm->strings_len);
844  if (ctrl)
845  ctrl->flags |= CHMC_TNFL_STATIC;
846 
847 #if 0
848  // FIXME just a test
849  {
850  UChar *p;
851  int len;
852  struct chmcUrlStrEntry urlStrEntry;
853 
854  urlStrEntry.url_offset = 0;
855  urlStrEntry.framename_offset = 0;
856 
857  p = malloc(4096);
858  if (p) {
859  memset(p, 0, 4096);
860  *p = 0x42;
861  len = 1;
862 
863  memcpy(p + len, &urlStrEntry, sizeof(struct chmcUrlStrEntry));
864  len += sizeof(struct chmcUrlStrEntry);
865  len += sprintf(p + len, "index.htm" ) + 1;
866 
867  memcpy(p + len, &urlStrEntry, sizeof(struct chmcUrlStrEntry));
868  len += sizeof(struct chmcUrlStrEntry);
869  len += sprintf(p + len, "test.htm" ) + 1;
870 
871  chmc_add_meta(chm, "/#URLSTR", 1, (UChar *)p, len);
872  } else
873  BUG_ON("FIXME: %s: %d\n", __FILE__, __LINE__);
874  }
875 #endif
876 
877  // chmc_add_entry(chm, "/#URLTBL", 0, 1, NULL, 0, 0);
878  // chmc_add_entry(chm, "/#TOPICS", 0, 1, NULL, 0, 0);
879 
880  // NOTE NOTE NOTE add any meta compressed before crunch ;-)
881 
882  chmc_crunch_lzx(chm, 1);
883 
886 
887  chmc_add_empty(chm, "/#ITBITS");
888 
889  // NOTE in this implementation compressed Content should be the last file
890  // added to section 0
891 
892  chmc_add_meta(chm, "::DataSpace/Storage/MSCompressed/Content", 0, NULL,
893  chm->sections[1]->offset);
894 
895  chmc_entries_qsort(chm);
897  chmc_pmgl_done(chm);
898 
899  chmc_pmgi_done(chm);
900 
901  itsf->dir_len = _CHMC_ITSP_V1_LEN
902  + (_CHMC_CHUNK_LEN * itsp->num_blocks);
903 
907  + (_CHMC_CHUNK_LEN * itsp->num_blocks);
908 
909  sect0->file_len += _CHMC_CHUNK_LEN * itsp->num_blocks;
910 
911  chmc_write(chm);
912 
913  {
914  struct chmcSection *section;
915  struct list_head *pos;
916  UChar buf[4096];
917 
919  section = list_entry(pos, struct chmcSection, list);
920  chmc_appendfile(chm, section->filename, buf, 4096);
921  }
922  }
923 
924  return CHMC_NOERR;
925 }
926 
927 int chmc_crunch_lzx(struct chmcFile *chm, int sect_id)
928 {
929  struct chmcLzxInfo lzx_info;
930 
931  lzx_data *lzxd;
932  int subd_ok = 1;
933  int do_reset = 1;
934  int block_size;
935  lzx_results lzxr;
936  int wsize_code = 16;
937 
938  assert(chm);
939 
940  if ((wsize_code < 15) || (wsize_code > 21)) {
941  fprintf(stderr, "window size must be between 15 and 21 inclusive\n");
942  return CHMC_EINVAL;
943  }
944 
945  lzx_info.chm = chm;
946  lzx_info.section = chm->sections[sect_id];
947  lzx_info.done = 0;
948  lzx_info.todo = lzx_info.section->offset;
949  lzx_info.pos = chm->entries_list.next;
950  lzx_info.error = 0;
951  lzx_info.eof = 0;
952 
953  lzx_info.fd = -1;
954  lzx_info.fd_offset = 0;
955 
956  chmc_compressed_add_mark(lzx_info.chm, 0);
957  lzx_info.section->reset_table_header.block_count++;
958 
959  /* undocumented fact, according to Caie --
960  block size cannot exceed window size. (why not?) */
961  /* The block size must not be larger than the window size.
962  While the compressor will create apparently-valid LZX files
963  if this restriction is violated, some decompressors
964  will not handle them. */
965 
966  block_size = 1 << wsize_code;
967 
968  // lzx_info.section->control_data.windowSize = wsize_code;
969  // lzx_info.section->control_data.windowsPerReset = block_size;
970 
971  lzx_init(&lzxd, wsize_code,
972  _lzx_get_bytes, &lzx_info, _lzx_at_eof,
973  _lzx_put_bytes, &lzx_info,
974  _lzx_mark_frame, &lzx_info);
975 
976  while(! _lzx_at_eof(&lzx_info)) {
977  if (do_reset)
978  lzx_reset(lzxd);
979  lzx_compress_block(lzxd, block_size, subd_ok);
980  }
981  lzx_finish(lzxd, &lzxr);
982 
983  return CHMC_NOERR;
984 }
985 
986 static int _lzx_at_eof(void *arg)
987 {
988  struct chmcLzxInfo *lzx_info = (struct chmcLzxInfo *)arg;
989 
990  return lzx_info->error || lzx_info->done >= lzx_info->todo || lzx_info->eof;
991 }
992 
993 static int _lzx_put_bytes(void *arg, int n, void *buf)
994 {
995  struct chmcLzxInfo *lzx_info = (struct chmcLzxInfo *)arg;
996  struct chmcSect0 *sect0 = &lzx_info->chm->sect0;
997  int wx;
998  static int counter = 0;
999 
1000  counter += n;
1001  wx = write(lzx_info->section->fd, buf, n);
1002  sect0->file_len += wx;
1003  lzx_info->section->len += wx;
1004 
1005  return wx;
1006 }
1007 
1008 static void _lzx_mark_frame(void *arg, uint32_t uncomp, uint32_t comp)
1009 {
1010  struct chmcLzxInfo *lzx_info = (struct chmcLzxInfo *)arg;
1011  struct chmcSection *section = lzx_info->chm->sections[1];
1012 
1013  UInt64 compressed;
1014 
1015  chmc_dump( "Aligned data at %d(in compressed stream, %d) (%lu/%lu)\n",
1016  uncomp, comp, (unsigned long)lzx_info->done, (unsigned long)lzx_info->todo );
1017 
1018  compressed = comp;
1019 
1020  section->reset_table_header.block_count++;
1021 
1022  chmc_compressed_add_mark( lzx_info->chm, compressed );
1023 
1024  section->reset_table_header.uncompressed_len = uncomp;
1025  section->reset_table_header.compressed_len = comp;
1026 }
1027 
1028 static int _lzx_get_bytes(void *arg, int n, void *buf)
1029 {
1030  struct chmcLzxInfo *lzx_info = (struct chmcLzxInfo *)arg;
1031  struct chmcFile *chm = lzx_info->chm;
1032  struct chmcTreeNode *node;
1033 
1034  int todo;
1035  int done;
1036  int toread;
1037  int rx;
1038 
1039  todo = n;
1040  done = 0;
1041 
1042  // compression state machine
1043  // lzx compressor ask for block input bytes
1044  // need to keep current entry file and offset trought blocks
1045  // until last entry
1046  while (todo) {
1047  // end of entries reached?
1048  if (lzx_info->pos == &chm->entries_list) {
1049  lzx_info->eof = 1;
1050  break;
1051  }
1052 
1053  node = list_entry( lzx_info->pos, struct chmcTreeNode, list );
1054 
1055  // skip empty files and directories
1056  if (node->len == 0
1057  || strcmp("MSCompressed", chm->sections[node->sect_id]->name)) {
1058  lzx_info->pos = lzx_info->pos->next;
1059  continue;
1060  }
1061  else
1062  if (node->buf) {
1063  // have len and buffer, it's mallocated not file
1064  }
1065  else
1066  if (lzx_info->fd == -1) {
1067  // open file if it isn't
1068  lzx_info->fd = open(node->name, O_RDONLY | O_BINARY);
1069  if (lzx_info->fd < 0) {
1070  chmc_error("%s: %d: error %d: '%s' %s\n",
1071  __FILE__, __LINE__,
1072  errno, node->name, strerror(errno));
1073  lzx_info->error = 1;
1074  break;
1075  }
1076  }
1077 
1078  // read till the end of the file or till the lzx buffer is filled
1079  toread = node->len - lzx_info->fd_offset;
1080  if (toread > todo)
1081  toread = todo;
1082 
1083  if (toread <= 0)
1084  continue;
1085 
1086  // read input
1087  if (node->buf) {
1088  memcpy((char *)buf + (n - todo), &node->buf[lzx_info->fd_offset], toread);
1089  rx = toread;
1090  }
1091  else
1092  {
1093  rx = read(lzx_info->fd, (char *)buf + (n - todo), toread);
1094  if (rx <= 0) {
1095  int temp = errno;
1096  chmc_error("read error %s \n", strerror(temp));
1097  lzx_info->error = 2;
1098  break;
1099  }
1100  }
1101 
1102  todo -= rx;
1103  lzx_info->fd_offset += rx;
1104  done += rx;
1105  lzx_info->done += rx;
1106 
1107  // end of current file reached, goto next entry
1108  if (lzx_info->fd_offset == node->len) {
1109  if (lzx_info->fd > -1)
1110  close(lzx_info->fd);
1111  lzx_info->fd = -1;
1112  lzx_info->fd_offset = 0;
1113  lzx_info->pos = lzx_info->pos->next;
1114  }
1115  }
1116 
1117  return done;
1118 }
1119 
1121 {
1122  struct chmcSection *section;
1123  struct chmcResetTableMark *mark;
1124 
1125  assert(chm);
1126 
1127  section = chm->sections[1];
1128 
1129  mark = malloc(_CHMC_RSTTBL_MARK);
1130  if (mark) {
1131  mark->at = at;
1132  chmc_dump("[%d] at: %jd\n", section->mark_count, at);
1133  list_add_tail(&mark->list, &section->mark_list);
1134  section->mark_count++;
1135  return CHMC_NOERR;
1136  }
1137 
1138  return CHMC_ENOMEM;
1139 }
1140 
1142 {
1143  struct chmcTreeNode *ctrl;
1144 
1145  ctrl = chmc_add_meta(chm, "::DataSpace/Storage/MSCompressed/ControlData",
1146  0, (UChar *)&chm->sections[1]->control_data,
1148 
1149  if (ctrl) {
1150  ctrl->flags |= CHMC_TNFL_STATIC;
1151  return CHMC_NOERR;
1152  }
1153 
1154  return CHMC_ENOMEM;
1155 }
1156 
1158 {
1159  struct chmcSection *section;
1160  struct chmcLzxcResetTable *reset_table;
1161  struct list_head *pos;
1162  struct chmcResetTableMark *mark;
1163 
1164  UInt64 *at;
1165  int i, len;
1166 
1167  section = chm->sections[1];
1168 
1169  len = _CHMC_LZXC_RESETTABLE_V1_LEN + (section->mark_count * sizeof(UInt64));
1170 
1171  reset_table = malloc(len);
1172 
1173  if (reset_table) {
1174  memcpy(reset_table, &section->reset_table_header,
1176  at = (void *)((char *)reset_table + _CHMC_LZXC_RESETTABLE_V1_LEN);
1177 
1178  i = 0;
1179  list_for_each(pos, &section->mark_list) {
1180  mark = list_entry(pos, struct chmcResetTableMark, list);
1181  at[i++] = mark->at;
1182  }
1183 
1184  chmc_add_dir(chm, "::DataSpace/Storage/MSCompressed/Transform/"
1185  "{7FC28940-9D31-11D0-9B27-00A0C91E9C7C}/InstanceData/");
1186  chmc_add_meta(chm, "::DataSpace/Storage/MSCompressed/Transform/"
1187  "{7FC28940-9D31-11D0-9B27-00A0C91E9C7C}"
1188  "/InstanceData/ResetTable",
1189  0, (UChar *)reset_table, len);
1190 
1191  { // TODO FIXME do better
1192  UInt64 *uncompressed_len = malloc(8);
1193  if (uncompressed_len) {
1194  *uncompressed_len = reset_table->uncompressed_len;
1195  chmc_add_meta(chm, "::DataSpace/Storage/MSCompressed/SpanInfo",
1196  0, (UChar *)uncompressed_len, 8);
1197  }
1198  }
1199 
1200  return CHMC_NOERR;
1201  }
1202 
1203  return CHMC_ENOMEM;
1204 }
1205 
1206 void chmc_entries_qsort(struct chmcFile *chm)
1207 {
1208  struct chmcTreeNode *node;
1209  struct list_head *pos;
1210  int i;
1211 
1212  assert(chm);
1213 
1214  chm->sort_entries = malloc(sizeof(struct chmcTreeNode *)
1215  * chm->entries_num);
1216 
1217  i = 0;
1218  list_for_each(pos, &chm->entries_list) {
1219  node = list_entry(pos, struct chmcTreeNode, list);
1220  chm->sort_entries[i++] = node;
1221  }
1222 
1223  qsort(chm->sort_entries, chm->entries_num, sizeof(struct chmcTreeNode *),
1224  _entry_cmp);
1225 }
1226 
1227 static int _entry_cmp(const void *pva, const void *pvb)
1228 {
1229  const struct chmcTreeNode * const *pa = pva;
1230  const struct chmcTreeNode * const *pb = pvb;
1231  const struct chmcTreeNode *a = *pa, *b = *pb;
1232 
1233  return strcmp( &a->name[a->prefixlen], &b->name[b->prefixlen] );
1234 }
1235 
1237 {
1238  struct chmcSect0 *sect0 = &chm->sect0;
1239  struct chmcTreeNode *node;
1240  struct list_head *pos;
1241  int wx;
1242 
1243  list_for_each(pos, &chm->entries_list) {
1244  node = list_entry( pos, struct chmcTreeNode, list );
1245 
1246  if (strcmp( "MSCompressed", chm->sections[node->sect_id]->name ) == 0)
1247  continue;
1248 
1249  if ((node->buf) && (node->len > 0)) {
1250  wx = write(chm->sections[node->sect_id]->fd, node->buf, node->len);
1251  sect0->file_len += wx;
1252  }
1253  }
1254 
1255  return CHMC_NOERR;
1256 }
1257 
1258 void chmc_pmgl_done(struct chmcFile *chm)
1259 {
1260  struct chmcTreeNode *entry;
1261  int i;
1262 
1263  assert(chm);
1264 
1265  for(i=0; i < chm->entries_num; i++) {
1266  entry = chm->sort_entries[i];
1267  chmc_pmgl_add_entry(chm, entry);
1268  }
1269 }
1270 
1272 {
1273  struct chmcPmglChunkNode *pmgl;
1274  struct chmcPmglChunk *chunk;
1275  struct chmcSection *section;
1276  struct chmcItspHeader *itsp = &chm->itsp;
1277 
1278  UChar *p;
1279  UInt16 *idx;
1280  int name_len;
1281  int outlen;
1282  int should_idx, idx_intlv;
1283  int free;
1284 
1285  assert(chm);
1286  assert(entry);
1287 
1288  // check section bound
1289  section = chmc_section_lookup(chm, entry->sect_id);
1290  if (!section)
1291  chmcerr_set_return(CHMC_ENOMEM, "section %d lookup failed: ",
1292  entry->sect_id);
1293 
1294  // check chunk space for new entry
1295  name_len = strlen(&entry->name[entry->prefixlen]);
1296 
1297  outlen = chmc_encint_len(name_len);
1298  outlen += name_len;
1299  outlen += chmc_encint_len(entry->sect_id);
1300  outlen += chmc_encint_len(entry->offset);
1301  outlen += chmc_encint_len(entry->len);
1302 
1303  // look for current pmgl chunk, create if doesn't exist
1304  if (!chm->pmgl_last) {
1305  pmgl = chmc_pmgl_create();
1306  if (pmgl)
1307  chmc_pmgl_add(chm, pmgl);
1308  else
1309  chmcerr_set_return(CHMC_ENOMEM, "pmgl chunk: ");
1310  }
1311  else
1312  pmgl = chm->pmgl_last;
1313 
1314  do {
1315 
1316  chunk = &chm->pmgl_last->chunk;
1317 
1318  idx_intlv = 1 + ( 1 << itsp->blockidx_intvl );
1319  should_idx = ( ( chunk->entries_count > 0 )
1320  && ! ( ( chunk->entries_count + 1 ) % idx_intlv )
1321  ? 2 : 0 );
1322 
1323  free = sizeof(chunk->data) - pmgl->data_len - pmgl->index_len
1324  - should_idx;
1325 
1326  // current(last) chunk doesn't have enough room? force new one
1327  if (outlen + should_idx > free) {
1328  //chm->pmgl_last = NULL;
1329  pmgl = chmc_pmgl_create();
1330  if ( pmgl )
1331  chmc_pmgl_add(chm, pmgl);
1332  else
1333  chmcerr_set_return(CHMC_ENOMEM, "pmgl chunk: ");
1334 
1335  continue;
1336  }
1337 
1338  p = (void *)&chunk->data[pmgl->data_len];
1339 
1340  if (should_idx) {
1341  idx = (void *)((char *)&chunk->data[CHMC_PMGL_DATA_LEN] - pmgl->index_len);
1342  *idx = (char *)p - (char *)&chunk->data;
1343  }
1344 
1345  p += chmc_encint(name_len, p);
1346  memcpy(p, &entry->name[entry->prefixlen], name_len);
1347  p += name_len;
1348  p += chmc_encint(entry->sect_id, p);
1349  p += chmc_encint(entry->offset, p);
1350  p += chmc_encint(entry->len, p);
1351 
1352  pmgl->data_len += outlen;
1353  pmgl->index_len += should_idx;
1354 
1355  chunk->entries_count++;
1356  chunk->header.free_space -= outlen;
1357  break;
1358 
1359  } while (1);
1360 
1361  return CHMC_NOERR;
1362 }
1363 
1364 struct chmcSection *chmc_section_lookup(struct chmcFile *chm, int id)
1365 {
1366  struct chmcSection *current;
1367  struct list_head *pos;
1368  int i;
1369 
1370  assert(chm);
1371 
1372  i = 0;
1373  list_for_each(pos, &chm->sections_list) {
1374  current = list_entry(pos, struct chmcSection, list);
1375  if (i == id)
1376  return current;
1377  i++;
1378  }
1379 
1380  return NULL;
1381 }
1382 
1384 {
1385  struct chmcPmglChunkNode *node;
1386 
1387  node = malloc(sizeof(struct chmcPmglChunkNode));
1388  if (node)
1390 
1391  return node;
1392 }
1393 
1395 {
1396  struct chmcPmglChunk *chunk;
1397 
1398  assert(node);
1399 
1400  node->data_len = 0;
1401  node->index_len = 0;
1402 
1403  chunk = &node->chunk;
1404 
1405  memcpy(chunk->header.signature, "PMGL", 4);
1406 
1407  // FIXME check it is the right len
1408  chunk->header.free_space = CHMC_PMGL_DATA_LEN + 2;
1409  chunk->header.unknown_0008 = 0;
1410  chunk->header.block_prev = -1;
1411  chunk->header.block_next = -1;
1412 
1413  memset(chunk->data, 0, CHMC_PMGL_DATA_LEN);
1414 }
1415 
1417 {
1418  struct chmcPmgiChunk *chunk;
1419 
1420  assert(node);
1421 
1422  node->data_len = 0;
1423  node->index_len = 0;
1424 
1425  chunk = &node->chunk;
1426 
1427  memcpy(chunk->header.signature, "PMGI", 4);
1428 
1429  // FIXME check it is the right len
1430  chunk->header.free_space = CHMC_PMGI_DATA_LEN + 2;
1431  // chunk->header.unknown_0008 = 0;
1432  // chunk->header.block_prev = -1;
1433  // chunk->header.block_next = -1;
1434 
1435  memset(chunk->data, 0, CHMC_PMGI_DATA_LEN);
1436 }
1437 
1438 
1439 
1441 {
1442  struct chmcPmgiChunkNode *node;
1443 
1444  node = malloc(sizeof(struct chmcPmgiChunkNode));
1445  if (node)
1447 
1448  return node;
1449 }
1450 
1452 {
1453  assert(node);
1454  free(node);
1455 }
1456 
1458 {
1459  assert(node);
1460  free(node);
1461 }
1462 
1463 void chmc_pmgl_add(struct chmcFile *chm, struct chmcPmglChunkNode *pmgl)
1464 {
1465  struct chmcItspHeader *itsp = &chm->itsp;
1466  struct chmcPmglHeader *hdr;
1467 
1468  assert(chm);
1469  assert(pmgl);
1470 
1471  list_add_tail(&pmgl->list, &chm->pmgl_list);
1472 
1473  itsp->index_last = itsp->num_blocks;
1474 
1475  hdr = &pmgl->chunk.header;
1476  hdr->block_prev = itsp->num_blocks - 1;
1477 
1478  if (chm->pmgl_last) {
1479  hdr = &chm->pmgl_last->chunk.header;
1480  hdr->block_next = itsp->num_blocks;
1481  }
1482 
1483  itsp->num_blocks++;
1484 
1485  chm->pmgl_last = pmgl;
1486 }
1487 
1488 int chmc_pmgi_done(struct chmcFile *chm)
1489 {
1490  struct chmcItspHeader *itsp = &chm->itsp;
1491  struct chmcPmglChunkNode *pmgl;
1492  struct list_head *pos;
1493 
1494  int i, j;
1495  char name[256]; //FIXME use malloc
1496  UInt32 name_len;
1497 
1498  assert(chm);
1499 
1500  // only one pml, omitted pmgi
1501  if (itsp->num_blocks == 1) {
1502  itsp->index_depth = 1;
1503  itsp->index_root = -1;
1504  itsp->index_last = 0;
1505  return CHMC_NOERR;
1506  }
1507 
1508  itsp->index_root = itsp->num_blocks;
1509 
1510  i = 0;
1511  list_for_each(pos, &chm->pmgl_list) {
1512  pmgl = list_entry(pos, struct chmcPmglChunkNode, list);
1513  j = chmc_decint(&pmgl->chunk.data[0], &name_len);
1514  if (name_len <= 255) {
1515  memcpy(name, &pmgl->chunk.data[j], name_len);
1516  name[name_len] = '\0';
1517  chmc_pmgi_add_entry(chm, name, i);
1518  }
1519  else
1520  BUG_ON("name_len >= 255(%lu) %.*s\n", (unsigned long)name_len, 255,
1521  &pmgl->chunk.data[j]);
1522  i++;
1523  }
1524 
1525  return CHMC_NOERR;
1526 }
1527 
1528 int chmc_pmgi_add_entry(struct chmcFile *chm, const char *name, int pmgl_id)
1529 {
1530  struct chmcPmgiChunkNode *pmgi;
1531  struct chmcPmgiChunk *chunk;
1532  struct chmcItspHeader *itsp = &chm->itsp;
1533 
1534  UChar *p;
1535  UInt16 *idx;
1536  int name_len;
1537  int outlen;
1538  int should_idx, idx_intlv;
1539  int free;
1540 
1541  assert(chm);
1542 
1543  // check chunk space for new entry
1544  name_len = strlen(name);
1545 
1546  outlen = chmc_encint_len(name_len);
1547  outlen += name_len;
1548  outlen += chmc_encint_len(pmgl_id);
1549 
1550  // look for current pmgi chunk, create if doesn't exist
1551  if (!chm->pmgi_last) {
1552  pmgi = chmc_pmgi_create();
1553  if (pmgi)
1554  chmc_pmgi_add(chm, pmgi);
1555  else
1556  chmcerr_set_return(CHMC_ENOMEM, "pmgi chunk: ");
1557  }
1558  else
1559  pmgi = chm->pmgi_last;
1560 
1561  do {
1562 
1563  chunk = &chm->pmgi_last->chunk;
1564 
1565  idx_intlv = 1 + ( 1 << itsp->blockidx_intvl );
1566  should_idx = ( ( chunk->entries_count > 0 )
1567  && ! ( ( chunk->entries_count + 1 ) % idx_intlv )
1568  ? 2 : 0 );
1569 
1570  free = sizeof(chunk->data) - pmgi->data_len -
1571  pmgi->index_len - should_idx;
1572 
1573  // current(last) chunk doesn't have enough room? force new one
1574  if (outlen + should_idx > free) {
1575  pmgi = chmc_pmgi_create();
1576  if (pmgi)
1577  chmc_pmgi_add(chm, pmgi);
1578  else
1579  chmcerr_set_return(CHMC_ENOMEM, "pmgi chunk: ");
1580 
1581  continue;
1582  }
1583 
1584  p = (void *)&chunk->data[pmgi->data_len];
1585 
1586  if (should_idx) {
1587  idx = (void *)((char *)&chunk->data[CHMC_PMGI_DATA_LEN] - pmgi->index_len);
1588  *idx = (char *)p - (char *)&chunk->data;
1589  }
1590 
1591  p += chmc_encint(name_len, p);
1592  memcpy(p, name, name_len);
1593  p += name_len;
1594  p += chmc_encint(pmgl_id, p);
1595 
1596  pmgi->data_len += outlen;
1597  pmgi->index_len += should_idx;
1598 
1599  chunk->entries_count++;
1600  chunk->header.free_space -= outlen;
1601  break;
1602 
1603  } while (1);
1604 
1605  return CHMC_NOERR;
1606 }
1607 
1608 void chmc_pmgi_add(struct chmcFile *chm, struct chmcPmgiChunkNode *pmgi)
1609 {
1610  struct chmcItspHeader *itsp = &chm->itsp;
1611 
1612  assert(chm);
1613  assert(pmgi);
1614 
1615  list_add_tail(&pmgi->list, &chm->pmgi_list);
1616  itsp->num_blocks++;
1617 
1618  chm->pmgi_last = pmgi;
1619 }
1620 
1621 int chmc_write(struct chmcFile *chm)
1622 {
1623  struct chmcItsfHeader *itsf = &chm->itsf;
1624  struct chmcSect0 *sect0 = &chm->sect0;
1625  struct chmcItspHeader *itsp = &chm->itsp;
1626 
1627  struct chmcPmglChunkNode *pmgl;
1628  struct chmcPmgiChunkNode *pmgi;
1629  struct list_head *pos;
1630 
1631  assert(chm);
1632 
1633  chmc_dump("write itsf %d\n", _CHMC_ITSF_V3_LEN);
1634  write(chm->fd, itsf, _CHMC_ITSF_V3_LEN);
1635  chmc_dump("write sect0 %d\n", _CHMC_SECT0_LEN);
1636  write(chm->fd, sect0, _CHMC_SECT0_LEN);
1637  chmc_dump("write itsp %d\n", _CHMC_ITSP_V1_LEN);
1638  write(chm->fd, itsp, _CHMC_ITSP_V1_LEN);
1639 
1640  list_for_each(pos, &chm->pmgl_list) {
1641  pmgl = list_entry(pos, struct chmcPmglChunkNode, list);
1642  chmc_dump("write pmgl %d\n", _CHMC_CHUNK_LEN);
1643  write(chm->fd, &pmgl->chunk, _CHMC_CHUNK_LEN);
1644  }
1645 
1646  chmc_dump("itsp->num_blocks %d", itsp->num_blocks);
1647  if (itsp->num_blocks > 1) {
1648  list_for_each( pos, &chm->pmgi_list ) {
1649  pmgi = list_entry(pos, struct chmcPmgiChunkNode, list);
1650  chmc_dump("write pmgi %d\n", _CHMC_CHUNK_LEN);
1651  write(chm->fd, &pmgi->chunk, _CHMC_CHUNK_LEN);
1652  }
1653  }
1654 
1655  return CHMC_NOERR;
1656 }
1657 
1658 int chmc_appendfile(struct chmcFile *chm, const char *filename, void *buf,
1659  size_t size )
1660 {
1661  struct stat statbuf;
1662  int in;
1663  off_t todo, toread;
1664  int rx;
1665 
1666  if (stat(filename, &statbuf) < 0)
1667  return errno;
1668 
1670  if (in >= 0) {
1671  todo = statbuf.st_size;
1672 
1673  while (todo) {
1674  toread = size;
1675  if (toread > todo)
1676  toread = todo;
1677 
1678  rx = read(in, buf, toread);
1679  if (rx > 0) {
1680  write(chm->fd, buf, rx);
1681  todo -= rx;
1682  }
1683  }
1684 
1685  close(in);
1686  }
1687  else
1688  BUG_ON("open %s\n", filename);
1689 
1690  return CHMC_NOERR;
1691 }
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:1227
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:1157
int chmc_pmgi_done(struct chmcFile *chm)
Definition: chmc.c:1488
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:1621
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:986
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:1364
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:1394
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:1608
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:1658
#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:1463
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:1440
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:1141
#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:1416
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:1120
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:1451
#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:1669
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
int chmc_uncompressed_done(struct chmcFile *chm)
Definition: chmc.c:1236
#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:59
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:993
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:1271
#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:1008
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:927
int chmc_tree_done(struct chmcFile *chm)
Definition: chmc.c:726
#define _CHMC_LZXC_V2_LEN
Definition: chm.h:166
void chmc_pmgi_destroy(struct chmcPmgiChunkNode *node)
Definition: chmc.c:1457
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:1528
#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:1028
Definition: name.c:36
#define calloc
Definition: rosglue.h:14
void chmc_entries_qsort(struct chmcFile *chm)
Definition: chmc.c:1206
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:1383
Int32 unknown_8
Definition: chmc.h:44
void chmc_pmgl_done(struct chmcFile *chm)
Definition: chmc.c:1258
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