ReactOS 0.4.16-dev-303-g11d5cb8
chmc.c File Reference
#include "chmc.h"
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "../../port/port.h"
#include <unistd.h>
#include "err.h"
#include "encint.h"
#include <stdint.h>
#include "../lzx_compress/lzx_config.h"
#include "../lzx_compress/lzx_compress.h"
Include dependency graph for chmc.c:

Go to the source code of this file.

Classes

struct  chmcLzxInfo
 

Macros

#define PACKAGE_STRING   "hhpcomp development version"
 
#define O_BINARY   0
 

Functions

int chmc_section_add (struct chmcFile *chm, const char *name)
 
struct chmcSectionchmc_section_create (struct chmcFile *chm, const char *name)
 
void chmc_reset_table_init (struct chmcLzxcResetTable *reset_table)
 
void chmc_control_data_init (struct chmcLzxcControlData *control_data)
 
int chmc_namelist_create (struct chmcFile *chm, int len)
 
struct chmcTreeNodechmc_add_meta (struct chmcFile *chm, const char *metaname, int sect_id, UChar *buf, UInt64 len)
 
struct chmcTreeNodechmc_add_entry (struct chmcFile *chm, const char *name, UInt16 prefixlen, int sect_id, UChar *buf, UInt64 offset, UInt64 len)
 
void chmc_sections_free (struct chmcFile *chm)
 
void chmc_section_destroy (struct chmcSection *section)
 
void chmc_pmgi_free (struct chmcFile *chm)
 
void chmc_pmgl_free (struct chmcFile *chm)
 
void chmc_pmgl_destroy (struct chmcPmglChunkNode *node)
 
void chmc_pmgi_destroy (struct chmcPmgiChunkNode *node)
 
void chmc_entries_free (struct chmcFile *chm)
 
void chmc_entry_destroy (struct chmcTreeNode *node)
 
int chmc_add_tree (struct chmcFile *chm, const char *dir)
 
struct chmcTreeNodechmc_add_file (struct chmcFile *chm, const char *filename, UInt16 prefixlen, int sect_id, UChar *buf, UInt64 len)
 
struct chmcTreeNodechmc_add_dir (struct chmcFile *chm, const char *dir)
 
struct chmcTreeNodechmc_add_empty (struct chmcFile *chm, const char *file)
 
int chmc_crunch_lzx (struct chmcFile *chm, int sect_id)
 
static int _lzx_at_eof (void *arg)
 
static int _lzx_put_bytes (void *arg, int n, void *buf)
 
static void _lzx_mark_frame (void *arg, uint32_t uncomp, uint32_t comp)
 
static int _lzx_get_bytes (void *arg, int n, void *buf)
 
int chmc_compressed_add_mark (struct chmcFile *chm, UInt64 at)
 
int chmc_control_data_done (struct chmcFile *chm)
 
int chmc_reset_table_done (struct chmcFile *chm)
 
void chmc_pmgl_done (struct chmcFile *chm)
 
void chmc_entries_qsort (struct chmcFile *chm)
 
static int _entry_cmp (const void *pva, const void *pvb)
 
struct chmcSectionchmc_section_lookup (struct chmcFile *chm, int id)
 
struct chmcPmglChunkNodechmc_pmgl_create (void)
 
void chmc_pmgl_add (struct chmcFile *chm, struct chmcPmglChunkNode *pmgl)
 
void chmc_pmgl_init (struct chmcPmglChunkNode *node)
 
int chmc_pmgi_add_entry (struct chmcFile *chm, const char *name, int pmgl_id)
 
void chmc_pmgi_add (struct chmcFile *chm, struct chmcPmgiChunkNode *pmgi)
 
void chmc_string_init (struct chmcStringChunk *node)
 
int chmc_init (struct chmcFile *chm, const char *filename, struct chmcConfig *config)
 
void chmc_sections_done (struct chmcFile *chm)
 
void chmc_term (struct chmcFile *chm)
 
UInt32 chmc_strings_add (struct chmcFile *chm, const char *s)
 
static voidchmc_syscat_mem (void *d, void *s, unsigned long len)
 
static voidchmc_syscat_entry (Int16 code, void *d, void *s, Int16 len)
 
int chmc_system_done (struct chmcFile *chm)
 
int chmc_tree_done (struct chmcFile *chm)
 
int chmc_uncompressed_done (struct chmcFile *chm)
 
int chmc_pmgl_add_entry (struct chmcFile *chm, struct chmcTreeNode *entry)
 
void chmc_pmgi_init (struct chmcPmgiChunkNode *node)
 
struct chmcPmgiChunkNodechmc_pmgi_create (void)
 
int chmc_pmgi_done (struct chmcFile *chm)
 
int chmc_write (struct chmcFile *chm)
 
int chmc_appendfile (struct chmcFile *chm, const char *filename, void *buf, size_t size)
 

Variables

static const short chmc_transform_list []
 

Macro Definition Documentation

◆ O_BINARY

#define O_BINARY   0

Definition at line 53 of file chmc.c.

◆ PACKAGE_STRING

#define PACKAGE_STRING   "hhpcomp development version"

Definition at line 49 of file chmc.c.

Function Documentation

◆ _entry_cmp()

static int _entry_cmp ( const void pva,
const void pvb 
)
static

Definition at line 1231 of file chmc.c.

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}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
static int ** pa
Definition: server.c:126

Referenced by chmc_entries_qsort().

◆ _lzx_at_eof()

static int _lzx_at_eof ( void arg)
static

Definition at line 990 of file chmc.c.

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}
UInt32 done
Definition: chmc.c:121
int eof
Definition: chmc.c:125
int error
Definition: chmc.c:124
UInt32 todo
Definition: chmc.c:122

Referenced by chmc_crunch_lzx().

◆ _lzx_get_bytes()

static int _lzx_get_bytes ( void arg,
int  n,
void buf 
)
static

