ReactOS  0.4.15-dev-5640-g0dde428
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 #ifndef __REACTOS__
943  if ((wsize_code < 15) || (wsize_code > 21)) {
944  fprintf(stderr, "window size must be between 15 and 21 inclusive\n");
945  return CHMC_EINVAL;
946  }
947 #endif
948 
949  lzx_info.chm = chm;
950  lzx_info.section = chm->sections[sect_id];
951  lzx_info.done = 0;
952  lzx_info.todo = lzx_info.section->offset;
953  lzx_info.pos = chm->entries_list.next;
954  lzx_info.error = 0;
955  lzx_info.eof = 0;
956 
957  lzx_info.fd = -1;
958  lzx_info.fd_offset = 0;
959 
960  chmc_compressed_add_mark(lzx_info.chm, 0);
961  lzx_info.section->reset_table_header.block_count++;
962 
963  /* undocumented fact, according to Caie --
964  block size cannot exceed window size. (why not?) */
965  /* The block size must not be larger than the window size.
966  While the compressor will create apparently-valid LZX files
967  if this restriction is violated, some decompressors
968  will not handle them. */
969 
970  block_size = 1 << wsize_code;
971 
972  // lzx_info.section->control_data.windowSize = wsize_code;
973  // lzx_info.section->control_data.windowsPerReset = block_size;
974 
975  lzx_init(&lzxd, wsize_code,
976  _lzx_get_bytes, &lzx_info, _lzx_at_eof,
977  _lzx_put_bytes, &lzx_info,
978  _lzx_mark_frame, &lzx_info);
979 
980  while(! _lzx_at_eof(&lzx_info)) {
981  if (do_reset)
982  lzx_reset(lzxd);
983  lzx_compress_block(lzxd, block_size, subd_ok);
984  }
985  lzx_finish(lzxd, &lzxr);
986 
987  return CHMC_NOERR;
988 }
989 
990 static int _lzx_at_eof(void *arg)
991 {
992  struct chmcLzxInfo *lzx_info = (struct chmcLzxInfo *)arg;
993 
994  return lzx_info->error || lzx_info->done >= lzx_info->todo || lzx_info->eof;
995 }
996 
997 static int _lzx_put_bytes(void *arg, int n, void *buf)
998 {
999  struct chmcLzxInfo *lzx_info = (struct chmcLzxInfo *)arg;
1000  struct chmcSect0 *sect0 = &lzx_info->chm->sect0;
1001  int wx;
1002  static int counter = 0;
1003 
1004  counter += n;
1005  wx = write(lzx_info->section->fd, buf, n);
1006  sect0->file_len += wx;
1007  lzx_info->section->len += wx;
1008 
1009  return wx;
1010 }
1011 
1012 static void _lzx_mark_frame(void *arg, uint32_t uncomp, uint32_t comp)
1013 {
1014  struct chmcLzxInfo *lzx_info = (struct chmcLzxInfo *)arg;
1015  struct chmcSection *section = lzx_info->chm->sections[1];
1016 
1017  UInt64 compressed;
1018 
1019  chmc_dump( "Aligned data at %d(in compressed stream, %d) (%lu/%lu)\n",
1020  uncomp, comp, (unsigned long)lzx_info->done, (unsigned long)lzx_info->todo );
1021 
1022  compressed = comp;
1023 
1024  section->reset_table_header.block_count++;
1025 
1026  chmc_compressed_add_mark( lzx_info->chm, compressed );
1027 
1028  section->reset_table_header.uncompressed_len = uncomp;
1029  section->reset_table_header.compressed_len = comp;
1030 }
1031 
1032 static int _lzx_get_bytes(void *arg, int n, void *buf)
1033 {
1034  struct chmcLzxInfo *lzx_info = (struct chmcLzxInfo *)arg;
1035  struct chmcFile *chm = lzx_info->chm;
1036  struct chmcTreeNode *node;
1037 
1038  int todo;
1039  int done;
1040  int toread;
1041  int rx;
1042 
1043  todo = n;
1044  done = 0;
1045 
1046  // compression state machine
1047  // lzx compressor ask for block input bytes
1048  // need to keep current entry file and offset trought blocks
1049  // until last entry
1050  while (todo) {
1051  // end of entries reached?
1052  if (lzx_info->pos == &chm->entries_list) {
1053  lzx_info->eof = 1;
1054  break;
1055  }
1056 
1057  node = list_entry( lzx_info->pos, struct chmcTreeNode, list );
1058 
1059  // skip empty files and directories
1060  if (node->len == 0
1061  || strcmp("MSCompressed", chm->sections[node->sect_id]->name)) {
1062  lzx_info->pos = lzx_info->pos->next;
1063  continue;
1064  }
1065  else
1066  if (node->buf) {
1067  // have len and buffer, it's mallocated not file
1068  }
1069  else
1070  if (lzx_info->fd == -1) {
1071  // open file if it isn't
1072  lzx_info->fd = open(node->name, O_RDONLY | O_BINARY);
1073  if (lzx_info->fd < 0) {
1074  chmc_error("%s: %d: error %d: '%s' %s\n",
1075  __FILE__, __LINE__,
1076  errno, node->name, strerror(errno));
1077  lzx_info->error = 1;
1078  break;
1079  }
1080  }
1081 
1082  // read till the end of the file or till the lzx buffer is filled
1083  toread = node->len - lzx_info->fd_offset;
1084  if (toread > todo)
1085  toread = todo;
1086 
1087  if (toread <= 0)
1088  continue;
1089 
1090  // read input
1091  if (node->buf) {
1092  memcpy((char *)buf + (n - todo), &node->buf[lzx_info->fd_offset], toread);
1093  rx = toread;
1094  }
1095  else
1096  {
1097  rx = read(lzx_info->fd, (char *)buf + (n - todo), toread);
1098  if (rx <= 0) {
1099  int temp = errno;
1100  chmc_error("read error %s \n", strerror(temp));
1101  lzx_info->error = 2;
1102  break;
1103  }
1104  }
1105 
1106  todo -= rx;
1107  lzx_info->fd_offset += rx;
1108  done += rx;
1109  lzx_info->done += rx;
1110 
1111  // end of current file reached, goto next entry
1112  if (lzx_info->fd_offset == node->len) {
1113  if (lzx_info->fd > -1)
1114  close(lzx_info->fd);
1115  lzx_info->fd = -1;
1116  lzx_info->fd_offset = 0;
1117  lzx_info->pos = lzx_info->pos->next;
1118  }
1119  }
1120 
1121  return done;
1122 }
1123 
1125 {
1126  struct chmcSection *section;
1127  struct chmcResetTableMark *mark;
1128 
1129  assert(chm);
1130 
1131  section = chm->sections[1];
1132 
1133  mark = malloc(_CHMC_RSTTBL_MARK);
1134  if (mark) {
1135  mark->at = at;
1136  chmc_dump("[%d] at: %jd\n", section->mark_count, at);
1137  list_add_tail(&mark->list, &section->mark_list);
1138  section->mark_count++;
1139  return CHMC_NOERR;
1140  }
1141 
1142  return CHMC_ENOMEM;
1143 }
1144 
1146 {
1147  struct chmcTreeNode *ctrl;
1148 
1149  ctrl = chmc_add_meta(chm, "::DataSpace/Storage/MSCompressed/ControlData",
1150  0, (UChar *)&chm->sections[1]->control_data,
1152 
1153  if (ctrl) {
1154  ctrl->flags |= CHMC_TNFL_STATIC;
1155  return CHMC_NOERR;
1156  }
1157 
1158  return CHMC_ENOMEM;
1159 }
1160 
1162 {
1163  struct chmcSection *section;
1164  struct chmcLzxcResetTable *reset_table;
1165  struct list_head *pos;
1166  struct chmcResetTableMark *mark;
1167 
1168  UInt64 *at;
1169  int i, len;
1170 
1171  section = chm->sections[1];
1172 
1173  len = _CHMC_LZXC_RESETTABLE_V1_LEN + (section->mark_count * sizeof(UInt64));
1174 
1175  reset_table = malloc(len);
1176 
1177  if (reset_table) {
1178  memcpy(reset_table, &section->reset_table_header,
1180  at = (void *)((char *)reset_table + _CHMC_LZXC_RESETTABLE_V1_LEN);
1181 
1182  i = 0;
1183  list_for_each(pos, &section->mark_list) {
1184  mark = list_entry(pos, struct chmcResetTableMark, list);
1185  at[i++] = mark->at;
1186  }
1187 
1188  chmc_add_dir(chm, "::DataSpace/Storage/MSCompressed/Transform/"
1189  "{7FC28940-9D31-11D0-9B27-00A0C91E9C7C}/InstanceData/");
1190  chmc_add_meta(chm, "::DataSpace/Storage/MSCompressed/Transform/"
1191  "{7FC28940-9D31-11D0-9B27-00A0C91E9C7C}"
1192  "/InstanceData/ResetTable",
1193  0, (UChar *)reset_table, len);
1194 
1195  { // TODO FIXME do better
1196  UInt64 *uncompressed_len = malloc(8);
1197  if (uncompressed_len) {
1198  *uncompressed_len = reset_table->uncompressed_len;
1199  chmc_add_meta(chm, "::DataSpace/Storage/MSCompressed/SpanInfo",
1200  0, (UChar *)uncompressed_len, 8);
1201  }
1202  }
1203 
1204  return CHMC_NOERR;
1205  }
1206 
1207  return CHMC_ENOMEM;
1208 }
1209 
1210 void chmc_entries_qsort(struct chmcFile *chm)
1211 {
1212  struct chmcTreeNode *node;
1213  struct list_head *pos;
1214  int i;
1215 
1216  assert(chm);
1217 
1218  chm->sort_entries = malloc(sizeof(struct chmcTreeNode *)
1219  * chm->entries_num);
1220 
1221  i = 0;
1222  list_for_each(pos, &chm->entries_list) {
1223  node = list_entry(pos, struct chmcTreeNode, list);
1224  chm->sort_entries[i++] = node;
1225  }
1226 
1227  qsort(chm->sort_entries, chm->entries_num, sizeof(struct chmcTreeNode *),
1228  _entry_cmp);
1229 }
1230 
1231 static int _entry_cmp(const void *pva, const void *pvb)
1232 {
1233  const struct chmcTreeNode * const *pa = pva;
1234  const struct chmcTreeNode * const *pb = pvb;
1235  const struct chmcTreeNode *a = *pa, *b = *pb;
1236 
1237  return strcmp( &a->name[a->prefixlen], &b->name[b->prefixlen] );
1238 }
1239 
1241 {
1242  struct chmcSect0 *sect0 = &chm->sect0;
1243  struct chmcTreeNode *node;
1244  struct list_head *pos;
1245  int wx;
1246 
1247  list_for_each(pos, &chm->entries_list) {
1248  node = list_entry( pos, struct chmcTreeNode, list );
1249 
1250  if (strcmp( "MSCompressed", chm->sections[node->sect_id]->name ) == 0)
1251  continue;
1252 
1253  if ((node->buf) && (node->len > 0)) {
1254  wx = write(chm->sections[node->sect_id]->fd, node->buf, node->len);
1255  sect0->file_len += wx;
1256  }
1257  }
1258 
1259  return CHMC_NOERR;
1260 }
1261 
1262 void chmc_pmgl_done(struct chmcFile *chm)
1263 {
1264  struct chmcTreeNode *entry;
1265  int i;
1266 
1267  assert(chm);
1268 
1269  for(i=0; i < chm->entries_num; i++) {
1270  entry = chm->sort_entries[i];
1271  chmc_pmgl_add_entry(chm, entry);
1272  }
1273 }
1274 
1276 {
1277  struct chmcPmglChunkNode *pmgl;
1278  struct chmcPmglChunk *chunk;
1279  struct chmcSection *section;
1280  struct chmcItspHeader *itsp = &chm->itsp;
1281 
1282  UChar *p;
1283  UInt16 *idx;
1284  int name_len;
1285  int outlen;
1286  int should_idx, idx_intlv;
1287  int free;
1288 
1289  assert(chm);
1290  assert(entry);
1291 
1292  // check section bound
1293  section = chmc_section_lookup(chm, entry->sect_id);
1294  if (!section)
1295  chmcerr_set_return(CHMC_ENOMEM, "section %d lookup failed: ",
1296  entry->sect_id);
1297 
1298  // check chunk space for new entry
1299  name_len = strlen(&entry->name[entry->prefixlen]);
1300 
1301  outlen = chmc_encint_len(name_len);
1302  outlen += name_len;
1303  outlen += chmc_encint_len(entry->sect_id);
1304  outlen += chmc_encint_len(entry->offset);
1305  outlen += chmc_encint_len(entry->len);
1306 
1307  // look for current pmgl chunk, create if doesn't exist
1308  if (!chm->pmgl_last) {
1309  pmgl = chmc_pmgl_create();
1310  if (pmgl)
1311  chmc_pmgl_add(chm, pmgl);
1312  else
1313  chmcerr_set_return(CHMC_ENOMEM, "pmgl chunk: ");
1314  }
1315  else
1316  pmgl = chm->pmgl_last;
1317 
1318  do {
1319 
1320  chunk = &chm->pmgl_last->chunk;
1321 
1322  idx_intlv = 1 + ( 1 << itsp->blockidx_intvl );
1323  should_idx = ( ( chunk->entries_count > 0 )
1324  && ! ( ( chunk->entries_count + 1 ) % idx_intlv )
1325  ? 2 : 0 );
1326 
1327  free = sizeof(chunk->data) - pmgl->data_len - pmgl->index_len
1328  - should_idx;
1329 
1330  // current(last) chunk doesn't have enough room? force new one
1331  if (outlen + should_idx > free) {
1332  //chm->pmgl_last = NULL;
1333  pmgl = chmc_pmgl_create();
1334  if ( pmgl )
1335  chmc_pmgl_add(chm, pmgl);
1336  else
1337  chmcerr_set_return(CHMC_ENOMEM, "pmgl chunk: ");
1338 
1339  continue;
1340  }
1341 
1342  p = (void *)&chunk->data[pmgl->data_len];
1343 
1344  if (should_idx) {
1345  idx = (void *)((char *)&chunk->data[CHMC_PMGL_DATA_LEN] - pmgl->index_len);
1346  *idx = (char *)p - (char *)&chunk->data;
1347  }
1348 
1349  p += chmc_encint(name_len, p);
1350  memcpy(p, &entry->name[entry->prefixlen], name_len);
1351  p += name_len;
1352  p += chmc_encint(entry->sect_id, p);
1353  p += chmc_encint(entry->offset, p);
1354  p += chmc_encint(entry->len, p);
1355 
1356  pmgl->data_len += outlen;
1357  pmgl->index_len += should_idx;
1358 
1359  chunk->entries_count++;
1360  chunk->header.free_space -= outlen;
1361  break;
1362 
1363  } while (1);
1364 
1365  return CHMC_NOERR;
1366 }
1367 
1368 struct chmcSection *chmc_section_lookup(struct chmcFile *chm, int id)
1369 {
1370  struct chmcSection *current;
1371  struct list_head *pos;
1372  int i;
1373 
1374  assert(chm);
1375 
1376  i = 0;
1377  list_for_each(pos, &chm->sections_list) {
1378  current = list_entry(pos, struct chmcSection, list);
1379  if (i == id)
1380  return current;
1381  i++;
1382  }
1383 
1384  return NULL;
1385 }
1386 
1388 {
1389  struct chmcPmglChunkNode *node;
1390 
1391  node = malloc(sizeof(struct chmcPmglChunkNode));
1392  if (node)
1394 
1395  return node;
1396 }
1397 
1399 {
1400  struct chmcPmglChunk *chunk;
1401 
1402  assert(node);
1403 
1404  node->data_len = 0;
1405  node->index_len = 0;
1406 
1407  chunk = &node->chunk;
1408 
1409  memcpy(chunk->header.signature, "PMGL", 4);
1410 
1411  // FIXME check it is the right len
1412  chunk->header.free_space = CHMC_PMGL_DATA_LEN + 2;
1413  chunk->header.unknown_0008 = 0;
1414  chunk->header.block_prev = -1;
1415  chunk->header.block_next = -1;
1416 
1417  memset(chunk->data, 0, CHMC_PMGL_DATA_LEN);
1418 }
1419 
1421 {
1422  struct chmcPmgiChunk *chunk;
1423 
1424  assert(node);
1425 
1426  node->data_len = 0;
1427  node->index_len = 0;
1428 
1429  chunk = &node->chunk;
1430 
1431  memcpy(chunk->header.signature, "PMGI", 4);
1432 
1433  // FIXME check it is the right len
1434  chunk->header.free_space = CHMC_PMGI_DATA_LEN + 2;
1435  // chunk->header.unknown_0008 = 0;
1436  // chunk->header.block_prev = -1;
1437  // chunk->header.block_next = -1;
1438 
1439  memset(chunk->data, 0, CHMC_PMGI_DATA_LEN);
1440 }
1441 
1442 
1443 
1445 {
1446  struct chmcPmgiChunkNode *node;
1447 
1448  node = malloc(sizeof(struct chmcPmgiChunkNode));
1449  if (node)
1451 
1452  return node;
1453 }
1454 
1456 {
1457  assert(node);
1458  free(node);
1459 }
1460 
1462 {
1463  assert(node);
1464  free(node);
1465 }
1466 
1467 void chmc_pmgl_add(struct chmcFile *chm, struct chmcPmglChunkNode *pmgl)
1468 {
1469  struct chmcItspHeader *itsp = &chm->itsp;
1470  struct chmcPmglHeader *hdr;
1471 
1472  assert(chm);
1473  assert(pmgl);
1474 
1475  list_add_tail(&pmgl->list, &chm->pmgl_list);
1476 
1477  itsp->index_last = itsp->num_blocks;
1478 
1479  hdr = &pmgl->chunk.header;
1480  hdr->block_prev = itsp->num_blocks - 1;
1481 
1482  if (chm->pmgl_last) {
1483  hdr = &chm->pmgl_last->chunk.header;
1484  hdr->block_next = itsp->num_blocks;
1485  }
1486 
1487  itsp->num_blocks++;
1488 
1489  chm->pmgl_last = pmgl;
1490 }
1491 
1492 int chmc_pmgi_done(struct chmcFile *chm)
1493 {
1494  struct chmcItspHeader *itsp = &chm->itsp;
1495  struct chmcPmglChunkNode *pmgl;
1496  struct list_head *pos;
1497 
1498  int i, j;
1499  char name[256]; //FIXME use malloc
1500  UInt32 name_len;
1501 
1502  assert(chm);
1503 
1504  // only one pml, omitted pmgi
1505  if (itsp->num_blocks == 1) {
1506  itsp->index_depth = 1;
1507  itsp->index_root = -1;
1508  itsp->index_last = 0;
1509  return CHMC_NOERR;
1510  }
1511 
1512  itsp->index_root = itsp->num_blocks;
1513 
1514  i = 0;
1515  list_for_each(pos, &chm->pmgl_list) {
1516  pmgl = list_entry(pos, struct chmcPmglChunkNode, list);
1517  j = chmc_decint(&pmgl->chunk.data[0], &name_len);
1518  if (name_len <= 255) {
1519  memcpy(name, &pmgl->chunk.data[j], name_len);
1520  name[name_len] = '\0';
1521  chmc_pmgi_add_entry(chm, name, i);
1522  }
1523  else
1524  BUG_ON("name_len >= 255(%lu) %.*s\n", (unsigned long)name_len, 255,
1525  &pmgl->chunk.data[j]);
1526  i++;
1527  }
1528 
1529  return CHMC_NOERR;
1530 }
1531 
1532 int chmc_pmgi_add_entry(struct chmcFile *chm, const char *name, int pmgl_id)
1533 {
1534  struct chmcPmgiChunkNode *pmgi;
1535  struct chmcPmgiChunk *chunk;
1536  struct chmcItspHeader *itsp = &chm->itsp;
1537 
1538  UChar *p;
1539  UInt16 *idx;
1540  int name_len;
1541  int outlen;
1542  int should_idx, idx_intlv;
1543  int free;
1544 
1545  assert(chm);
1546 
1547  // check chunk space for new entry
1548  name_len = strlen(name);
1549 
1550  outlen = chmc_encint_len(name_len);
1551  outlen += name_len;
1552  outlen += chmc_encint_len(pmgl_id);
1553 
1554  // look for current pmgi chunk, create if doesn't exist
1555  if (!chm->pmgi_last) {
1556  pmgi = chmc_pmgi_create();
1557  if (pmgi)
1558  chmc_pmgi_add(chm, pmgi);
1559  else
1560  chmcerr_set_return(CHMC_ENOMEM, "pmgi chunk: ");
1561  }
1562  else
1563  pmgi = chm->pmgi_last;
1564 
1565  do {
1566 
1567  chunk = &chm->pmgi_last->chunk;
1568 
1569  idx_intlv = 1 + ( 1 << itsp->blockidx_intvl );
1570  should_idx = ( ( chunk->entries_count > 0 )
1571  && ! ( ( chunk->entries_count + 1 ) % idx_intlv )
1572  ? 2 : 0 );
1573 
1574  free = sizeof(chunk->data) - pmgi->data_len -
1575  pmgi->index_len - should_idx;
1576 
1577  // current(last) chunk doesn't have enough room? force new one
1578  if (outlen + should_idx > free) {
1579  pmgi = chmc_pmgi_create();
1580  if (pmgi)
1581  chmc_pmgi_add(chm, pmgi);
1582  else
1583  chmcerr_set_return(CHMC_ENOMEM, "pmgi chunk: ");
1584 
1585  continue;
1586  }
1587 
1588  p = (void *)&chunk->data[pmgi->data_len];
1589 
1590  if (should_idx) {
1591  idx = (void *)((char *)&chunk->data[CHMC_PMGI_DATA_LEN] - pmgi->index_len);
1592  *idx = (char *)p - (char *)&chunk->data;
1593  }
1594 
1595  p += chmc_encint(name_len, p);
1596  memcpy(p, name, name_len);
1597  p += name_len;
1598  p += chmc_encint(pmgl_id, p);
1599 
1600  pmgi->data_len += outlen;
1601  pmgi->index_len += should_idx;
1602 
1603  chunk->entries_count++;
1604  chunk->header.free_space -= outlen;
1605  break;
1606 
1607  } while (1);
1608 
1609  return CHMC_NOERR;
1610 }
1611 
1612 void chmc_pmgi_add(struct chmcFile *chm, struct chmcPmgiChunkNode *pmgi)
1613 {
1614  struct chmcItspHeader *itsp = &chm->itsp;
1615 
1616  assert(chm);
1617  assert(pmgi);
1618 
1619  list_add_tail(&pmgi->list, &chm->pmgi_list);
1620  itsp->num_blocks++;
1621 
1622  chm->pmgi_last = pmgi;
1623 }
1624 
1625 int chmc_write(struct chmcFile *chm)
1626 {
1627  struct chmcItsfHeader *itsf = &chm->itsf;
1628  struct chmcSect0 *sect0 = &chm->sect0;
1629  struct chmcItspHeader *itsp = &chm->itsp;
1630 
1631  struct chmcPmglChunkNode *pmgl;
1632  struct chmcPmgiChunkNode *pmgi;
1633  struct list_head *pos;
1634 
1635  assert(chm);
1636 
1637  chmc_dump("write itsf %d\n", _CHMC_ITSF_V3_LEN);
1638  write(chm->fd, itsf, _CHMC_ITSF_V3_LEN);
1639  chmc_dump("write sect0 %d\n", _CHMC_SECT0_LEN);
1640  write(chm->fd, sect0, _CHMC_SECT0_LEN);
1641  chmc_dump("write itsp %d\n", _CHMC_ITSP_V1_LEN);
1642  write(chm->fd, itsp, _CHMC_ITSP_V1_LEN);
1643 
1644  list_for_each(pos, &chm->pmgl_list) {
1645  pmgl = list_entry(pos, struct chmcPmglChunkNode, list);
1646  chmc_dump("write pmgl %d\n", _CHMC_CHUNK_LEN);
1647  write(chm->fd, &pmgl->chunk, _CHMC_CHUNK_LEN);
1648  }
1649 
1650  chmc_dump("itsp->num_blocks %d", itsp->num_blocks);
1651  if (itsp->num_blocks > 1) {
1652  list_for_each( pos, &chm->pmgi_list ) {
1653  pmgi = list_entry(pos, struct chmcPmgiChunkNode, list);
1654  chmc_dump("write pmgi %d\n", _CHMC_CHUNK_LEN);
1655  write(chm->fd, &pmgi->chunk, _CHMC_CHUNK_LEN);
1656  }
1657  }
1658 
1659  return CHMC_NOERR;
1660 }
1661 
1662 int chmc_appendfile(struct chmcFile *chm, const char *filename, void *buf,
1663  size_t size )
1664 {
1665  struct stat statbuf;
1666  int in;
1667  off_t todo, toread;
1668  int rx;
1669 
1670  if (stat(filename, &statbuf) < 0)
1671  return errno;
1672 
1674  if (in >= 0) {
1675  todo = statbuf.st_size;
1676 
1677  while (todo) {
1678  toread = size;
1679  if (toread > todo)
1680  toread = todo;
1681 
1682  rx = read(in, buf, toread);
1683  if (rx > 0) {
1684  write(chm->fd, buf, rx);
1685  todo -= rx;
1686  }
1687  }
1688 
1689  close(in);
1690  }
1691  else
1692  BUG_ON("open %s\n", filename);
1693 
1694  return CHMC_NOERR;
1695 }
#define BUG_ON(c)
Definition: module.h:253
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:1231
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:1161
int chmc_pmgi_done(struct chmcFile *chm)
Definition: chmc.c:1492
struct chmcLzxcControlData control_data
Definition: chmc.h:225
UInt64 uncompressed_len
Definition: chm.h:162
#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:115
Int32 header_len
Definition: chm.h:93
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:1625
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
static int _lzx_at_eof(void *arg)
Definition: chmc.c:990
UInt32 lang_id
Definition: chm.h:96
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:156
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:1368
Int32 index_last
Definition: chm.h:129
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:163
UInt32 sect_id
Definition: chmc.h:169
void chmc_pmgl_init(struct chmcPmglChunkNode *node)
Definition: chmc.c:1398
BYTE UChar
Definition: chm_lib.c:100
UInt64 block_len
Definition: chm.h:164
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:1612
if(dx==0 &&dy==0)
Definition: linetemp.h:174
const char * filename
Definition: ioapi.h:137
#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:1662
#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
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
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:1467
UInt32 block_count
Definition: chm.h:159
int error
Definition: chmc.c:124
struct chmcPmgiChunkNode * chmc_pmgi_create(void)
Definition: chmc.c:1444
UInt32 done
Definition: chmc.c:121
Int32 unknown_000c
Definition: chm.h:94
_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:1145
#define _CHMC_ITSF_V3_LEN
Definition: chm.h:89
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:160
unsigned int idx
Definition: utils.c:41
void chmc_pmgi_init(struct chmcPmgiChunkNode *node)
Definition: chmc.c:1420
static int chmc_decint(const UChar *in, UInt32 *value)
Definition: encint.h:78
UInt32 lang_id
Definition: chm.h:132
Int32 unknown_000c
Definition: chm.h:123
int chmc_compressed_add_mark(struct chmcFile *chm, UInt64 at)
Definition: chmc.c:1124
char signature[4]
Definition: chm.h:120
#define SIEC_IDXHDR
Definition: chmc.h:78
Int32 unknown_4
Definition: chmc.h:43
void chmc_pmgl_destroy(struct chmcPmglChunkNode *node)
Definition: chmc.c:1455
#define chmcerr_msg(fmt,...)
Definition: err.h:59
Int32 unknown_0028
Definition: chm.h:130
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:91
#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:99
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:1240
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:158
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
Int32 version
Definition: chm.h:121
_Check_return_ _CRTIMP int __cdecl fileno(_In_ FILE *_File)
#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
GLintptr offset
Definition: glext.h:5920
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
SYSTEM_INFO sysinfo
Definition: dbghelp.c:76
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:98
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
struct chmcFile * chm
Definition: chmc.c:117
struct task_struct * current
Definition: linux.c:32
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:997
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:1275
#define _CHMC_SECT0_LEN
Definition: chm.h:106
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:107
UInt32 block_len
Definition: chm.h:124
#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:1012
GLdouble s
Definition: gl.h:2039
Int32 header_len
Definition: chm.h:122
Definition: _list.h:228
#define O_TRUNC
Definition: acwin.h:112
#define close
Definition: acwin.h:98
Definition: inflate.c:139
UInt64 dir_len
Definition: chm.h:102
#define O_BINARY
Definition: chmc.c:53
#define CHMC_NOERR
Definition: err.h:39
UChar system_uuid[16]
Definition: chm.h:133
Int32 unknown_0000
Definition: chm.h:108
int code
Definition: main.c:75
UInt64 sect0_len
Definition: chm.h:100
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:169
void chmc_pmgi_destroy(struct chmcPmgiChunkNode *node)
Definition: chmc.c:1461
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:134
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
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
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:1532
#define O_RDWR
Definition: fcntl.h:36
Int32 index_root
Definition: chm.h:127
SHORT Int16
Definition: chm_lib.c:101
Int32 blockidx_intvl
Definition: chm.h:125
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
#define NULL
Definition: types.h:112
UInt64 data_offset
Definition: chm.h:103
UInt64 file_len
Definition: chm.h:110
#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:97
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:1032
Definition: name.c:38
#define calloc
Definition: rosglue.h:14
void chmc_entries_qsort(struct chmcFile *chm)
Definition: chmc.c:1210
Int32 version
Definition: chm.h:92
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:126
#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:101
UInt32 num_blocks
Definition: chm.h:131
#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:118
#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:135
#define d
Definition: ke_i.h:81
UInt32 table_offset
Definition: chm.h:161
_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 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:1387
Int32 unknown_8
Definition: chmc.h:44
void chmc_pmgl_done(struct chmcFile *chm)
Definition: chmc.c:1262
Definition: dlist.c:348
struct list_head list
Definition: chmc.h:158
#define O_RDONLY
Definition: acwin.h:108
Definition: fci.c:126