...
|
...
|
@@ -1,7 +1,7 @@
|
1
|
1
|
/*
|
2
|
2
|
* Extract component parts of MS CHM files
|
3
|
3
|
*
|
4
|
|
- * Copyright (C) 2004-2005 trog@uncon.org
|
|
4
|
+ * Copyright (C) 2004-2007 trog@uncon.org
|
5
|
5
|
*
|
6
|
6
|
* This program is free software; you can redistribute it and/or modify
|
7
|
7
|
* it under the terms of the GNU General Public License as published by
|
...
|
...
|
@@ -68,14 +68,14 @@
|
68
|
68
|
#define CHM_ITSF_MIN_LEN (0x60)
|
69
|
69
|
typedef struct itsf_header_tag
|
70
|
70
|
{
|
71
|
|
- unsigned char signature[4] __attribute__ ((packed));
|
|
71
|
+ unsigned char signature[4];
|
72
|
72
|
int32_t version __attribute__ ((packed));
|
73
|
73
|
int32_t header_len __attribute__ ((packed));
|
74
|
74
|
uint32_t unknown __attribute__ ((packed));
|
75
|
75
|
uint32_t last_modified __attribute__ ((packed));
|
76
|
76
|
uint32_t lang_id __attribute__ ((packed));
|
77
|
|
- unsigned char dir_clsid[16] __attribute__ ((packed));
|
78
|
|
- unsigned char stream_clsid[16] __attribute__ ((packed));
|
|
77
|
+ unsigned char dir_clsid[16];
|
|
78
|
+ unsigned char stream_clsid[16];
|
79
|
79
|
uint64_t sec0_offset __attribute__ ((packed));
|
80
|
80
|
uint64_t sec0_len __attribute__ ((packed));
|
81
|
81
|
uint64_t dir_offset __attribute__ ((packed));
|
...
|
...
|
@@ -86,7 +86,7 @@ typedef struct itsf_header_tag
|
86
|
86
|
#define CHM_ITSP_LEN (0x54)
|
87
|
87
|
typedef struct itsp_header_tag
|
88
|
88
|
{
|
89
|
|
- unsigned char signature[4] __attribute__ ((packed));
|
|
89
|
+ unsigned char signature[4];
|
90
|
90
|
int32_t version __attribute__ ((packed));
|
91
|
91
|
int32_t header_len __attribute__ ((packed));
|
92
|
92
|
int32_t unknown1 __attribute__ ((packed));
|
...
|
...
|
@@ -99,25 +99,24 @@ typedef struct itsp_header_tag
|
99
|
99
|
int32_t unknown2 __attribute__ ((packed));
|
100
|
100
|
uint32_t num_blocks __attribute__ ((packed));
|
101
|
101
|
uint32_t lang_id __attribute__ ((packed));
|
102
|
|
- unsigned char system_clsid[16] __attribute__ ((packed));
|
103
|
|
- unsigned char unknown4[16] __attribute__ ((packed));
|
|
102
|
+ unsigned char system_clsid[16];
|
|
103
|
+ unsigned char unknown4[16];
|
104
|
104
|
} itsp_header_t;
|
105
|
105
|
|
106
|
106
|
#define CHM_CHUNK_HDR_LEN (0x14)
|
107
|
107
|
typedef struct chunk_header_tag
|
108
|
108
|
{
|
109
|
|
- unsigned char signature[4] __attribute__ ((packed));
|
|
109
|
+ char signature[4];
|
110
|
110
|
uint32_t free_space __attribute__ ((packed));
|
111
|
111
|
uint32_t unknown __attribute__ ((packed));
|
112
|
112
|
int32_t block_prev __attribute__ ((packed));
|
113
|
113
|
int32_t block_next __attribute__ ((packed));
|
114
|
|
- unsigned char *chunk_data;
|
|
114
|
+ char *chunk_data;
|
115
|
115
|
uint16_t num_entries;
|
116
|
116
|
} chunk_header_t;
|
117
|
117
|
|
118
|
118
|
typedef struct file_list_tag
|
119
|
119
|
{
|
120
|
|
- unsigned char *name;
|
121
|
120
|
uint64_t section;
|
122
|
121
|
uint64_t offset;
|
123
|
122
|
uint64_t length;
|
...
|
...
|
@@ -127,7 +126,7 @@ typedef struct file_list_tag
|
127
|
127
|
#define CHM_CONTROL_LEN (0x18)
|
128
|
128
|
typedef struct lzx_control_tag {
|
129
|
129
|
uint32_t length __attribute__ ((packed));
|
130
|
|
- unsigned char signature[4] __attribute__ ((packed));
|
|
130
|
+ unsigned char signature[4];
|
131
|
131
|
uint32_t version __attribute__ ((packed));
|
132
|
132
|
uint32_t reset_interval __attribute__ ((packed));
|
133
|
133
|
uint32_t window_size __attribute__ ((packed));
|
...
|
...
|
@@ -159,13 +158,21 @@ typedef struct lzx_content_tag {
|
159
|
159
|
#pragma pack
|
160
|
160
|
#endif
|
161
|
161
|
|
|
162
|
+#define CHM_SYS_CONTROL_NAME "::DataSpace/Storage/MSCompressed/ControlData"
|
|
163
|
+#define CHM_SYS_CONTENT_NAME "::DataSpace/Storage/MSCompressed/Content"
|
|
164
|
+#define CHM_SYS_RESETTABLE_NAME "::DataSpace/Storage/MSCompressed/Transform/{7FC28940-9D31-11D0-9B27-00A0C91E9C7C}/InstanceData/ResetTable"
|
|
165
|
+
|
|
166
|
+#define CHM_SYS_CONTROL_LEN 44
|
|
167
|
+#define CHM_SYS_CONTENT_LEN 40
|
|
168
|
+#define CHM_SYS_RESETTABLE_LEN 105
|
|
169
|
+
|
162
|
170
|
#define chm_endian_convert_16(x) le16_to_host(x)
|
163
|
171
|
#define chm_endian_convert_32(x) le32_to_host(x)
|
164
|
172
|
#define chm_endian_convert_64(x) le64_to_host(x)
|
165
|
173
|
|
166
|
174
|
/* Read in a block of data from either the mmap area or the given fd */
|
167
|
|
-static int chm_read_data(int fd, unsigned char *dest, off_t offset, off_t len,
|
168
|
|
- unsigned char *m_area, off_t m_length)
|
|
175
|
+static int chm_read_data(int fd, char *dest, off_t offset, off_t len,
|
|
176
|
+ char *m_area, off_t m_length)
|
169
|
177
|
{
|
170
|
178
|
if ((offset < 0) || (len < 0) || ((offset+len) < 0)) {
|
171
|
179
|
return FALSE;
|
...
|
...
|
@@ -214,9 +221,6 @@ static void free_file_list(file_list_t *file_l)
|
214
|
214
|
|
215
|
215
|
while (file_l) {
|
216
|
216
|
next = file_l->next;
|
217
|
|
- if (file_l->name) {
|
218
|
|
- free(file_l->name);
|
219
|
|
- }
|
220
|
217
|
free(file_l);
|
221
|
218
|
file_l = next;
|
222
|
219
|
}
|
...
|
...
|
@@ -232,7 +236,7 @@ static void itsf_print_header(itsf_header_t *itsf_hdr)
|
232
|
232
|
cli_dbgmsg("Signature:\t%c%c%c%c\n", itsf_hdr->signature[0],
|
233
|
233
|
itsf_hdr->signature[1],itsf_hdr->signature[2],itsf_hdr->signature[3]);
|
234
|
234
|
cli_dbgmsg("Version:\t%d\n", itsf_hdr->version);
|
235
|
|
- cli_dbgmsg("Header len:\t%ld\n", itsf_hdr->header_len);
|
|
235
|
+ cli_dbgmsg("Header len:\t%d\n", itsf_hdr->header_len);
|
236
|
236
|
cli_dbgmsg("Lang ID:\t%d\n", itsf_hdr->lang_id);
|
237
|
237
|
cli_dbgmsg("Sec0 offset:\t%llu\n", itsf_hdr->sec0_offset);
|
238
|
238
|
cli_dbgmsg("Sec0 len:\t%llu\n", itsf_hdr->sec0_len);
|
...
|
...
|
@@ -243,10 +247,10 @@ static void itsf_print_header(itsf_header_t *itsf_hdr)
|
243
|
243
|
}
|
244
|
244
|
}
|
245
|
245
|
|
246
|
|
-static int itsf_read_header(int fd, itsf_header_t *itsf_hdr, unsigned char *m_area, off_t m_length)
|
|
246
|
+static int itsf_read_header(int fd, itsf_header_t *itsf_hdr, char *m_area, off_t m_length)
|
247
|
247
|
{
|
248
|
248
|
#if defined(HAVE_ATTRIB_PACKED) || defined(HAVE_PRAGMA_PACK) || defined(HAVE_PRAGMA_PACK_HPPA)
|
249
|
|
- if (!chm_read_data(fd, (unsigned char *) itsf_hdr, 0, CHM_ITSF_MIN_LEN,
|
|
249
|
+ if (!chm_read_data(fd, (char *) itsf_hdr, 0, CHM_ITSF_MIN_LEN,
|
250
|
250
|
m_area, m_length)) {
|
251
|
251
|
return FALSE;
|
252
|
252
|
}
|
...
|
...
|
@@ -321,21 +325,21 @@ static void itsp_print_header(itsp_header_t *itsp_hdr)
|
321
|
321
|
cli_dbgmsg("Signature:\t%c%c%c%c\n", itsp_hdr->signature[0],
|
322
|
322
|
itsp_hdr->signature[1],itsp_hdr->signature[2],itsp_hdr->signature[3]);
|
323
|
323
|
cli_dbgmsg("Version:\t%d\n", itsp_hdr->version);
|
324
|
|
- cli_dbgmsg("Block len:\t%ld\n", itsp_hdr->block_len);
|
|
324
|
+ cli_dbgmsg("Block len:\t%u\n", itsp_hdr->block_len);
|
325
|
325
|
cli_dbgmsg("Block idx int:\t%d\n", itsp_hdr->blockidx_intvl);
|
326
|
326
|
cli_dbgmsg("Index depth:\t%d\n", itsp_hdr->index_depth);
|
327
|
327
|
cli_dbgmsg("Index root:\t%d\n", itsp_hdr->index_root);
|
328
|
328
|
cli_dbgmsg("Index head:\t%u\n", itsp_hdr->index_head);
|
329
|
329
|
cli_dbgmsg("Index tail:\t%u\n", itsp_hdr->index_tail);
|
330
|
330
|
cli_dbgmsg("Num Blocks:\t%u\n", itsp_hdr->num_blocks);
|
331
|
|
- cli_dbgmsg("Lang ID:\t%lu\n\n", itsp_hdr->lang_id);
|
|
331
|
+ cli_dbgmsg("Lang ID:\t%u\n\n", itsp_hdr->lang_id);
|
332
|
332
|
}
|
333
|
333
|
|
334
|
334
|
static int itsp_read_header(int fd, itsp_header_t *itsp_hdr, off_t offset,
|
335
|
|
- unsigned char *m_area, off_t m_length)
|
|
335
|
+ char *m_area, off_t m_length)
|
336
|
336
|
{
|
337
|
337
|
#if defined(HAVE_ATTRIB_PACKED) || defined(HAVE_PRAGMA_PACK) || defined(HAVE_PRAGMA_PACK_HPPA)
|
338
|
|
- if (!chm_read_data(fd, (unsigned char *) itsp_hdr, offset, CHM_ITSP_LEN,
|
|
338
|
+ if (!chm_read_data(fd, (char *) itsp_hdr, offset, CHM_ITSP_LEN,
|
339
|
339
|
m_area, m_length)) {
|
340
|
340
|
return FALSE;
|
341
|
341
|
}
|
...
|
...
|
@@ -412,10 +416,10 @@ static int itsp_read_header(int fd, itsp_header_t *itsp_hdr, off_t offset,
|
412
|
412
|
return TRUE;
|
413
|
413
|
}
|
414
|
414
|
|
415
|
|
-static uint64_t read_enc_int(unsigned char **start, unsigned char *end)
|
|
415
|
+static uint64_t read_enc_int(char **start, char *end)
|
416
|
416
|
{
|
417
|
417
|
uint64_t retval=0;
|
418
|
|
- unsigned char *current;
|
|
418
|
+ char *current;
|
419
|
419
|
|
420
|
420
|
current = *start;
|
421
|
421
|
|
...
|
...
|
@@ -436,11 +440,11 @@ static uint64_t read_enc_int(unsigned char **start, unsigned char *end)
|
436
|
436
|
|
437
|
437
|
/* Read chunk entries */
|
438
|
438
|
/* Note: the file lists end up in reverse order to the order in the chunk */
|
439
|
|
-static int read_chunk_entries(unsigned char *chunk, uint32_t chunk_len,
|
|
439
|
+static int read_chunk_entries(char *chunk, uint32_t chunk_len,
|
440
|
440
|
uint16_t num_entries,
|
441
|
441
|
file_list_t *file_l, file_list_t *sys_file_l)
|
442
|
442
|
{
|
443
|
|
- unsigned char *current, *end;
|
|
443
|
+ char *current, *end;
|
444
|
444
|
uint64_t name_len;
|
445
|
445
|
file_list_t *file_e;
|
446
|
446
|
|
...
|
...
|
@@ -453,49 +457,44 @@ static int read_chunk_entries(unsigned char *chunk, uint32_t chunk_len,
|
453
|
453
|
return FALSE;
|
454
|
454
|
}
|
455
|
455
|
|
456
|
|
- file_e = (file_list_t *) cli_malloc(sizeof(file_list_t));
|
457
|
|
- if (!file_e) {
|
458
|
|
- return FALSE;
|
459
|
|
- }
|
460
|
|
- file_e->next = NULL;
|
461
|
|
-
|
462
|
456
|
name_len = read_enc_int(¤t, end);
|
463
|
457
|
if (((current + name_len) > end) || ((current + name_len) < chunk)) {
|
464
|
458
|
cli_dbgmsg("Bad CHM name_len detected\n");
|
465
|
|
- free(file_e);
|
466
|
459
|
return FALSE;
|
467
|
460
|
}
|
468
|
|
- if (name_len > 0xFFFFFF) {
|
469
|
|
- cli_dbgmsg("CHM file name too long: %llu\n", name_len);
|
470
|
|
- file_e->name = (unsigned char *) cli_strdup("truncated");
|
471
|
|
- if (!file_e->name) {
|
472
|
|
- free(file_e);
|
473
|
|
- return FALSE;
|
474
|
|
- }
|
|
461
|
+ if ((name_len >= 2) && (current[0] == ':') &&
|
|
462
|
+ (current[1] == ':')) {
|
|
463
|
+ if ((name_len == CHM_SYS_CONTROL_LEN) && (strcmp(current, CHM_SYS_CONTROL_NAME) == 0)) {
|
|
464
|
+ current += name_len;
|
|
465
|
+ sys_file_l[0].section = read_enc_int(¤t, end);
|
|
466
|
+ sys_file_l[0].offset = read_enc_int(¤t, end);
|
|
467
|
+ sys_file_l[0].length = read_enc_int(¤t, end);
|
|
468
|
+ } else if ((name_len == CHM_SYS_CONTENT_LEN) && (strcmp(current, CHM_SYS_CONTENT_NAME) == 0)) {
|
|
469
|
+ current += name_len;
|
|
470
|
+ sys_file_l[1].section = read_enc_int(¤t, end);
|
|
471
|
+ sys_file_l[1].offset = read_enc_int(¤t, end);
|
|
472
|
+ sys_file_l[1].length = read_enc_int(¤t, end);
|
|
473
|
+ } else if ((name_len == CHM_SYS_RESETTABLE_LEN) && (strcmp(current, CHM_SYS_RESETTABLE_NAME) == 0)) {
|
|
474
|
+ current += name_len;
|
|
475
|
+ sys_file_l[2].section = read_enc_int(¤t, end);
|
|
476
|
+ sys_file_l[2].offset = read_enc_int(¤t, end);
|
|
477
|
+ sys_file_l[2].length = read_enc_int(¤t, end);
|
|
478
|
+ }
|
475
|
479
|
} else {
|
476
|
|
- file_e->name = (unsigned char *) cli_malloc(name_len+1);
|
477
|
|
- if (!file_e->name) {
|
478
|
|
- free(file_e);
|
|
480
|
+ current += name_len;
|
|
481
|
+ file_e = (file_list_t *) cli_malloc(sizeof(file_list_t));
|
|
482
|
+ if (!file_e) {
|
479
|
483
|
return FALSE;
|
480
|
484
|
}
|
481
|
|
- strncpy(file_e->name, current, name_len);
|
482
|
|
- file_e->name[name_len] = '\0';
|
483
|
|
- }
|
484
|
|
- current += name_len;
|
485
|
|
- file_e->section = read_enc_int(¤t, end);
|
486
|
|
- file_e->offset = read_enc_int(¤t, end);
|
487
|
|
- file_e->length = read_enc_int(¤t, end);
|
488
|
|
- if ((name_len >= 2) && (file_e->name[0] == ':') &&
|
489
|
|
- (file_e->name[1] == ':')) {
|
490
|
|
- file_e->next = sys_file_l->next;
|
491
|
|
- sys_file_l->next = file_e;
|
492
|
|
- } else {
|
|
485
|
+ file_e->section = read_enc_int(¤t, end);
|
|
486
|
+ file_e->offset = read_enc_int(¤t, end);
|
|
487
|
+ file_e->length = read_enc_int(¤t, end);
|
493
|
488
|
file_e->next = file_l->next;
|
494
|
489
|
file_l->next = file_e;
|
495
|
|
- }
|
496
|
|
- cli_dbgmsg("Section: %llu Offset: %llu Length: %llu, Name: %s\n",
|
|
490
|
+ cli_dbgmsg("Section: %llu Offset: %llu Length: %llu\n",
|
497
|
491
|
file_e->section, file_e->offset,
|
498
|
|
- file_e->length, file_e->name);
|
|
492
|
+ file_e->length);
|
|
493
|
+ }
|
499
|
494
|
}
|
500
|
495
|
return TRUE;
|
501
|
496
|
}
|
...
|
...
|
@@ -516,7 +515,7 @@ static void print_chunk(chunk_header_t *chunk)
|
516
|
516
|
}
|
517
|
517
|
|
518
|
518
|
static int read_chunk(int fd, off_t offset, uint32_t chunk_len,
|
519
|
|
- unsigned char *m_area, off_t m_length,
|
|
519
|
+ char *m_area, off_t m_length,
|
520
|
520
|
file_list_t *file_l, file_list_t *sys_file_l)
|
521
|
521
|
{
|
522
|
522
|
chunk_header_t *chunk_hdr;
|
...
|
...
|
@@ -531,7 +530,7 @@ static int read_chunk(int fd, off_t offset, uint32_t chunk_len,
|
531
|
531
|
return FALSE;
|
532
|
532
|
}
|
533
|
533
|
|
534
|
|
- chunk_hdr->chunk_data = (unsigned char *) cli_malloc(chunk_len);
|
|
534
|
+ chunk_hdr->chunk_data = (char *) cli_malloc(chunk_len);
|
535
|
535
|
if (!chunk_hdr->chunk_data) {
|
536
|
536
|
free(chunk_hdr);
|
537
|
537
|
return FALSE;
|
...
|
...
|
@@ -568,7 +567,7 @@ static int read_chunk(int fd, off_t offset, uint32_t chunk_len,
|
568
|
568
|
|
569
|
569
|
if (memcmp(chunk_hdr->signature, "PMGL", 4) == 0) {
|
570
|
570
|
#if defined(HAVE_ATTRIB_PACKED) || defined(HAVE_PRAGMA_PACK) || defined(HAVE_PRAGMA_PACK_HPPA)
|
571
|
|
- if (!chm_read_data(fd, (unsigned char *) &chunk_hdr->unknown, offset+8, 12,
|
|
571
|
+ if (!chm_read_data(fd, (char *) &chunk_hdr->unknown, offset+8, 12,
|
572
|
572
|
m_area, m_length)) {
|
573
|
573
|
goto abort;
|
574
|
574
|
}
|
...
|
...
|
@@ -609,7 +608,7 @@ static void print_sys_control(lzx_control_t *lzx_control)
|
609
|
609
|
}
|
610
|
610
|
|
611
|
611
|
cli_dbgmsg("---- Control ----\n");
|
612
|
|
- cli_dbgmsg("Length:\t\t%lu\n", lzx_control->length);
|
|
612
|
+ cli_dbgmsg("Length:\t\t%u\n", lzx_control->length);
|
613
|
613
|
cli_dbgmsg("Signature:\t%c%c%c%c\n", lzx_control->signature[0],
|
614
|
614
|
lzx_control->signature[1],lzx_control->signature[2],lzx_control->signature[3]);
|
615
|
615
|
cli_dbgmsg("Version:\t%d\n", lzx_control->version);
|
...
|
...
|
@@ -619,7 +618,7 @@ static void print_sys_control(lzx_control_t *lzx_control)
|
619
|
619
|
}
|
620
|
620
|
|
621
|
621
|
static lzx_control_t *read_sys_control(int fd, itsf_header_t *itsf_hdr, file_list_t *file_e,
|
622
|
|
- unsigned char *m_area, off_t m_length)
|
|
622
|
+ char *m_area, off_t m_length)
|
623
|
623
|
{
|
624
|
624
|
off_t offset;
|
625
|
625
|
lzx_control_t *lzx_control;
|
...
|
...
|
@@ -637,7 +636,7 @@ static lzx_control_t *read_sys_control(int fd, itsf_header_t *itsf_hdr, file_lis
|
637
|
637
|
return NULL;
|
638
|
638
|
}
|
639
|
639
|
#if defined(HAVE_ATTRIB_PACKED) || defined(HAVE_PRAGMA_PACK) || defined(HAVE_PRAGMA_PACK_HPPA)
|
640
|
|
- if (!chm_read_data(fd, (unsigned char *) lzx_control, offset, CHM_CONTROL_LEN,
|
|
640
|
+ if (!chm_read_data(fd, (char *) lzx_control, offset, CHM_CONTROL_LEN,
|
641
|
641
|
m_area, m_length)) {
|
642
|
642
|
goto abort;
|
643
|
643
|
}
|
...
|
...
|
@@ -670,7 +669,7 @@ static lzx_control_t *read_sys_control(int fd, itsf_header_t *itsf_hdr, file_lis
|
670
|
670
|
lzx_control->window_size = chm_endian_convert_32(lzx_control->window_size);
|
671
|
671
|
lzx_control->cache_size = chm_endian_convert_32(lzx_control->cache_size);
|
672
|
672
|
|
673
|
|
- if (strncmp("LZXC", lzx_control->signature, 4) != 0) {
|
|
673
|
+ if (strncmp((const char *) "LZXC", (const char *) lzx_control->signature, 4) != 0) {
|
674
|
674
|
cli_dbgmsg("bad sys_control signature");
|
675
|
675
|
goto abort;
|
676
|
676
|
}
|
...
|
...
|
@@ -726,16 +725,16 @@ static void print_sys_reset_table(lzx_reset_table_t *lzx_reset_table)
|
726
|
726
|
}
|
727
|
727
|
|
728
|
728
|
cli_dbgmsg("---- Reset Table ----\n");
|
729
|
|
- cli_dbgmsg("Num Entries:\t%lu\n", lzx_reset_table->num_entries);
|
730
|
|
- cli_dbgmsg("Entry Size:\t%lu\n", lzx_reset_table->entry_size);
|
731
|
|
- cli_dbgmsg("Table Offset:\t%lu\n", lzx_reset_table->table_offset);
|
|
729
|
+ cli_dbgmsg("Num Entries:\t%u\n", lzx_reset_table->num_entries);
|
|
730
|
+ cli_dbgmsg("Entry Size:\t%u\n", lzx_reset_table->entry_size);
|
|
731
|
+ cli_dbgmsg("Table Offset:\t%u\n", lzx_reset_table->table_offset);
|
732
|
732
|
cli_dbgmsg("Uncom Len:\t%llu\n", lzx_reset_table->uncom_len);
|
733
|
733
|
cli_dbgmsg("Com Len:\t%llu\n", lzx_reset_table->com_len);
|
734
|
734
|
cli_dbgmsg("Frame Len:\t%llu\n\n", lzx_reset_table->frame_len);
|
735
|
735
|
}
|
736
|
736
|
|
737
|
737
|
static lzx_reset_table_t *read_sys_reset_table(int fd, itsf_header_t *itsf_hdr, file_list_t *file_e,
|
738
|
|
- unsigned char *m_area, off_t m_length)
|
|
738
|
+ char *m_area, off_t m_length)
|
739
|
739
|
{
|
740
|
740
|
off_t offset;
|
741
|
741
|
lzx_reset_table_t *lzx_reset_table;
|
...
|
...
|
@@ -759,7 +758,7 @@ static lzx_reset_table_t *read_sys_reset_table(int fd, itsf_header_t *itsf_hdr,
|
759
|
759
|
lzx_reset_table->rt_offset = offset-4;
|
760
|
760
|
|
761
|
761
|
#if defined(HAVE_ATTRIB_PACKED) || defined(HAVE_PRAGMA_PACK) || defined(HAVE_PRAGMA_PACK_HPPA)
|
762
|
|
- if (!chm_read_data(fd, (unsigned char *) lzx_reset_table, offset, CHM_RESET_TABLE_LEN,
|
|
762
|
+ if (!chm_read_data(fd, (char *) lzx_reset_table, offset, CHM_RESET_TABLE_LEN,
|
763
|
763
|
m_area, m_length)) {
|
764
|
764
|
goto abort;
|
765
|
765
|
}
|
...
|
...
|
@@ -794,7 +793,7 @@ static lzx_reset_table_t *read_sys_reset_table(int fd, itsf_header_t *itsf_hdr,
|
794
|
794
|
lzx_reset_table->frame_len = chm_endian_convert_64(lzx_reset_table->frame_len);
|
795
|
795
|
|
796
|
796
|
if (lzx_reset_table->frame_len != LZX_FRAME_SIZE) {
|
797
|
|
- cli_dbgmsg("bad sys_reset_table frame_len: 0x%x\n",lzx_reset_table->frame_len);
|
|
797
|
+ cli_dbgmsg("bad sys_reset_table frame_len: 0x%lx\n", (long unsigned int) lzx_reset_table->frame_len);
|
798
|
798
|
goto abort;
|
799
|
799
|
}
|
800
|
800
|
if ((lzx_reset_table->entry_size != 4) && (lzx_reset_table->entry_size != 8)) {
|
...
|
...
|
@@ -812,13 +811,9 @@ abort:
|
812
|
812
|
/* This section interfaces to the mspack files. As such, this is a */
|
813
|
813
|
/* little bit dirty compared to my usual code */
|
814
|
814
|
|
815
|
|
-#define CHM_SYS_CONTROL_NAME "::DataSpace/Storage/MSCompressed/ControlData"
|
816
|
|
-#define CHM_SYS_CONTENT_NAME "::DataSpace/Storage/MSCompressed/Content"
|
817
|
|
-#define CHM_SYS_RESETTABLE_NAME "::DataSpace/Storage/MSCompressed/Transform/{7FC28940-9D31-11D0-9B27-00A0C91E9C7C}/InstanceData/ResetTable"
|
818
|
|
-
|
819
|
815
|
static int chm_decompress_stream(int fd, const char *dirname, itsf_header_t *itsf_hdr,
|
820
|
816
|
file_list_t *file_l, file_list_t *sys_file_l,
|
821
|
|
- unsigned char *m_area, off_t m_length)
|
|
817
|
+ char *m_area, off_t m_length)
|
822
|
818
|
{
|
823
|
819
|
file_list_t *entry;
|
824
|
820
|
lzx_content_t *lzx_content=NULL;
|
...
|
...
|
@@ -827,7 +822,7 @@ static int chm_decompress_stream(int fd, const char *dirname, itsf_header_t *its
|
827
|
827
|
int window_bits, count, length, tmpfd, ofd, retval=FALSE;
|
828
|
828
|
uint64_t com_offset;
|
829
|
829
|
struct lzx_stream * stream;
|
830
|
|
- unsigned char filename[1024];
|
|
830
|
+ char filename[1024];
|
831
|
831
|
|
832
|
832
|
snprintf(filename, 1024, "%s/clamav-unchm.bin", dirname);
|
833
|
833
|
tmpfd = open(filename, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU);
|
...
|
...
|
@@ -836,18 +831,14 @@ static int chm_decompress_stream(int fd, const char *dirname, itsf_header_t *its
|
836
|
836
|
return FALSE;
|
837
|
837
|
}
|
838
|
838
|
|
839
|
|
- entry = sys_file_l->next;
|
840
|
|
- while (entry) {
|
841
|
|
- if (strcmp(entry->name, CHM_SYS_CONTROL_NAME) == 0) {
|
842
|
|
- lzx_control = read_sys_control(fd, itsf_hdr, entry, m_area, m_length);
|
843
|
|
- } else if (strcmp(entry->name, CHM_SYS_CONTENT_NAME) == 0) {
|
844
|
|
- lzx_content = read_sys_content(fd, itsf_hdr, entry);
|
845
|
|
- } else if (strcmp(entry->name, CHM_SYS_RESETTABLE_NAME) == 0) {
|
846
|
|
- lzx_reset_table = read_sys_reset_table(fd, itsf_hdr, entry, m_area, m_length);
|
847
|
|
- }
|
848
|
|
- entry = entry->next;
|
|
839
|
+ if (!sys_file_l[0].length || !sys_file_l[1].length ||!sys_file_l[2].length) {
|
|
840
|
+ goto abort;
|
849
|
841
|
}
|
850
|
|
-
|
|
842
|
+
|
|
843
|
+ lzx_control = read_sys_control(fd, itsf_hdr, &sys_file_l[0], m_area, m_length);
|
|
844
|
+ lzx_content = read_sys_content(fd, itsf_hdr, &sys_file_l[1]);
|
|
845
|
+ lzx_reset_table = read_sys_reset_table(fd, itsf_hdr, &sys_file_l[2], m_area, m_length);
|
|
846
|
+
|
851
|
847
|
if (!lzx_content || !lzx_reset_table || !lzx_control) {
|
852
|
848
|
goto abort;
|
853
|
849
|
}
|
...
|
...
|
@@ -935,7 +926,7 @@ static int chm_decompress_stream(int fd, const char *dirname, itsf_header_t *its
|
935
|
935
|
continue;
|
936
|
936
|
}
|
937
|
937
|
if (chm_copy_file_data(tmpfd, ofd, entry->length) != entry->length) {
|
938
|
|
- cli_dbgmsg("failed to copy %lu bytes\n", entry->length);
|
|
938
|
+ cli_dbgmsg("failed to copy %lu bytes\n", (long unsigned int) entry->length);
|
939
|
939
|
}
|
940
|
940
|
|
941
|
941
|
close(ofd);
|
...
|
...
|
@@ -967,9 +958,9 @@ abort:
|
967
|
967
|
int chm_unpack(int fd, const char *dirname)
|
968
|
968
|
{
|
969
|
969
|
int retval=FALSE;
|
970
|
|
- unsigned char *m_area=NULL;
|
|
970
|
+ char *m_area=NULL;
|
971
|
971
|
off_t m_length=0, offset;
|
972
|
|
- file_list_t *file_l, *sys_file_l;
|
|
972
|
+ file_list_t *file_l, sys_file_l[3];
|
973
|
973
|
struct stat statbuf;
|
974
|
974
|
itsf_header_t itsf_hdr;
|
975
|
975
|
itsp_header_t itsp_hdr;
|
...
|
...
|
@@ -983,14 +974,7 @@ int chm_unpack(int fd, const char *dirname)
|
983
|
983
|
return FALSE;
|
984
|
984
|
}
|
985
|
985
|
file_l->next = NULL;
|
986
|
|
- file_l->name = NULL;
|
987
|
|
- sys_file_l = (file_list_t *) cli_malloc(sizeof(file_list_t));
|
988
|
|
- if (!sys_file_l) {
|
989
|
|
- free(file_l);
|
990
|
|
- return FALSE;
|
991
|
|
- }
|
992
|
|
- sys_file_l->next = NULL;
|
993
|
|
- sys_file_l->name = NULL;
|
|
986
|
+ sys_file_l[0].length = sys_file_l[1].length = sys_file_l[2].length = 0;
|
994
|
987
|
|
995
|
988
|
#ifdef HAVE_MMAP
|
996
|
989
|
if (fstat(fd, &statbuf) == 0) {
|
...
|
...
|
@@ -998,7 +982,7 @@ int chm_unpack(int fd, const char *dirname)
|
998
|
998
|
goto abort;
|
999
|
999
|
}
|
1000
|
1000
|
m_length = statbuf.st_size;
|
1001
|
|
- m_area = (unsigned char *) mmap(NULL, m_length, PROT_READ, MAP_PRIVATE, fd, 0);
|
|
1001
|
+ m_area = (char *) mmap(NULL, m_length, PROT_READ, MAP_PRIVATE, fd, 0);
|
1002
|
1002
|
if (m_area == MAP_FAILED) {
|
1003
|
1003
|
m_area = NULL;
|
1004
|
1004
|
}
|
...
|
...
|
@@ -1048,7 +1032,6 @@ int chm_unpack(int fd, const char *dirname)
|
1048
|
1048
|
retval = TRUE;
|
1049
|
1049
|
abort:
|
1050
|
1050
|
free_file_list(file_l);
|
1051
|
|
- free_file_list(sys_file_l);
|
1052
|
1051
|
|
1053
|
1052
|
#ifdef HAVE_MMAP
|
1054
|
1053
|
if (m_area) {
|