Definition at line 1032 of file chmc.c.

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}
#define read
Definition: acwin.h:96
#define O_RDONLY
Definition: acwin.h:108
#define open
Definition: acwin.h:95
#define close
Definition: acwin.h:98
#define O_BINARY
Definition: chmc.c:53
Definition: list.h:37
#define list_entry(ptr, type, member)
Definition: list.h:185
GLdouble n
Definition: glext.h:7729
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
BOOL todo
Definition: filedlg.c:313
const char * strerror(int err)
Definition: compat_str.c:23
static calc_node_t temp
Definition: rpn_ieee.c:38
#define errno
Definition: errno.h:18
#define chmc_error(fmt,...)
Definition: err.h:48
Definition: chmc.h:192
struct list_head entries_list
Definition: chmc.h:202
struct chmcSection ** sections
Definition: chmc.h:199
UInt32 fd_offset
Definition: chmc.c:120
struct chmcFile * chm
Definition: chmc.c:117
int fd
Definition: chmc.c:119
struct list_head * pos
Definition: chmc.c:123
Definition: dlist.c:348

Referenced by chmc_crunch_lzx().

◆ _lzx_mark_frame()

static void _lzx_mark_frame ( void arg,
uint32_t  uncomp,
uint32_t  comp 
)
static

Definition at line 1012 of file chmc.c.

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}
ULONGLONG UInt64
Definition: chm_lib.c:106
int chmc_compressed_add_mark(struct chmcFile *chm, UInt64 at)
Definition: chmc.c:1124
#define chmc_dump(fmt,...)
Definition: chmc.h:263
Definition: parser.c:56

Referenced by chmc_crunch_lzx().

◆ _lzx_put_bytes()

static int _lzx_put_bytes ( void arg,
int  n,
void buf 
)
static

Definition at line 997 of file chmc.c.

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}
#define write
Definition: acwin.h:97
struct chmcSection * section
Definition: chmc.c:118
Definition: chm.h:107
UInt64 file_len
Definition: chm.h:110

Referenced by chmc_crunch_lzx().

◆ chmc_add_dir()

struct chmcTreeNode * chmc_add_dir ( struct chmcFile chm,
const char dir 
)

Definition at line 621 of file chmc.c.

622{
623 assert(chm);
624
625 return chmc_add_entry(chm, dir, 0, 0, NULL, 0, 0);
626}
unsigned int dir
Definition: maze.c:112
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
#define NULL
Definition: types.h:112
#define assert(x)
Definition: debug.h:53

Referenced by chmc_reset_table_done(), and chmc_tree_done().

◆ chmc_add_empty()

struct chmcTreeNode * chmc_add_empty ( struct chmcFile chm,
const char file 
)

Definition at line 401 of file chmc.c.

402{
403 assert(chm);
404 return chmc_add_entry(chm, file, 0, 0, NULL, 0, 0);
405}
Definition: fci.c:127

Referenced by chmc_tree_done().

◆ chmc_add_entry()

struct chmcTreeNode * chmc_add_entry ( struct chmcFile chm,
const char name,
UInt16  prefixlen,
int  sect_id,
UChar buf,
UInt64  offset,
UInt64  len 
)

Definition at line 429 of file chmc.c.

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}
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
#define malloc
Definition: debug_ros.c:4
GLenum GLsizei len
Definition: glext.h:6722
GLintptr offset
Definition: glext.h:5920
#define stderr
Definition: stdio.h:100
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define BUG_ON(c)
Definition: module.h:255
_Check_return_ _CRTIMP char *__cdecl strdup(_In_opt_z_ const char *_Src)
int entries_num
Definition: chmc.h:203
int sections_num
Definition: chmc.h:197
UInt32 sect_id
Definition: chmc.h:169
UInt16 prefixlen
Definition: chmc.h:171
Definition: name.c:39

Referenced by chmc_add_dir(), chmc_add_empty(), chmc_add_file(), and chmc_add_meta().

◆ chmc_add_file()

struct chmcTreeNode * chmc_add_file ( struct chmcFile chm,
const char filename,
UInt16  prefixlen,
int  sect_id,
UChar buf,
UInt64  len 
)

Definition at line 598 of file chmc.c.

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}
const char * filename
Definition: ioapi.h:137

Referenced by main().

◆ chmc_add_meta()

struct chmcTreeNode * chmc_add_meta ( struct chmcFile chm,
const char metaname,
int  sect_id,
UChar buf,
UInt64  len 
)

Definition at line 407 of file chmc.c.

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}

Referenced by chmc_control_data_done(), chmc_namelist_create(), chmc_reset_table_done(), chmc_system_done(), and chmc_tree_done().

◆ chmc_add_tree()

int chmc_add_tree ( struct chmcFile chm,
const char dir 
)

◆ chmc_appendfile()

int chmc_appendfile ( struct chmcFile chm,
const char filename,
void buf,
size_t  size 
)

Definition at line 1662 of file chmc.c.

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 stat
Definition: acwin.h:99
__kernel_off_t off_t
Definition: linux.h:201
GLsizeiptr size
Definition: glext.h:5919
GLuint in
Definition: glext.h:9616
#define CHMC_NOERR
Definition: err.h:39
int fd
Definition: chmc.h:193
Definition: stat.h:55

Referenced by chmc_tree_done().

◆ chmc_compressed_add_mark()

int chmc_compressed_add_mark ( struct chmcFile chm,
UInt64  at 
)

Definition at line 1124 of file chmc.c.

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}
#define _CHMC_RSTTBL_MARK
Definition: chmc.h:230
#define CHMC_ENOMEM
Definition: err.h:40
struct list_head list
Definition: chmc.h:234

Referenced by _lzx_mark_frame(), and chmc_crunch_lzx().

◆ chmc_control_data_done()

int chmc_control_data_done ( struct chmcFile chm)

Definition at line 1145 of file chmc.c.

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}
#define _CHMC_LZXC_V2_LEN
Definition: chm.h:169
BYTE UChar
Definition: chm_lib.c:100
struct chmcTreeNode * chmc_add_meta(struct chmcFile *chm, const char *metaname, int sect_id, UChar *buf, UInt64 len)
Definition: chmc.c:407
#define CHMC_TNFL_STATIC
Definition: chmc.h:164
#define ctrl
Definition: input.c:1756

Referenced by chmc_tree_done().

◆ chmc_control_data_init()

void chmc_control_data_init ( struct chmcLzxcControlData control_data)

Definition at line 337 of file chmc.c.

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}
UInt32 version
Definition: chm.h:173
UInt32 windowSize
Definition: chm.h:175
UInt32 size
Definition: chm.h:171
char signature[4]
Definition: chm.h:172
UInt32 resetInterval
Definition: chm.h:174
UInt32 windowsPerReset
Definition: chm.h:176
UInt32 unknown_18
Definition: chm.h:177

Referenced by chmc_section_create().

◆ chmc_crunch_lzx()

int chmc_crunch_lzx ( struct chmcFile chm,
int  sect_id 
)

Definition at line 929 of file chmc.c.

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}
static void _lzx_mark_frame(void *arg, uint32_t uncomp, uint32_t comp)
Definition: chmc.c:1012
static int _lzx_get_bytes(void *arg, int n, void *buf)
Definition: chmc.c:1032
static int _lzx_put_bytes(void *arg, int n, void *buf)
Definition: chmc.c:997
static int _lzx_at_eof(void *arg)
Definition: chmc.c:990
static DWORD block_size(DWORD block)
Definition: jsutils.c:66
int lzx_finish(struct lzx_data *lzxd, struct lzx_results *lzxr)
Definition: lzx_layer.c:1236
int lzx_init(struct lzx_data **lzxdp, int wsize_code, lzx_get_bytes_t get_bytes, void *get_bytes_arg, lzx_at_eof_t at_eof, lzx_put_bytes_t put_bytes, void *put_bytes_arg, lzx_mark_frame_t mark_frame, void *mark_frame_arg)
Definition: lzx_layer.c:1189
int lzx_compress_block(lzx_data *lzxd, int block_size, int subdivide)
Definition: lzx_layer.c:1062
void lzx_reset(lzx_data *lzxd)
Definition: lzx_layer.c:1053
#define CHMC_EINVAL
Definition: err.h:41

Referenced by chmc_tree_done().

◆ chmc_entries_free()

void chmc_entries_free ( struct chmcFile chm)

Definition at line 542 of file chmc.c.

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}
void chmc_entry_destroy(struct chmcTreeNode *node)
Definition: chmc.c:587
#define free
Definition: debug_ros.c:5
#define list_for_each_safe(pos, n, head)
Definition: list.h:211
static void list_del(struct list_head *entry)
Definition: list.h:89
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
struct chmcTreeNode ** sort_entries
Definition: chmc.h:204
Definition: list.h:15

Referenced by chmc_term().

◆ chmc_entries_qsort()

void chmc_entries_qsort ( struct chmcFile chm)

Definition at line 1210 of file chmc.c.

1211{
1212 struct chmcTreeNode *node;
1213 struct list_head *pos;
1214 int i;
1215
1216 assert(chm);
1217
1218 chm->sort_entries = malloc(sizeof(struct chmcTreeNode *)
1219 * chm->entries_num);
1220
1221 i = 0;
1223 node = list_entry(pos, struct chmcTreeNode, list);
1224 chm->sort_entries[i++] = node;
1225 }
1226
1227 qsort(chm->sort_entries, chm->entries_num, sizeof(struct chmcTreeNode *),
1228 _entry_cmp);
1229}
#define list_for_each(entry, head)
Definition: list.h:36
static int _entry_cmp(const void *pva, const void *pvb)
Definition: chmc.c:1231
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
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 *))

Referenced by chmc_tree_done().

◆ chmc_entry_destroy()

void chmc_entry_destroy ( struct chmcTreeNode node)

Definition at line 587 of file chmc.c.

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}

Referenced by chmc_entries_free().

◆ chmc_init()

int chmc_init ( struct chmcFile chm,
const char filename,
struct chmcConfig config 
)

Definition at line 133 of file chmc.c.

135{
136 struct chmcItsfHeader *itsf = &chm->itsf;
137 struct chmcSect0 *sect0 = &chm->sect0;
138 struct chmcItspHeader *itsp = &chm->itsp;
139 struct chmcSystem *system = &chm->system;
140 struct chmcSystemInfo *sysinfo = &chm->system.info;
141 struct chmcIndexHeader *idxhdr = &chm->idxhdr;
142
143 assert(chm);
145
147
148 memset(chm, 0, sizeof(struct chmcFile));
149
150 chm->config = config;
151
152 if (strcmp(filename, "-") != 0) {
153 chm->fd = open(filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0644);
154 if (chm->fd < 0) {
156 chmcerr_return_msg("creat file '%s'", filename);
157 }
158 } else {
159 chm->fd = fileno(stdout);
160 }
161
162 memcpy(itsf->signature, "ITSF", 4);
163 itsf->version = 3;
165 itsf->unknown_000c = 1;
166
167 itsf->lang_id = chm->config->language;
168 memcpy(itsf->dir_uuid, CHMC_DIR_UUID, 16);
171
174
178
179 sect0->unknown_0000 = 510;
180
181 memcpy(itsp->signature, "ITSP", 4);
182 itsp->version = 1;
184 itsp->unknown_000c = 10;
187 itsp->index_depth = 2;
188
189 itsp->unknown_0028 = -1;
193 memset(itsp->unknown_0048, -1, 12);
194
195 system->version = 3;
196 system->_size = _CHMC_SYSTEM_HDR_LEN + sizeof(struct chmcIndexHeader);
197
199
200 memcpy(idxhdr->signature, "T#SM", 4);
201 idxhdr->unknown_4 = 28582569; // FIXME got from some chm
202 idxhdr->unknown_8 = 1;
203 // idxhdr->full_search = 1;
204 // idxhdr->klinks = 1;
205 // idxhdr->alinks = 0;
206 // idxhdr->timestamp = ???;
207
208 // idxhdr->num_of_topic = 2; // sorry??
209 idxhdr->off_img_list = -1;
210 // idxhdr->img_type_folder;
211 idxhdr->background = -1;
212 idxhdr->foreground = -1;
213 idxhdr->off_font = -1;
214 idxhdr->win_style = -1;
215 idxhdr->ex_win_style = -1;
216 idxhdr->unknown_34 = -1;
217 idxhdr->off_frame_name = -1;
218 idxhdr->off_win_name = -1;
219 // idxhdr->num_of_info;
220 idxhdr->unknown_44 = 1;
221 // idxhdr->num_of_merge_files;
222 // idxhdr->unknown_4c;
223
228
229 chm->strings = malloc(4096);
230 memset(chm->strings, 0, 4096);
231 chm->strings_len = 4096;
232 chm->strings_offset = 1;
233
234 if (chmc_section_add(chm, "Uncompressed") != CHMC_NOERR)
235 chmcerr_return_msg("adding section: Uncompressed");
236
237 if (chmc_section_add(chm, "MSCompressed") != CHMC_NOERR)
238 chmcerr_return_msg("adding section: MSCompressed");
239
241
242 return CHMC_NOERR;
243}
#define O_CREAT
Definition: acwin.h:110
#define fileno
Definition: acwin.h:102
#define O_TRUNC
Definition: acwin.h:112
#define _CHMC_ITSP_V1_LEN
Definition: chm.h:118
#define _CHMC_ITSF_V3_LEN
Definition: chm.h:89
#define _CHMC_SECT0_LEN
Definition: chm.h:106
#define CHM_IDX_INTVL
Definition: chm.h:115
void chmc_sections_done(struct chmcFile *chm)
Definition: chmc.c:348
int chmc_section_add(struct chmcFile *chm, const char *name)
Definition: chmc.c:245
#define CHMC_SYSTEM_UUID
Definition: chmc.h:38
#define _CHMC_CHUNK_LEN
Definition: chmc.h:133
#define _CHMC_SYSTEM_HDR_LEN
Definition: chmc.h:123
#define CHMC_MS_LCID_EN_US
Definition: chmc.h:121
#define CHMC_STREAM_UUID
Definition: chmc.h:36
#define CHMC_DIR_UUID
Definition: chmc.h:34
struct config_s config
SYSTEM_INFO sysinfo
Definition: dbghelp.c:76
#define INIT_LIST_HEAD(ptr)
Definition: list.h:24
#define O_RDWR
Definition: fcntl.h:36
#define stdout
Definition: stdio.h:99
int __cdecl system(_In_opt_z_ const char *_Command)
#define memset(x, y, z)
Definition: compat.h:39
void chmcerr_set(int code, const char *fmt,...)
Definition: err.c:50
void chmcerr_clean(void)
Definition: err.c:37
#define chmcerr_return_msg(fmt,...)
Definition: err.h:50
struct chmcItsfHeader itsf
Definition: chmc.h:194
struct chmcSystem system
Definition: chmc.h:207
struct chmcConfig * config
Definition: chmc.h:212
struct list_head pmgl_list
Definition: chmc.h:200
UInt32 strings_offset
Definition: chmc.h:210
struct chmcSect0 sect0
Definition: chmc.h:195
struct chmcIndexHeader idxhdr
Definition: chmc.h:208
struct chmcItspHeader itsp
Definition: chmc.h:196
struct list_head sections_list
Definition: chmc.h:198
UChar * strings
Definition: chmc.h:209
UInt32 strings_len
Definition: chmc.h:211
struct list_head pmgi_list
Definition: chmc.h:205
Int32 win_style
Definition: chmc.h:53
Int32 unknown_4
Definition: chmc.h:43
Int32 unknown_8
Definition: chmc.h:44
Int32 ex_win_style
Definition: chmc.h:54
Int32 background
Definition: chmc.h:50
Int32 off_img_list
Definition: chmc.h:47
Int32 foreground
Definition: chmc.h:51
Int32 off_font
Definition: chmc.h:52
Int32 unknown_44
Definition: chmc.h:59
char signature[4]
Definition: chmc.h:42
Int32 off_frame_name
Definition: chmc.h:56
Int32 off_win_name
Definition: chmc.h:57
Int32 unknown_34
Definition: chmc.h:55
Int32 unknown_000c
Definition: chm.h:94
Int32 version
Definition: chm.h:92
UInt64 sect0_offset
Definition: chm.h:99
UChar stream_uuid[16]
Definition: chm.h:98
UInt64 dir_offset
Definition: chm.h:101
char signature[4]
Definition: chm.h:91
UChar dir_uuid[16]
Definition: chm.h:97
UInt32 lang_id
Definition: chm.h:96
Int32 header_len
Definition: chm.h:93
UInt64 sect0_len
Definition: chm.h:100
char signature[4]
Definition: chm.h:120
UInt32 block_len
Definition: chm.h:124
Int32 version
Definition: chm.h:121
Int32 index_depth
Definition: chm.h:126
UInt32 header_len2
Definition: chm.h:134
Int32 unknown_000c
Definition: chm.h:123
UInt32 lang_id
Definition: chm.h:132
UChar unknown_0048[12]
Definition: chm.h:135
Int32 header_len
Definition: chm.h:122
Int32 unknown_0028
Definition: chm.h:130
UChar system_uuid[16]
Definition: chm.h:133
Int32 blockidx_intvl
Definition: chm.h:125
Int32 unknown_0000
Definition: chm.h:108

Referenced by main().

◆ chmc_namelist_create()

int chmc_namelist_create ( struct chmcFile chm,
int  len 
)

Definition at line 372 of file chmc.c.

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}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
USHORT UInt16
Definition: chm_lib.c:102
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
int k
Definition: mpi.c:3369
const WCHAR * name
Definition: parser.c:57

Referenced by chmc_sections_done().

◆ chmc_pmgi_add()

void chmc_pmgi_add ( struct chmcFile chm,
struct chmcPmgiChunkNode pmgi 
)

Definition at line 1612 of file chmc.c.

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}
struct chmcPmgiChunkNode * pmgi_last
Definition: chmc.h:206
UInt32 num_blocks
Definition: chm.h:131
struct list_head list
Definition: chmc.h:158

Referenced by chmc_pmgi_add_entry().

◆ chmc_pmgi_add_entry()

int chmc_pmgi_add_entry ( struct chmcFile chm,
const char name,
int  pmgl_id 
)

Definition at line 1532 of file chmc.c.

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}
void chmc_pmgi_add(struct chmcFile *chm, struct chmcPmgiChunkNode *pmgi)
Definition: chmc.c:1612
struct chmcPmgiChunkNode * chmc_pmgi_create(void)
Definition: chmc.c:1444
#define CHMC_PMGI_DATA_LEN
Definition: chmc.h:149
unsigned int idx
Definition: utils.c:41
static int chmc_encint(const UInt32 val, UChar *out)
Definition: encint.h:46
static int chmc_encint_len(const UInt32 val)
Definition: encint.h:28
GLfloat GLfloat p
Definition: glext.h:8902
if(dx< 0)
Definition: linetemp.h:194
#define chmcerr_set_return(code, fmt,...)
Definition: err.h:67

Referenced by chmc_pmgi_done().

◆ chmc_pmgi_create()

struct chmcPmgiChunkNode * chmc_pmgi_create ( void  )

Definition at line 1444 of file chmc.c.

1445{
1446 struct chmcPmgiChunkNode *node;
1447
1448 node = malloc(sizeof(struct chmcPmgiChunkNode));
1449 if (node)
1451
1452 return node;
1453}
void chmc_pmgi_init(struct chmcPmgiChunkNode *node)
Definition: chmc.c:1420

Referenced by chmc_pmgi_add_entry().

◆ chmc_pmgi_destroy()

void chmc_pmgi_destroy ( struct chmcPmgiChunkNode node)

Definition at line 1461 of file chmc.c.

1462{
1463 assert(node);
1464 free(node);
1465}

Referenced by chmc_pmgi_free().

◆ chmc_pmgi_done()

int chmc_pmgi_done ( struct chmcFile chm)

Definition at line 1492 of file chmc.c.

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}
DWORD UInt32
Definition: chm_lib.c:104
int chmc_pmgi_add_entry(struct chmcFile *chm, const char *name, int pmgl_id)
Definition: chmc.c:1532
static int chmc_decint(const UChar *in, UInt32 *value)
Definition: encint.h:78
Int32 index_root
Definition: chm.h:127
Int32 index_last
Definition: chm.h:129
struct chmcPmglChunk chunk
Definition: chmc.h:146

Referenced by chmc_tree_done().

◆ chmc_pmgi_free()

void chmc_pmgi_free ( struct chmcFile chm)

Definition at line 514 of file chmc.c.

515{
516 struct chmcPmgiChunkNode *node;
517 struct list_head *pos, *q;
518
519 assert(chm);
520
523 list_del(pos);
525 }
526}
void chmc_pmgi_destroy(struct chmcPmgiChunkNode *node)
Definition: chmc.c:1461

Referenced by chmc_term().

◆ chmc_pmgi_init()

void chmc_pmgi_init ( struct chmcPmgiChunkNode node)

Definition at line 1420 of file chmc.c.

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}

Referenced by chmc_pmgi_create().

◆ chmc_pmgl_add()

void chmc_pmgl_add ( struct chmcFile chm,
struct chmcPmglChunkNode pmgl 
)

Definition at line 1467 of file chmc.c.

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}
char hdr[14]
Definition: iptest.cpp:33
struct chmcPmglChunkNode * pmgl_last
Definition: chmc.h:201
struct list_head list
Definition: chmc.h:143

Referenced by chmc_pmgl_add_entry().

◆ chmc_pmgl_add_entry()

int chmc_pmgl_add_entry ( struct chmcFile chm,
struct chmcTreeNode entry 
)

Definition at line 1275 of file chmc.c.

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}
void chmc_pmgl_add(struct chmcFile *chm, struct chmcPmglChunkNode *pmgl)
Definition: chmc.c:1467
struct chmcPmglChunkNode * chmc_pmgl_create(void)
Definition: chmc.c:1387
struct chmcSection * chmc_section_lookup(struct chmcFile *chm, int id)
Definition: chmc.c:1368
#define CHMC_PMGL_DATA_LEN
Definition: chmc.h:134
uint32_t entry
Definition: isohybrid.c:63

Referenced by chmc_pmgl_done().

◆ chmc_pmgl_create()

struct chmcPmglChunkNode * chmc_pmgl_create ( void  )

Definition at line 1387 of file chmc.c.

1388{
1389 struct chmcPmglChunkNode *node;
1390
1391 node = malloc(sizeof(struct chmcPmglChunkNode));
1392 if (node)
1394
1395 return node;
1396}
void chmc_pmgl_init(struct chmcPmglChunkNode *node)
Definition: chmc.c:1398

Referenced by chmc_pmgl_add_entry().

◆ chmc_pmgl_destroy()

void chmc_pmgl_destroy ( struct chmcPmglChunkNode node)

Definition at line 1455 of file chmc.c.

1456{
1457 assert(node);
1458 free(node);
1459}

Referenced by chmc_pmgl_free().

◆ chmc_pmgl_done()

void chmc_pmgl_done ( struct chmcFile chm)

Definition at line 1262 of file chmc.c.

1263{
1264 struct chmcTreeNode *entry;
1265 int i;
1266
1267 assert(chm);
1268
1269 for(i=0; i < chm->entries_num; i++) {
1270 entry = chm->sort_entries[i];
1272 }
1273}
int chmc_pmgl_add_entry(struct chmcFile *chm, struct chmcTreeNode *entry)
Definition: chmc.c:1275

Referenced by chmc_tree_done().

◆ chmc_pmgl_free()

void chmc_pmgl_free ( struct chmcFile chm)

Definition at line 528 of file chmc.c.

529{
530 struct chmcPmglChunkNode *node;
531 struct list_head *pos, *q;
532
533 assert(chm);
534
537 list_del(pos);
539 }
540}
void chmc_pmgl_destroy(struct chmcPmglChunkNode *node)
Definition: chmc.c:1455

Referenced by chmc_term().

◆ chmc_pmgl_init()

void chmc_pmgl_init ( struct chmcPmglChunkNode node)

Definition at line 1398 of file chmc.c.

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}

Referenced by chmc_pmgl_create().

◆ chmc_reset_table_done()

int chmc_reset_table_done ( struct chmcFile chm)

Definition at line 1161 of file chmc.c.

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}
#define _CHMC_LZXC_RESETTABLE_V1_LEN
Definition: chm.h:156
struct chmcTreeNode * chmc_add_dir(struct chmcFile *chm, const char *dir)
Definition: chmc.c:621

Referenced by chmc_tree_done().

◆ chmc_reset_table_init()

void chmc_reset_table_init ( struct chmcLzxcResetTable reset_table)

Definition at line 326 of file chmc.c.

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}
UInt32 version
Definition: chm.h:158
UInt32 entry_size
Definition: chm.h:160
UInt64 compressed_len
Definition: chm.h:163
UInt32 table_offset
Definition: chm.h:161
UInt64 uncompressed_len
Definition: chm.h:162
UInt32 block_count
Definition: chm.h:159
UInt64 block_len
Definition: chm.h:164

Referenced by chmc_section_create().

◆ chmc_section_add()

int chmc_section_add ( struct chmcFile chm,
const char name 
)

Definition at line 245 of file chmc.c.

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}
struct chmcSection * chmc_section_create(struct chmcFile *chm, const char *name)
Definition: chmc.c:262
int chmcerr_code(void)
Definition: err.c:42

Referenced by chmc_init().

◆ chmc_section_create()

struct chmcSection * chmc_section_create ( struct chmcFile chm,
const char name 
)

Definition at line 262 of file chmc.c.

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}
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
#define PATH_MAX
Definition: types.h:280
void chmc_reset_table_init(struct chmcLzxcResetTable *reset_table)
Definition: chmc.c:326
void chmc_control_data_init(struct chmcLzxcControlData *control_data)
Definition: chmc.c:337
int mkstemps(char *template, int suffix_len)
Definition: mkstemps.c:73
#define calloc
Definition: rosglue.h:14
#define chmcerr_msg(fmt,...)
Definition: err.h:59
static char tmpdir[MAX_PATH]
Definition: shlexec.c:52

Referenced by chmc_section_add().

◆ chmc_section_destroy()

void chmc_section_destroy ( struct chmcSection section)

Definition at line 493 of file chmc.c.

494{
496 assert(section->fd > -1);
497
498 if (strcmp(section->name, "MSCompressed") == 0) {
499 struct list_head *pos, *q;
500 struct chmcResetTableMark *mark;
501
502 list_for_each_safe(pos, q, &section->mark_list) {
503 mark = list_entry(pos, struct chmcResetTableMark, list);
504 list_del(pos);
505 free(mark);
506 }
507 }
508
509 close(section->fd);
510 unlink(section->filename);
511 free(section);
512}
#define unlink
Definition: syshdrs.h:54

Referenced by chmc_sections_free().

◆ chmc_section_lookup()

struct chmcSection * chmc_section_lookup ( struct chmcFile chm,
int  id 
)

Definition at line 1368 of file chmc.c.

1369{
1370 struct chmcSection *current;
1371 struct list_head *pos;
1372 int i;
1373
1374 assert(chm);
1375
1376 i = 0;
1379 if (i == id)
1380 return current;
1381 i++;
1382 }
1383
1384 return NULL;
1385}
struct task_struct * current
Definition: linux.c:32

Referenced by chmc_pmgl_add_entry().

◆ chmc_sections_done()

void chmc_sections_done ( struct chmcFile chm)

Definition at line 348 of file chmc.c.

349{
350 int len;
351 int i;
352
353 assert(chm);
354
355 chm->sections = malloc(sizeof(struct chmcSection *) * chm->sections_num);
356 if (chm->sections) {
357 struct chmcSection *section;
358 struct list_head *pos;
359
360 i = 0;
361 len = 4;
364 len += 4 + strlen(section->name) * 2;
365 chm->sections[i++] = section;
366 }
368 } else
369 BUG_ON("FIXME: %s: %d\n", __FILE__, __LINE__);
370}
int chmc_namelist_create(struct chmcFile *chm, int len)
Definition: chmc.c:372

Referenced by chmc_init().

◆ chmc_sections_free()

void chmc_sections_free ( struct chmcFile chm)

Definition at line 479 of file chmc.c.

480{
481 struct chmcSection *section;
482 struct list_head *pos, *q;
483
484 assert(chm);
485
488 list_del(pos);
490 }
491}
void chmc_section_destroy(struct chmcSection *section)
Definition: chmc.c:493

Referenced by chmc_term().

◆ chmc_string_init()

void chmc_string_init ( struct chmcStringChunk node)

◆ chmc_strings_add()

UInt32 chmc_strings_add ( struct chmcFile chm,
const char s 
)

Definition at line 558 of file chmc.c.

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}
GLdouble s
Definition: gl.h:2039

Referenced by chmc_tree_done().

◆ chmc_syscat_entry()

static void * chmc_syscat_entry ( Int16  code,
void d,
void s,
Int16  len 
)
static

Definition at line 635 of file chmc.c.

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}
static void * chmc_syscat_mem(void *d, void *s, unsigned long len)
Definition: chmc.c:628
#define d
Definition: ke_i.h:81
Definition: inflate.c:139

Referenced by chmc_system_done().

◆ chmc_syscat_mem()

static void * chmc_syscat_mem ( void d,
void s,
unsigned long  len 
)
inlinestatic

Definition at line 628 of file chmc.c.

629{
630 memcpy(d, s, len);
631
632 return (char *)d + len;
633}

Referenced by chmc_syscat_entry(), and chmc_system_done().

◆ chmc_system_done()

int chmc_system_done ( struct chmcFile chm)

Definition at line 647 of file chmc.c.

648{
649 struct chmcSystem *system;
650 struct chmcSystemInfo *sysinfo;
651 struct chmcIndexHeader *idxhdr;
652 void *sysp, *p;
653
654 assert(chm);
655
656 system = &chm->system;
657 sysinfo = &system->info;
658 idxhdr = &chm->idxhdr;
659
660 // TODO should be set from application
661 // system->_size += (_CHMC_SYS_ENTRY_HDR_LEN + sizeof(UInt32)) /* timestamp */
662 // + (_CHMC_SYS_ENTRY_HDR_LEN + sizeof(PACKAGE_STRING)) /* compiler */
663 // + (_CHMC_SYS_ENTRY_HDR_LEN + sizeof(UInt32)) /* eof */
664 // + (_CHMC_SYS_ENTRY_HDR_LEN + sizeof(DEFAULT_TOPIC))
665 // + (_CHMC_SYS_ENTRY_HDR_LEN + sizeof(TITLE))
666 // + 32;
667
668 sysp = malloc(16384);
669 if (sysp) {
670 UInt32 val;
671#ifndef __REACTOS__
672 UInt16 code, len;
673#endif
674 const char *entry_val;
675
676 p = chmc_syscat_mem(sysp, &system->version, sizeof(system->version));
677
678 val = 0;
679 p = chmc_syscat_entry(SIEC_TIMESTAMP, p, &val, sizeof(val));
681 /*"HHA Version 4.74.8702"*/
683 sizeof(PACKAGE_STRING)
684 /*strlen("HHA Version 4.74.8702")+1*/);
686 sysinfo, sizeof(struct chmcSystemInfo));
687
688 if (chm->config != NULL && chm->config->deftopic != NULL)
689 entry_val = chm->config->deftopic;
690 else
691 entry_val = "index.htm";
692 p = chmc_syscat_entry(SIEC_DEFTOPIC, p, (void *)entry_val,
693 strlen(entry_val)+1);
694
695 if (chm->config != NULL && chm->config->title != NULL)
696 entry_val = chm->config->title;
697 else
698 entry_val = "untitled";
699 p = chmc_syscat_entry(SIEC_TITLE, p, (void *)entry_val,
700 strlen(entry_val)+1);
701 // p = chmc_syscat_entry(SIEC_DEFFONT, p, &val, sizeof(val));
702 p = chmc_syscat_entry(SIEC_LCASEFILE, p, "siec_lcasefile",
703 strlen("siec_lcasefile")+1);
705 "MsdnHelp", strlen("MsdnHelp")+1);
706
707 val = 0;
709
711 idxhdr, sizeof(struct chmcIndexHeader));
712
713
714 val = 0;
716
717 system->_size = (char *)p - (char *)sysp;
718 chmc_add_meta(chm, "/#SYSTEM", 0, sysp, system->_size);
719 return CHMC_NOERR;
720 }
721
722 chmcerr_set(CHMC_ENOMEM, "system done: malloc %d bytes",
723 system->_size);
724
725 return CHMC_ENOMEM;
726}
#define PACKAGE_STRING
Definition: chmc.c:49
static void * chmc_syscat_entry(Int16 code, void *d, void *s, Int16 len)
Definition: chmc.c:635
#define SIEC_LCASEFILE
Definition: chmc.h:68
#define SIEC_NUMOFINFOT
Definition: chmc.h:75
#define SIEC_INFOCHKSUM
Definition: chmc.h:80
#define SIEC_SYSINFO
Definition: chmc.h:85
#define SIEC_DEFTOPIC
Definition: chmc.h:66
#define SIEC_TITLE
Definition: chmc.h:67
#define SIEC_IDXHDR
Definition: chmc.h:78
#define SIEC_DEFWINDOW
Definition: chmc.h:69
#define SIEC_COMPVER
Definition: chmc.h:84
#define SIEC_TIMESTAMP
Definition: chmc.h:83
GLuint GLfloat * val
Definition: glext.h:7180

Referenced by chmc_tree_done().

◆ chmc_term()

void chmc_term ( struct chmcFile chm)

Definition at line 461 of file chmc.c.

462{
463 assert(chm);
464 assert(chm->fd > -1);
465
466 free(chm->strings);
467
469 chmc_pmgl_free(chm);
470 chmc_pmgi_free(chm);
471 if (chm->sections)
472 free(chm->sections);
474
475 if (chm->fd != fileno(stdout))
476 close(chm->fd);
477}
void chmc_pmgl_free(struct chmcFile *chm)
Definition: chmc.c:528
void chmc_sections_free(struct chmcFile *chm)
Definition: chmc.c:479
void chmc_entries_free(struct chmcFile *chm)
Definition: chmc.c:542
void chmc_pmgi_free(struct chmcFile *chm)
Definition: chmc.c:514

Referenced by main().

◆ chmc_tree_done()

int chmc_tree_done ( struct chmcFile chm)

Definition at line 728 of file chmc.c.

729{
730 struct chmcItsfHeader *itsf;
731 struct chmcSect0 *sect0;
732 struct chmcItspHeader *itsp;
733 struct chmcTreeNode *ctrl;
734 UInt32 str_index;
735 const char *val;
736
737 assert(chm);
738
739 itsf = &chm->itsf;
740 sect0 = &chm->sect0;
741 itsp = &chm->itsp;
742
743 chmc_add_dir(chm, "/");
744
745 ctrl = chmc_add_meta(chm, "::DataSpace/Storage/MSCompressed/Transform/List",
747 sizeof(chmc_transform_list));
748 if (ctrl)
749 ctrl->flags |= CHMC_TNFL_STATIC;
750
751 chmc_system_done(chm);
752
753 if (chm->config != NULL && chm->config->deftopic != NULL)
754 val = chm->config->deftopic;
755 else
756 val = "index.htm";
757
758 str_index = chmc_strings_add(chm, val);
759
760#if 0
761 // FIXME just a test
762 {
763 UChar *p;
764 int len;
765 struct chmcTopicEntry topicEntry;
766 // struct chmcUrlStrEntry urlStrEntry;
767
768 p = malloc(4096);
769 if (p) {
770 memset(p, 0, 4096);
771 len = 0;
772
773 topicEntry.tocidx_offset = 4096;
774 topicEntry.strings_offset = -1;
775 topicEntry.urltbl_offset = 0;
776 topicEntry.in_content = 6;
777 topicEntry.unknown = 0;
778
779 memcpy(p, &topicEntry, sizeof(struct chmcTopicEntry));
780 len += sizeof(struct chmcTopicEntry);
781
782 chm->idxhdr.num_of_topic++;
783
784 chmc_add_meta(chm, "/#TOPICS", 1, (UChar *)p, len);
785 } else
786 BUG_ON("FIXME: %s: %d\n", __FILE__, __LINE__);
787 }
788#endif
789
790 ctrl = chmc_add_meta(chm, "/#IDXHDR", 1, (void *)&chm->idxhdr,
791 sizeof(struct chmcIndexHeader));
792 if (ctrl)
793 ctrl->flags |= CHMC_TNFL_STATIC;
794
795 {
796 UInt32 *p;
797 p = malloc(8+196);
798 if (p) {
799 const char *val;
800 memset(p+2, 0, 196);
801
802 p[0] = 1;
803 p[1] = 196;
804
805 p[2+0] = 196;
806 // p[2+2] = 1;
807 // p[2+3] = 0x00000532;
808 // p[2+4] = 0x00062520;
809
810 // p[2+8] = 86;
811 // p[2+9] = 51;
812 // p[2+10] = 872;
813 // p[2+11] = 558;
814
815 // p[2+19] = 220;
816
817 // p[2+27] = 0x00000041;
818 // p[2+28] = 14462;
819
820 if (chm->config != NULL && chm->config->title != NULL)
821 val = chm->config->title;
822 else
823 val = "untitled";
824 p[2+5] = chmc_strings_add(chm, val);
825
826 if (chm->config != NULL && chm->config->hhc != NULL)
827 val = chm->config->hhc;
828 else
829 val = "toc.hhc";
830 p[2+24] = chmc_strings_add(chm, val);
831
832 if (chm->config != NULL && chm->config->hhk != NULL)
833 val = chm->config->hhc;
834 else
835 val = "toc.hhk";
836 p[2+25] = chmc_strings_add(chm, val);
837 p[2+26] = str_index;
838
839 chmc_add_meta(chm, "/#WINDOWS", 1, (UChar *)p, 8+196);
840 } else
841 BUG_ON("FIXME: %s: %d\n", __FILE__, __LINE__);
842 }
843
844 ctrl = chmc_add_meta(chm, "/#STRINGS", 1, (void *)chm->strings,
845 chm->strings_len);
846 if (ctrl)
847 ctrl->flags |= CHMC_TNFL_STATIC;
848
849#if 0
850 // FIXME just a test
851 {
852 UChar *p;
853 int len;
854 struct chmcUrlStrEntry urlStrEntry;
855
856 urlStrEntry.url_offset = 0;
857 urlStrEntry.framename_offset = 0;
858
859 p = malloc(4096);
860 if (p) {
861 memset(p, 0, 4096);
862 *p = 0x42;
863 len = 1;
864
865 memcpy(p + len, &urlStrEntry, sizeof(struct chmcUrlStrEntry));
866 len += sizeof(struct chmcUrlStrEntry);
867 len += sprintf(p + len, "index.htm" ) + 1;
868
869 memcpy(p + len, &urlStrEntry, sizeof(struct chmcUrlStrEntry));
870 len += sizeof(struct chmcUrlStrEntry);
871 len += sprintf(p + len, "test.htm" ) + 1;
872
873 chmc_add_meta(chm, "/#URLSTR", 1, (UChar *)p, len);
874 } else
875 BUG_ON("FIXME: %s: %d\n", __FILE__, __LINE__);
876 }
877#endif
878
879 // chmc_add_entry(chm, "/#URLTBL", 0, 1, NULL, 0, 0);
880 // chmc_add_entry(chm, "/#TOPICS", 0, 1, NULL, 0, 0);
881
882 // NOTE NOTE NOTE add any meta compressed before crunch ;-)
883
884 chmc_crunch_lzx(chm, 1);
885
888
889 chmc_add_empty(chm, "/#ITBITS");
890
891 // NOTE in this implementation compressed Content should be the last file
892 // added to section 0
893
894 chmc_add_meta(chm, "::DataSpace/Storage/MSCompressed/Content", 0, NULL,
895 chm->sections[1]->offset);
896
899 chmc_pmgl_done(chm);
900
901 chmc_pmgi_done(chm);
902
904 + (_CHMC_CHUNK_LEN * itsp->num_blocks);
905
909 + (_CHMC_CHUNK_LEN * itsp->num_blocks);
910
911 sect0->file_len += _CHMC_CHUNK_LEN * itsp->num_blocks;
912
913 chmc_write(chm);
914
915 {
916 struct chmcSection *section;
917 struct list_head *pos;
918 UChar buf[4096];
919
922 chmc_appendfile(chm, section->filename, buf, 4096);
923 }
924 }
925
926 return CHMC_NOERR;
927}
int chmc_appendfile(struct chmcFile *chm, const char *filename, void *buf, size_t size)
Definition: chmc.c:1662
int chmc_write(struct chmcFile *chm)
Definition: chmc.c:1625
int chmc_crunch_lzx(struct chmcFile *chm, int sect_id)
Definition: chmc.c:929
int chmc_reset_table_done(struct chmcFile *chm)
Definition: chmc.c:1161
struct chmcTreeNode * chmc_add_empty(struct chmcFile *chm, const char *file)
Definition: chmc.c:401
int chmc_uncompressed_done(struct chmcFile *chm)
Definition: chmc.c:1240
static const short chmc_transform_list[]
Definition: chmc.c:128
void chmc_entries_qsort(struct chmcFile *chm)
Definition: chmc.c:1210
int chmc_pmgi_done(struct chmcFile *chm)
Definition: chmc.c:1492
int chmc_control_data_done(struct chmcFile *chm)
Definition: chmc.c:1145
int chmc_system_done(struct chmcFile *chm)
Definition: chmc.c:647
UInt32 chmc_strings_add(struct chmcFile *chm, const char *s)
Definition: chmc.c:558
void chmc_pmgl_done(struct chmcFile *chm)
Definition: chmc.c:1262
#define sprintf(buf, format,...)
Definition: sprintf.c:55
UInt64 data_offset
Definition: chm.h:103
UInt64 dir_len
Definition: chm.h:102
UInt32 url_offset
Definition: chmc.h:238

Referenced by main().

◆ chmc_uncompressed_done()

int chmc_uncompressed_done ( struct chmcFile chm)

Definition at line 1240 of file chmc.c.

1241{
1242 struct chmcSect0 *sect0 = &chm->sect0;
1243 struct chmcTreeNode *node;
1244 struct list_head *pos;
1245 int wx;
1246
1248 node = list_entry( pos, struct chmcTreeNode, list );
1249
1250 if (strcmp( "MSCompressed", chm->sections[node->sect_id]->name ) == 0)
1251 continue;
1252
1253 if ((node->buf) && (node->len > 0)) {
1254 wx = write(chm->sections[node->sect_id]->fd, node->buf, node->len);
1255 sect0->file_len += wx;
1256 }
1257 }
1258
1259 return CHMC_NOERR;
1260}

Referenced by chmc_tree_done().

◆ chmc_write()

int chmc_write ( struct chmcFile chm)

Definition at line 1625 of file chmc.c.

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}
struct chmcPmgiChunk chunk
Definition: chmc.h:161

Referenced by chmc_tree_done().

Variable Documentation

◆ chmc_transform_list

const short chmc_transform_list[]
static
Initial value:
= {
0x7b, 0x37, 0x46, 0x43, 0x32, 0x38, 0x39,
0x34, 0x30, 0x2d, 0x39, 0x44, 0x33, 0x31,
0x2d, 0x31, 0x31, 0x44, 0x30 }

Definition at line 128 of file chmc.c.

Referenced by chmc_tree_done().