1 /* libmspack -- a library for working with Microsoft compression formats. 2 * (C) 2003-2019 Stuart Caie <kyzer@cabextract.org.uk> 3 * 4 * libmspack is free software; you can redistribute it and/or modify it under 5 * the terms of the GNU Lesser General Public License (LGPL) version 2.1 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU Lesser General Public License for more details. 11 * 12 * You should have received a copy of the GNU Lesser General Public License 13 * along with this program; if not, write to the Free Software 14 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 15 */ 16 17 /** \mainpage 18 * 19 * \section intro Introduction 20 * 21 * libmspack is a library which provides compressors and decompressors, 22 * archivers and dearchivers for Microsoft compression formats. 23 * 24 * \section formats Formats supported 25 * 26 * The following file formats are supported: 27 * - SZDD files, which use LZSS compression 28 * - KWAJ files, which use LZSS, LZSS+Huffman or deflate compression 29 * - .HLP (MS Help) files, which use LZSS compression 30 * - .CAB (MS Cabinet) files, which use deflate, LZX or Quantum compression 31 * - .CHM (HTML Help) files, which use LZX compression 32 * - .LIT (MS EBook) files, which use LZX compression and DES encryption 33 * - .LZX (Exchange Offline Addressbook) files, which use LZX compression 34 * 35 * To determine the capabilities of the library, and the binary 36 * compatibility version of any particular compressor or decompressor, use 37 * the mspack_version() function. The UNIX library interface version is 38 * defined as the highest-versioned library component. 39 * 40 * \section starting Getting started 41 * 42 * The macro MSPACK_SYS_SELFTEST() should be used to ensure the library can 43 * be used. In particular, it checks if the caller is using 32-bit file I/O 44 * when the library is compiled for 64-bit file I/O and vice versa. 45 * 46 * If compiled normally, the library includes basic file I/O and memory 47 * management functionality using the standard C library. This can be 48 * customised and replaced entirely by creating a mspack_system structure. 49 * 50 * A compressor or decompressor for the required format must be 51 * instantiated before it can be used. Each construction function takes 52 * one parameter, which is either a pointer to a custom mspack_system 53 * structure, or NULL to use the default. The instantiation returned, if 54 * not NULL, contains function pointers (methods) to work with the given 55 * file format. 56 * 57 * For compression: 58 * - mspack_create_cab_compressor() creates a mscab_compressor 59 * - mspack_create_chm_compressor() creates a mschm_compressor 60 * - mspack_create_lit_compressor() creates a mslit_compressor 61 * - mspack_create_hlp_compressor() creates a mshlp_compressor 62 * - mspack_create_szdd_compressor() creates a msszdd_compressor 63 * - mspack_create_kwaj_compressor() creates a mskwaj_compressor 64 * - mspack_create_oab_compressor() creates a msoab_compressor 65 * 66 * For decompression: 67 * - mspack_create_cab_decompressor() creates a mscab_decompressor 68 * - mspack_create_chm_decompressor() creates a mschm_decompressor 69 * - mspack_create_lit_decompressor() creates a mslit_decompressor 70 * - mspack_create_hlp_decompressor() creates a mshlp_decompressor 71 * - mspack_create_szdd_decompressor() creates a msszdd_decompressor 72 * - mspack_create_kwaj_decompressor() creates a mskwaj_decompressor 73 * - mspack_create_oab_decompressor() creates a msoab_decompressor 74 * 75 * Once finished working with a format, each kind of 76 * compressor/decompressor has its own specific destructor: 77 * - mspack_destroy_cab_compressor() 78 * - mspack_destroy_cab_decompressor() 79 * - mspack_destroy_chm_compressor() 80 * - mspack_destroy_chm_decompressor() 81 * - mspack_destroy_lit_compressor() 82 * - mspack_destroy_lit_decompressor() 83 * - mspack_destroy_hlp_compressor() 84 * - mspack_destroy_hlp_decompressor() 85 * - mspack_destroy_szdd_compressor() 86 * - mspack_destroy_szdd_decompressor() 87 * - mspack_destroy_kwaj_compressor() 88 * - mspack_destroy_kwaj_decompressor() 89 * - mspack_destroy_oab_compressor() 90 * - mspack_destroy_oab_decompressor() 91 * 92 * Destroying a compressor or decompressor does not destroy any objects, 93 * structures or handles that have been created using that compressor or 94 * decompressor. Ensure that everything created or opened is destroyed or 95 * closed before compressor/decompressor is itself destroyed. 96 * 97 * \section errors Error codes 98 * 99 * All compressors and decompressors use the same set of error codes. Most 100 * methods return an error code directly. For methods which do not 101 * return error codes directly, the error code can be obtained with the 102 * last_error() method. 103 * 104 * - #MSPACK_ERR_OK is used to indicate success. This error code is defined 105 * as zero, all other code are non-zero. 106 * - #MSPACK_ERR_ARGS indicates that a method was called with inappropriate 107 * arguments. 108 * - #MSPACK_ERR_OPEN indicates that mspack_system::open() failed. 109 * - #MSPACK_ERR_READ indicates that mspack_system::read() failed. 110 * - #MSPACK_ERR_WRITE indicates that mspack_system::write() failed. 111 * - #MSPACK_ERR_SEEK indicates that mspack_system::seek() failed. 112 * - #MSPACK_ERR_NOMEMORY indicates that mspack_system::alloc() failed. 113 * - #MSPACK_ERR_SIGNATURE indicates that the file being read does not 114 * have the correct "signature". It is probably not a valid file for 115 * whatever format is being read. 116 * - #MSPACK_ERR_DATAFORMAT indicates that the file being used or read 117 * is corrupt. 118 * - #MSPACK_ERR_CHECKSUM indicates that a data checksum has failed. 119 * - #MSPACK_ERR_CRUNCH indicates an error occured during compression. 120 * - #MSPACK_ERR_DECRUNCH indicates an error occured during decompression. 121 * 122 * \section threading Multi-threading 123 * 124 * libmspack methods are reentrant and multithreading-safe when each 125 * thread has its own compressor or decompressor. 126 127 * You should not call multiple methods simultaneously on a single 128 * compressor or decompressor instance. 129 * 130 * If this may happen, you can either use one compressor or 131 * decompressor per thread, or you can use your preferred lock, 132 * semaphore or mutex library to ensure no more than one method on a 133 * compressor/decompressor is called simultaneously. libmspack will 134 * not do this locking for you. 135 * 136 * Example of incorrect behaviour: 137 * - thread 1 calls mspack_create_cab_decompressor() 138 * - thread 1 calls open() 139 * - thread 1 calls extract() for one file 140 * - thread 2 simultaneously calls extract() for another file 141 * 142 * Correct behaviour: 143 * - thread 1 calls mspack_create_cab_decompressor() 144 * - thread 2 calls mspack_create_cab_decompressor() 145 * - thread 1 calls its own open() / extract() 146 * - thread 2 simultaneously calls its own open() / extract() 147 * 148 * Also correct behaviour: 149 * - thread 1 calls mspack_create_cab_decompressor() 150 * - thread 1 locks a mutex for with the decompressor before 151 * calling any methods on it, and unlocks the mutex after each 152 * method returns. 153 * - thread 1 can share the results of open() with thread 2, and both 154 * can call extract(), provided they both guard against simultaneous 155 * use of extract(), and any other methods, with the mutex 156 */ 157 158 #ifndef LIB_MSPACK_H 159 #define LIB_MSPACK_H 1 160 161 #ifdef __cplusplus 162 extern "C" { 163 #endif 164 165 #include <sys/types.h> 166 #include <stdlib.h> 167 168 /** 169 * System self-test function, to ensure both library and calling program 170 * can use one another. 171 * 172 * A result of MSPACK_ERR_OK means the library and caller are 173 * compatible. Any other result indicates that the library and caller are 174 * not compatible and should not be used. In particular, a value of 175 * MSPACK_ERR_SEEK means the library and caller use different off_t 176 * datatypes. 177 * 178 * It should be used like so: 179 * 180 * @code 181 * int selftest_result; 182 * MSPACK_SYS_SELFTEST(selftest_result); 183 * if (selftest_result != MSPACK_ERR_OK) { 184 * fprintf(stderr, "incompatible with this build of libmspack\n"); 185 * exit(0); 186 * } 187 * @endcode 188 * 189 * @param result an int variable to store the result of the self-test 190 */ 191 #define MSPACK_SYS_SELFTEST(result) do { \ 192 (result) = mspack_sys_selftest_internal(sizeof(off_t)); \ 193 } while (0) 194 195 /** Part of the MSPACK_SYS_SELFTEST() macro, must not be used directly. */ 196 extern int mspack_sys_selftest_internal(int); 197 198 /** 199 * Enquire about the binary compatibility version of a specific interface in 200 * the library. Currently, the following interfaces are defined: 201 * 202 * - #MSPACK_VER_LIBRARY: the overall library 203 * - #MSPACK_VER_SYSTEM: the mspack_system interface 204 * - #MSPACK_VER_MSCABD: the mscab_decompressor interface 205 * - #MSPACK_VER_MSCABC: the mscab_compressor interface 206 * - #MSPACK_VER_MSCHMD: the mschm_decompressor interface 207 * - #MSPACK_VER_MSCHMC: the mschm_compressor interface 208 * - #MSPACK_VER_MSLITD: the mslit_decompressor interface 209 * - #MSPACK_VER_MSLITC: the mslit_compressor interface 210 * - #MSPACK_VER_MSHLPD: the mshlp_decompressor interface 211 * - #MSPACK_VER_MSHLPC: the mshlp_compressor interface 212 * - #MSPACK_VER_MSSZDDD: the msszdd_decompressor interface 213 * - #MSPACK_VER_MSSZDDC: the msszdd_compressor interface 214 * - #MSPACK_VER_MSKWAJD: the mskwaj_decompressor interface 215 * - #MSPACK_VER_MSKWAJC: the mskwaj_compressor interface 216 * - #MSPACK_VER_MSOABD: the msoab_decompressor interface 217 * - #MSPACK_VER_MSOABC: the msoab_compressor interface 218 * 219 * The result of the function should be interpreted as follows: 220 * - -1: this interface is completely unknown to the library 221 * - 0: this interface is known, but non-functioning 222 * - 1: this interface has all basic functionality 223 * - 2, 3, ...: this interface has additional functionality, clearly marked 224 * in the documentation as "version 2", "version 3" and so on. 225 * 226 * @param entity the interface to request current version of 227 * @return the version of the requested interface 228 */ 229 extern int mspack_version(int entity); 230 231 /** Pass to mspack_version() to get the overall library version */ 232 #define MSPACK_VER_LIBRARY (0) 233 /** Pass to mspack_version() to get the mspack_system version */ 234 #define MSPACK_VER_SYSTEM (1) 235 /** Pass to mspack_version() to get the mscab_decompressor version */ 236 #define MSPACK_VER_MSCABD (2) 237 /** Pass to mspack_version() to get the mscab_compressor version */ 238 #define MSPACK_VER_MSCABC (3) 239 /** Pass to mspack_version() to get the mschm_decompressor version */ 240 #define MSPACK_VER_MSCHMD (4) 241 /** Pass to mspack_version() to get the mschm_compressor version */ 242 #define MSPACK_VER_MSCHMC (5) 243 /** Pass to mspack_version() to get the mslit_decompressor version */ 244 #define MSPACK_VER_MSLITD (6) 245 /** Pass to mspack_version() to get the mslit_compressor version */ 246 #define MSPACK_VER_MSLITC (7) 247 /** Pass to mspack_version() to get the mshlp_decompressor version */ 248 #define MSPACK_VER_MSHLPD (8) 249 /** Pass to mspack_version() to get the mshlp_compressor version */ 250 #define MSPACK_VER_MSHLPC (9) 251 /** Pass to mspack_version() to get the msszdd_decompressor version */ 252 #define MSPACK_VER_MSSZDDD (10) 253 /** Pass to mspack_version() to get the msszdd_compressor version */ 254 #define MSPACK_VER_MSSZDDC (11) 255 /** Pass to mspack_version() to get the mskwaj_decompressor version */ 256 #define MSPACK_VER_MSKWAJD (12) 257 /** Pass to mspack_version() to get the mskwaj_compressor version */ 258 #define MSPACK_VER_MSKWAJC (13) 259 /** Pass to mspack_version() to get the msoab_decompressor version */ 260 #define MSPACK_VER_MSOABD (14) 261 /** Pass to mspack_version() to get the msoab_compressor version */ 262 #define MSPACK_VER_MSOABC (15) 263 264 /* --- file I/O abstraction ------------------------------------------------ */ 265 266 /** 267 * A structure which abstracts file I/O and memory management. 268 * 269 * The library always uses the mspack_system structure for interaction 270 * with the file system and to allocate, free and copy all memory. It also 271 * uses it to send literal messages to the library user. 272 * 273 * When the library is compiled normally, passing NULL to a compressor or 274 * decompressor constructor will result in a default mspack_system being 275 * used, where all methods are implemented with the standard C library. 276 * However, all constructors support being given a custom created 277 * mspack_system structure, with the library user's own methods. This 278 * allows for more abstract interaction, such as reading and writing files 279 * directly to memory, or from a network socket or pipe. 280 * 281 * Implementors of an mspack_system structure should read all 282 * documentation entries for every structure member, and write methods 283 * which conform to those standards. 284 */ 285 struct mspack_system { 286 /** 287 * Opens a file for reading, writing, appending or updating. 288 * 289 * @param self a self-referential pointer to the mspack_system 290 * structure whose open() method is being called. If 291 * this pointer is required by close(), read(), write(), 292 * seek() or tell(), it should be stored in the result 293 * structure at this time. 294 * @param filename the file to be opened. It is passed directly from the 295 * library caller without being modified, so it is up to 296 * the caller what this parameter actually represents. 297 * @param mode one of #MSPACK_SYS_OPEN_READ (open an existing file 298 * for reading), #MSPACK_SYS_OPEN_WRITE (open a new file 299 * for writing), #MSPACK_SYS_OPEN_UPDATE (open an existing 300 * file for reading/writing from the start of the file) or 301 * #MSPACK_SYS_OPEN_APPEND (open an existing file for 302 * reading/writing from the end of the file) 303 * @return a pointer to a mspack_file structure. This structure officially 304 * contains no members, its true contents are up to the 305 * mspack_system implementor. It should contain whatever is needed 306 * for other mspack_system methods to operate. Returning the NULL 307 * pointer indicates an error condition. 308 * @see close(), read(), write(), seek(), tell(), message() 309 */ 310 struct mspack_file * (*open)(struct mspack_system *self, 311 const char *filename, 312 int mode); 313 314 /** 315 * Closes a previously opened file. If any memory was allocated for this 316 * particular file handle, it should be freed at this time. 317 * 318 * @param file the file to close 319 * @see open() 320 */ 321 void (*close)(struct mspack_file *file); 322 323 /** 324 * Reads a given number of bytes from an open file. 325 * 326 * @param file the file to read from 327 * @param buffer the location where the read bytes should be stored 328 * @param bytes the number of bytes to read from the file. 329 * @return the number of bytes successfully read (this can be less than 330 * the number requested), zero to mark the end of file, or less 331 * than zero to indicate an error. The library does not "retry" 332 * reads and assumes short reads are due to EOF, so you should 333 * avoid returning short reads because of transient errors. 334 * @see open(), write() 335 */ 336 int (*read)(struct mspack_file *file, 337 void *buffer, 338 int bytes); 339 340 /** 341 * Writes a given number of bytes to an open file. 342 * 343 * @param file the file to write to 344 * @param buffer the location where the written bytes should be read from 345 * @param bytes the number of bytes to write to the file. 346 * @return the number of bytes successfully written, this can be less 347 * than the number requested. Zero or less can indicate an error 348 * where no bytes at all could be written. All cases where less 349 * bytes were written than requested are considered by the library 350 * to be an error. 351 * @see open(), read() 352 */ 353 int (*write)(struct mspack_file *file, 354 void *buffer, 355 int bytes); 356 357 /** 358 * Seeks to a specific file offset within an open file. 359 * 360 * Sometimes the library needs to know the length of a file. It does 361 * this by seeking to the end of the file with seek(file, 0, 362 * MSPACK_SYS_SEEK_END), then calling tell(). Implementations may want 363 * to make a special case for this. 364 * 365 * Due to the potentially varying 32/64 bit datatype off_t on some 366 * architectures, the #MSPACK_SYS_SELFTEST macro MUST be used before 367 * using the library. If not, the error caused by the library passing an 368 * inappropriate stackframe to seek() is subtle and hard to trace. 369 * 370 * @param file the file to be seeked 371 * @param offset an offset to seek, measured in bytes 372 * @param mode one of #MSPACK_SYS_SEEK_START (the offset should be 373 * measured from the start of the file), #MSPACK_SYS_SEEK_CUR 374 * (the offset should be measured from the current file offset) 375 * or #MSPACK_SYS_SEEK_END (the offset should be measured from 376 * the end of the file) 377 * @return zero for success, non-zero for an error 378 * @see open(), tell() 379 */ 380 int (*seek)(struct mspack_file *file, 381 off_t offset, 382 int mode); 383 384 /** 385 * Returns the current file position (in bytes) of the given file. 386 * 387 * @param file the file whose file position is wanted 388 * @return the current file position of the file 389 * @see open(), seek() 390 */ 391 off_t (*tell)(struct mspack_file *file); 392 393 /** 394 * Used to send messages from the library to the user. 395 * 396 * Occasionally, the library generates warnings or other messages in 397 * plain english to inform the human user. These are informational only 398 * and can be ignored if not wanted. 399 * 400 * @param file may be a file handle returned from open() if this message 401 * pertains to a specific open file, or NULL if not related to 402 * a specific file. 403 * @param format a printf() style format string. It does NOT include a 404 * trailing newline. 405 * @see open() 406 */ 407 void (*message)(struct mspack_file *file, 408 const char *format, 409 ...); 410 411 /** 412 * Allocates memory. 413 * 414 * @param self a self-referential pointer to the mspack_system 415 * structure whose alloc() method is being called. 416 * @param bytes the number of bytes to allocate 417 * @result a pointer to the requested number of bytes, or NULL if 418 * not enough memory is available 419 * @see free() 420 */ 421 void * (*alloc)(struct mspack_system *self, 422 size_t bytes); 423 424 /** 425 * Frees memory. 426 * 427 * @param ptr the memory to be freed. NULL is accepted and ignored. 428 * @see alloc() 429 */ 430 void (*free)(void *ptr); 431 432 /** 433 * Copies from one region of memory to another. 434 * 435 * The regions of memory are guaranteed not to overlap, are usually less 436 * than 256 bytes, and may not be aligned. Please note that the source 437 * parameter comes before the destination parameter, unlike the standard 438 * C function memcpy(). 439 * 440 * @param src the region of memory to copy from 441 * @param dest the region of memory to copy to 442 * @param bytes the size of the memory region, in bytes 443 */ 444 void (*copy)(void *src, 445 void *dest, 446 size_t bytes); 447 448 /** 449 * A null pointer to mark the end of mspack_system. It must equal NULL. 450 * 451 * Should the mspack_system structure extend in the future, this NULL 452 * will be seen, rather than have an invalid method pointer called. 453 */ 454 void *null_ptr; 455 }; 456 457 /** mspack_system::open() mode: open existing file for reading. */ 458 #define MSPACK_SYS_OPEN_READ (0) 459 /** mspack_system::open() mode: open new file for writing */ 460 #define MSPACK_SYS_OPEN_WRITE (1) 461 /** mspack_system::open() mode: open existing file for writing */ 462 #define MSPACK_SYS_OPEN_UPDATE (2) 463 /** mspack_system::open() mode: open existing file for writing */ 464 #define MSPACK_SYS_OPEN_APPEND (3) 465 466 /** mspack_system::seek() mode: seek relative to start of file */ 467 #define MSPACK_SYS_SEEK_START (0) 468 /** mspack_system::seek() mode: seek relative to current offset */ 469 #define MSPACK_SYS_SEEK_CUR (1) 470 /** mspack_system::seek() mode: seek relative to end of file */ 471 #define MSPACK_SYS_SEEK_END (2) 472 473 /** 474 * A structure which represents an open file handle. The contents of this 475 * structure are determined by the implementation of the 476 * mspack_system::open() method. 477 */ 478 struct mspack_file { 479 int dummy; 480 }; 481 482 /* --- error codes --------------------------------------------------------- */ 483 484 /** Error code: no error */ 485 #define MSPACK_ERR_OK (0) 486 /** Error code: bad arguments to method */ 487 #define MSPACK_ERR_ARGS (1) 488 /** Error code: error opening file */ 489 #define MSPACK_ERR_OPEN (2) 490 /** Error code: error reading file */ 491 #define MSPACK_ERR_READ (3) 492 /** Error code: error writing file */ 493 #define MSPACK_ERR_WRITE (4) 494 /** Error code: seek error */ 495 #define MSPACK_ERR_SEEK (5) 496 /** Error code: out of memory */ 497 #define MSPACK_ERR_NOMEMORY (6) 498 /** Error code: bad "magic id" in file */ 499 #define MSPACK_ERR_SIGNATURE (7) 500 /** Error code: bad or corrupt file format */ 501 #define MSPACK_ERR_DATAFORMAT (8) 502 /** Error code: bad checksum or CRC */ 503 #define MSPACK_ERR_CHECKSUM (9) 504 /** Error code: error during compression */ 505 #define MSPACK_ERR_CRUNCH (10) 506 /** Error code: error during decompression */ 507 #define MSPACK_ERR_DECRUNCH (11) 508 509 /* --- functions available in library -------------------------------------- */ 510 511 /** Creates a new CAB compressor. 512 * @param sys a custom mspack_system structure, or NULL to use the default 513 * @return a #mscab_compressor or NULL 514 */ 515 extern struct mscab_compressor * 516 mspack_create_cab_compressor(struct mspack_system *sys); 517 518 /** Creates a new CAB decompressor. 519 * @param sys a custom mspack_system structure, or NULL to use the default 520 * @return a #mscab_decompressor or NULL 521 */ 522 extern struct mscab_decompressor * 523 mspack_create_cab_decompressor(struct mspack_system *sys); 524 525 /** Destroys an existing CAB compressor. 526 * @param self the #mscab_compressor to destroy 527 */ 528 extern void mspack_destroy_cab_compressor(struct mscab_compressor *self); 529 530 /** Destroys an existing CAB decompressor. 531 * @param self the #mscab_decompressor to destroy 532 */ 533 extern void mspack_destroy_cab_decompressor(struct mscab_decompressor *self); 534 535 536 /** Creates a new CHM compressor. 537 * @param sys a custom mspack_system structure, or NULL to use the default 538 * @return a #mschm_compressor or NULL 539 */ 540 extern struct mschm_compressor * 541 mspack_create_chm_compressor(struct mspack_system *sys); 542 543 /** Creates a new CHM decompressor. 544 * @param sys a custom mspack_system structure, or NULL to use the default 545 * @return a #mschm_decompressor or NULL 546 */ 547 extern struct mschm_decompressor * 548 mspack_create_chm_decompressor(struct mspack_system *sys); 549 550 /** Destroys an existing CHM compressor. 551 * @param self the #mschm_compressor to destroy 552 */ 553 extern void mspack_destroy_chm_compressor(struct mschm_compressor *self); 554 555 /** Destroys an existing CHM decompressor. 556 * @param self the #mschm_decompressor to destroy 557 */ 558 extern void mspack_destroy_chm_decompressor(struct mschm_decompressor *self); 559 560 561 /** Creates a new LIT compressor. 562 * @param sys a custom mspack_system structure, or NULL to use the default 563 * @return a #mslit_compressor or NULL 564 */ 565 extern struct mslit_compressor * 566 mspack_create_lit_compressor(struct mspack_system *sys); 567 568 /** Creates a new LIT decompressor. 569 * @param sys a custom mspack_system structure, or NULL to use the default 570 * @return a #mslit_decompressor or NULL 571 */ 572 extern struct mslit_decompressor * 573 mspack_create_lit_decompressor(struct mspack_system *sys); 574 575 /** Destroys an existing LIT compressor. 576 * @param self the #mslit_compressor to destroy 577 */ 578 extern void mspack_destroy_lit_compressor(struct mslit_compressor *self); 579 580 /** Destroys an existing LIT decompressor. 581 * @param self the #mslit_decompressor to destroy 582 */ 583 extern void mspack_destroy_lit_decompressor(struct mslit_decompressor *self); 584 585 586 /** Creates a new HLP compressor. 587 * @param sys a custom mspack_system structure, or NULL to use the default 588 * @return a #mshlp_compressor or NULL 589 */ 590 extern struct mshlp_compressor * 591 mspack_create_hlp_compressor(struct mspack_system *sys); 592 593 /** Creates a new HLP decompressor. 594 * @param sys a custom mspack_system structure, or NULL to use the default 595 * @return a #mshlp_decompressor or NULL 596 */ 597 extern struct mshlp_decompressor * 598 mspack_create_hlp_decompressor(struct mspack_system *sys); 599 600 /** Destroys an existing hlp compressor. 601 * @param self the #mshlp_compressor to destroy 602 */ 603 extern void mspack_destroy_hlp_compressor(struct mshlp_compressor *self); 604 605 /** Destroys an existing hlp decompressor. 606 * @param self the #mshlp_decompressor to destroy 607 */ 608 extern void mspack_destroy_hlp_decompressor(struct mshlp_decompressor *self); 609 610 611 /** Creates a new SZDD compressor. 612 * @param sys a custom mspack_system structure, or NULL to use the default 613 * @return a #msszdd_compressor or NULL 614 */ 615 extern struct msszdd_compressor * 616 mspack_create_szdd_compressor(struct mspack_system *sys); 617 618 /** Creates a new SZDD decompressor. 619 * @param sys a custom mspack_system structure, or NULL to use the default 620 * @return a #msszdd_decompressor or NULL 621 */ 622 extern struct msszdd_decompressor * 623 mspack_create_szdd_decompressor(struct mspack_system *sys); 624 625 /** Destroys an existing SZDD compressor. 626 * @param self the #msszdd_compressor to destroy 627 */ 628 extern void mspack_destroy_szdd_compressor(struct msszdd_compressor *self); 629 630 /** Destroys an existing SZDD decompressor. 631 * @param self the #msszdd_decompressor to destroy 632 */ 633 extern void mspack_destroy_szdd_decompressor(struct msszdd_decompressor *self); 634 635 636 /** Creates a new KWAJ compressor. 637 * @param sys a custom mspack_system structure, or NULL to use the default 638 * @return a #mskwaj_compressor or NULL 639 */ 640 extern struct mskwaj_compressor * 641 mspack_create_kwaj_compressor(struct mspack_system *sys); 642 643 /** Creates a new KWAJ decompressor. 644 * @param sys a custom mspack_system structure, or NULL to use the default 645 * @return a #mskwaj_decompressor or NULL 646 */ 647 extern struct mskwaj_decompressor * 648 mspack_create_kwaj_decompressor(struct mspack_system *sys); 649 650 /** Destroys an existing KWAJ compressor. 651 * @param self the #mskwaj_compressor to destroy 652 */ 653 extern void mspack_destroy_kwaj_compressor(struct mskwaj_compressor *self); 654 655 /** Destroys an existing KWAJ decompressor. 656 * @param self the #mskwaj_decompressor to destroy 657 */ 658 extern void mspack_destroy_kwaj_decompressor(struct mskwaj_decompressor *self); 659 660 661 /** Creates a new OAB compressor. 662 * @param sys a custom mspack_system structure, or NULL to use the default 663 * @return a #msoab_compressor or NULL 664 */ 665 extern struct msoab_compressor * 666 mspack_create_oab_compressor(struct mspack_system *sys); 667 668 /** Creates a new OAB decompressor. 669 * @param sys a custom mspack_system structure, or NULL to use the default 670 * @return a #msoab_decompressor or NULL 671 */ 672 extern struct msoab_decompressor * 673 mspack_create_oab_decompressor(struct mspack_system *sys); 674 675 /** Destroys an existing OAB compressor. 676 * @param self the #msoab_compressor to destroy 677 */ 678 extern void mspack_destroy_oab_compressor(struct msoab_compressor *self); 679 680 /** Destroys an existing OAB decompressor. 681 * @param self the #msoab_decompressor to destroy 682 */ 683 extern void mspack_destroy_oab_decompressor(struct msoab_decompressor *self); 684 685 686 /* --- support for .CAB (MS Cabinet) file format --------------------------- */ 687 688 /** 689 * A structure which represents a single cabinet file. 690 * 691 * All fields are READ ONLY. 692 * 693 * If this cabinet is part of a merged cabinet set, the #files and #folders 694 * fields are common to all cabinets in the set, and will be identical. 695 * 696 * @see mscab_decompressor::open(), mscab_decompressor::close(), 697 * mscab_decompressor::search() 698 */ 699 struct mscabd_cabinet { 700 /** 701 * The next cabinet in a chained list, if this cabinet was opened with 702 * mscab_decompressor::search(). May be NULL to mark the end of the 703 * list. 704 */ 705 struct mscabd_cabinet *next; 706 707 /** 708 * The filename of the cabinet. More correctly, the filename of the 709 * physical file that the cabinet resides in. This is given by the 710 * library user and may be in any format. 711 */ 712 const char *filename; 713 714 /** The file offset of cabinet within the physical file it resides in. */ 715 off_t base_offset; 716 717 /** The length of the cabinet file in bytes. */ 718 unsigned int length; 719 720 /** The previous cabinet in a cabinet set, or NULL. */ 721 struct mscabd_cabinet *prevcab; 722 723 /** The next cabinet in a cabinet set, or NULL. */ 724 struct mscabd_cabinet *nextcab; 725 726 /** The filename of the previous cabinet in a cabinet set, or NULL. */ 727 char *prevname; 728 729 /** The filename of the next cabinet in a cabinet set, or NULL. */ 730 char *nextname; 731 732 /** The name of the disk containing the previous cabinet in a cabinet 733 * set, or NULL. 734 */ 735 char *previnfo; 736 737 /** The name of the disk containing the next cabinet in a cabinet set, 738 * or NULL. 739 */ 740 char *nextinfo; 741 742 /** A list of all files in the cabinet or cabinet set. */ 743 struct mscabd_file *files; 744 745 /** A list of all folders in the cabinet or cabinet set. */ 746 struct mscabd_folder *folders; 747 748 /** 749 * The set ID of the cabinet. All cabinets in the same set should have 750 * the same set ID. 751 */ 752 unsigned short set_id; 753 754 /** 755 * The index number of the cabinet within the set. Numbering should 756 * start from 0 for the first cabinet in the set, and increment by 1 for 757 * each following cabinet. 758 */ 759 unsigned short set_index; 760 761 /** 762 * The number of bytes reserved in the header area of the cabinet. 763 * 764 * If this is non-zero and flags has MSCAB_HDR_RESV set, this data can 765 * be read by the calling application. It is of the given length, 766 * located at offset (base_offset + MSCAB_HDR_RESV_OFFSET) in the 767 * cabinet file. 768 * 769 * @see flags 770 */ 771 unsigned short header_resv; 772 773 /** 774 * Header flags. 775 * 776 * - MSCAB_HDR_PREVCAB indicates the cabinet is part of a cabinet set, and 777 * has a predecessor cabinet. 778 * - MSCAB_HDR_NEXTCAB indicates the cabinet is part of a cabinet set, and 779 * has a successor cabinet. 780 * - MSCAB_HDR_RESV indicates the cabinet has reserved header space. 781 * 782 * @see prevname, previnfo, nextname, nextinfo, header_resv 783 */ 784 int flags; 785 }; 786 787 /** Offset from start of cabinet to the reserved header data (if present). */ 788 #define MSCAB_HDR_RESV_OFFSET (0x28) 789 790 /** Cabinet header flag: cabinet has a predecessor */ 791 #define MSCAB_HDR_PREVCAB (0x01) 792 /** Cabinet header flag: cabinet has a successor */ 793 #define MSCAB_HDR_NEXTCAB (0x02) 794 /** Cabinet header flag: cabinet has reserved header space */ 795 #define MSCAB_HDR_RESV (0x04) 796 797 /** 798 * A structure which represents a single folder in a cabinet or cabinet set. 799 * 800 * All fields are READ ONLY. 801 * 802 * A folder is a single compressed stream of data. When uncompressed, it 803 * holds the data of one or more files. A folder may be split across more 804 * than one cabinet. 805 */ 806 struct mscabd_folder { 807 /** 808 * A pointer to the next folder in this cabinet or cabinet set, or NULL 809 * if this is the final folder. 810 */ 811 struct mscabd_folder *next; 812 813 /** 814 * The compression format used by this folder. 815 * 816 * The macro MSCABD_COMP_METHOD() should be used on this field to get 817 * the algorithm used. The macro MSCABD_COMP_LEVEL() should be used to get 818 * the "compression level". 819 * 820 * @see MSCABD_COMP_METHOD(), MSCABD_COMP_LEVEL() 821 */ 822 int comp_type; 823 824 /** 825 * The total number of data blocks used by this folder. This includes 826 * data blocks present in other files, if this folder spans more than 827 * one cabinet. 828 */ 829 unsigned int num_blocks; 830 }; 831 832 /** 833 * Returns the compression method used by a folder. 834 * 835 * @param comp_type a mscabd_folder::comp_type value 836 * @return one of #MSCAB_COMP_NONE, #MSCAB_COMP_MSZIP, #MSCAB_COMP_QUANTUM 837 * or #MSCAB_COMP_LZX 838 */ 839 #define MSCABD_COMP_METHOD(comp_type) ((comp_type) & 0x0F) 840 /** 841 * Returns the compression level used by a folder. 842 * 843 * @param comp_type a mscabd_folder::comp_type value 844 * @return the compression level. This is only defined by LZX and Quantum 845 * compression 846 */ 847 #define MSCABD_COMP_LEVEL(comp_type) (((comp_type) >> 8) & 0x1F) 848 849 /** Compression mode: no compression. */ 850 #define MSCAB_COMP_NONE (0) 851 /** Compression mode: MSZIP (deflate) compression. */ 852 #define MSCAB_COMP_MSZIP (1) 853 /** Compression mode: Quantum compression */ 854 #define MSCAB_COMP_QUANTUM (2) 855 /** Compression mode: LZX compression */ 856 #define MSCAB_COMP_LZX (3) 857 858 /** 859 * A structure which represents a single file in a cabinet or cabinet set. 860 * 861 * All fields are READ ONLY. 862 */ 863 struct mscabd_file { 864 /** 865 * The next file in the cabinet or cabinet set, or NULL if this is the 866 * final file. 867 */ 868 struct mscabd_file *next; 869 870 /** 871 * The filename of the file. 872 * 873 * A null terminated string of up to 255 bytes in length, it may be in 874 * either ISO-8859-1 or UTF8 format, depending on the file attributes. 875 * 876 * @see attribs 877 */ 878 char *filename; 879 880 /** The uncompressed length of the file, in bytes. */ 881 unsigned int length; 882 883 /** 884 * File attributes. 885 * 886 * The following attributes are defined: 887 * - #MSCAB_ATTRIB_RDONLY indicates the file is write protected. 888 * - #MSCAB_ATTRIB_HIDDEN indicates the file is hidden. 889 * - #MSCAB_ATTRIB_SYSTEM indicates the file is a operating system file. 890 * - #MSCAB_ATTRIB_ARCH indicates the file is "archived". 891 * - #MSCAB_ATTRIB_EXEC indicates the file is an executable program. 892 * - #MSCAB_ATTRIB_UTF_NAME indicates the filename is in UTF8 format rather 893 * than ISO-8859-1. 894 */ 895 int attribs; 896 897 /** File's last modified time, hour field. */ 898 char time_h; 899 /** File's last modified time, minute field. */ 900 char time_m; 901 /** File's last modified time, second field. */ 902 char time_s; 903 904 /** File's last modified date, day field. */ 905 char date_d; 906 /** File's last modified date, month field. */ 907 char date_m; 908 /** File's last modified date, year field. */ 909 int date_y; 910 911 /** A pointer to the folder that contains this file. */ 912 struct mscabd_folder *folder; 913 914 /** The uncompressed offset of this file in its folder. */ 915 unsigned int offset; 916 }; 917 918 /** mscabd_file::attribs attribute: file is read-only. */ 919 #define MSCAB_ATTRIB_RDONLY (0x01) 920 /** mscabd_file::attribs attribute: file is hidden. */ 921 #define MSCAB_ATTRIB_HIDDEN (0x02) 922 /** mscabd_file::attribs attribute: file is an operating system file. */ 923 #define MSCAB_ATTRIB_SYSTEM (0x04) 924 /** mscabd_file::attribs attribute: file is "archived". */ 925 #define MSCAB_ATTRIB_ARCH (0x20) 926 /** mscabd_file::attribs attribute: file is an executable program. */ 927 #define MSCAB_ATTRIB_EXEC (0x40) 928 /** mscabd_file::attribs attribute: filename is UTF8, not ISO-8859-1. */ 929 #define MSCAB_ATTRIB_UTF_NAME (0x80) 930 931 /** mscab_decompressor::set_param() parameter: search buffer size. */ 932 #define MSCABD_PARAM_SEARCHBUF (0) 933 /** mscab_decompressor::set_param() parameter: repair MS-ZIP streams? */ 934 #define MSCABD_PARAM_FIXMSZIP (1) 935 /** mscab_decompressor::set_param() parameter: size of decompression buffer */ 936 #define MSCABD_PARAM_DECOMPBUF (2) 937 /** mscab_decompressor::set_param() parameter: salvage data from bad cabinets? 938 * If enabled, open() will skip file with bad folder indices or filenames 939 * rather than reject the whole cabinet, and extract() will limit rather than 940 * reject files with invalid offsets and lengths, and bad data block checksums 941 * will be ignored. Available only in CAB decoder version 2 and above. 942 */ 943 #define MSCABD_PARAM_SALVAGE (3) 944 945 /** TODO */ 946 struct mscab_compressor { 947 int dummy; 948 }; 949 950 /** 951 * A decompressor for .CAB (Microsoft Cabinet) files 952 * 953 * All fields are READ ONLY. 954 * 955 * @see mspack_create_cab_decompressor(), mspack_destroy_cab_decompressor() 956 */ 957 struct mscab_decompressor { 958 /** 959 * Opens a cabinet file and reads its contents. 960 * 961 * If the file opened is a valid cabinet file, all headers will be read 962 * and a mscabd_cabinet structure will be returned, with a full list of 963 * folders and files. 964 * 965 * In the case of an error occuring, NULL is returned and the error code 966 * is available from last_error(). 967 * 968 * The filename pointer should be considered "in use" until close() is 969 * called on the cabinet. 970 * 971 * @param self a self-referential pointer to the mscab_decompressor 972 * instance being called 973 * @param filename the filename of the cabinet file. This is passed 974 * directly to mspack_system::open(). 975 * @return a pointer to a mscabd_cabinet structure, or NULL on failure 976 * @see close(), search(), last_error() 977 */ 978 struct mscabd_cabinet * (*open) (struct mscab_decompressor *self, 979 const char *filename); 980 981 /** 982 * Closes a previously opened cabinet or cabinet set. 983 * 984 * This closes a cabinet, all cabinets associated with it via the 985 * mscabd_cabinet::next, mscabd_cabinet::prevcab and 986 * mscabd_cabinet::nextcab pointers, and all folders and files. All 987 * memory used by these entities is freed. 988 * 989 * The cabinet pointer is now invalid and cannot be used again. All 990 * mscabd_folder and mscabd_file pointers from that cabinet or cabinet 991 * set are also now invalid, and cannot be used again. 992 * 993 * If the cabinet pointer given was created using search(), it MUST be 994 * the cabinet pointer returned by search() and not one of the later 995 * cabinet pointers further along the mscabd_cabinet::next chain. 996 997 * If extra cabinets have been added using append() or prepend(), these 998 * will all be freed, even if the cabinet pointer given is not the first 999 * cabinet in the set. Do NOT close() more than one cabinet in the set. 1000 * 1001 * The mscabd_cabinet::filename is not freed by the library, as it is 1002 * not allocated by the library. The caller should free this itself if 1003 * necessary, before it is lost forever. 1004 * 1005 * @param self a self-referential pointer to the mscab_decompressor 1006 * instance being called 1007 * @param cab the cabinet to close 1008 * @see open(), search(), append(), prepend() 1009 */ 1010 void (*close)(struct mscab_decompressor *self, 1011 struct mscabd_cabinet *cab); 1012 1013 /** 1014 * Searches a regular file for embedded cabinets. 1015 * 1016 * This opens a normal file with the given filename and will search the 1017 * entire file for embedded cabinet files 1018 * 1019 * If any cabinets are found, the equivalent of open() is called on each 1020 * potential cabinet file at the offset it was found. All successfully 1021 * open()ed cabinets are kept in a list. 1022 * 1023 * The first cabinet found will be returned directly as the result of 1024 * this method. Any further cabinets found will be chained in a list 1025 * using the mscabd_cabinet::next field. 1026 * 1027 * In the case of an error occuring anywhere other than the simulated 1028 * open(), NULL is returned and the error code is available from 1029 * last_error(). 1030 * 1031 * If no error occurs, but no cabinets can be found in the file, NULL is 1032 * returned and last_error() returns MSPACK_ERR_OK. 1033 * 1034 * The filename pointer should be considered in use until close() is 1035 * called on the cabinet. 1036 * 1037 * close() should only be called on the result of search(), not on any 1038 * subsequent cabinets in the mscabd_cabinet::next chain. 1039 * 1040 * @param self a self-referential pointer to the mscab_decompressor 1041 * instance being called 1042 * @param filename the filename of the file to search for cabinets. This 1043 * is passed directly to mspack_system::open(). 1044 * @return a pointer to a mscabd_cabinet structure, or NULL 1045 * @see close(), open(), last_error() 1046 */ 1047 struct mscabd_cabinet * (*search) (struct mscab_decompressor *self, 1048 const char *filename); 1049 1050 /** 1051 * Appends one mscabd_cabinet to another, forming or extending a cabinet 1052 * set. 1053 * 1054 * This will attempt to append one cabinet to another such that 1055 * <tt>(cab->nextcab == nextcab) && (nextcab->prevcab == cab)</tt> and 1056 * any folders split between the two cabinets are merged. 1057 * 1058 * The cabinets MUST be part of a cabinet set -- a cabinet set is a 1059 * cabinet that spans more than one physical cabinet file on disk -- and 1060 * must be appropriately matched. 1061 * 1062 * It can be determined if a cabinet has further parts to load by 1063 * examining the mscabd_cabinet::flags field: 1064 * 1065 * - if <tt>(flags & MSCAB_HDR_PREVCAB)</tt> is non-zero, there is a 1066 * predecessor cabinet to open() and prepend(). Its MS-DOS 1067 * case-insensitive filename is mscabd_cabinet::prevname 1068 * - if <tt>(flags & MSCAB_HDR_NEXTCAB)</tt> is non-zero, there is a 1069 * successor cabinet to open() and append(). Its MS-DOS case-insensitive 1070 * filename is mscabd_cabinet::nextname 1071 * 1072 * If the cabinets do not match, an error code will be returned. Neither 1073 * cabinet has been altered, and both should be closed seperately. 1074 * 1075 * Files and folders in a cabinet set are a single entity. All cabinets 1076 * in a set use the same file list, which is updated as cabinets in the 1077 * set are added. All pointers to mscabd_folder and mscabd_file 1078 * structures in either cabinet must be discarded and re-obtained after 1079 * merging. 1080 * 1081 * @param self a self-referential pointer to the mscab_decompressor 1082 * instance being called 1083 * @param cab the cabinet which will be appended to, 1084 * predecessor of nextcab 1085 * @param nextcab the cabinet which will be appended, 1086 * successor of cab 1087 * @return an error code, or MSPACK_ERR_OK if successful 1088 * @see prepend(), open(), close() 1089 */ 1090 int (*append) (struct mscab_decompressor *self, 1091 struct mscabd_cabinet *cab, 1092 struct mscabd_cabinet *nextcab); 1093 1094 /** 1095 * Prepends one mscabd_cabinet to another, forming or extending a 1096 * cabinet set. 1097 * 1098 * This will attempt to prepend one cabinet to another, such that 1099 * <tt>(cab->prevcab == prevcab) && (prevcab->nextcab == cab)</tt>. In 1100 * all other respects, it is identical to append(). See append() for the 1101 * full documentation. 1102 * 1103 * @param self a self-referential pointer to the mscab_decompressor 1104 * instance being called 1105 * @param cab the cabinet which will be prepended to, 1106 * successor of prevcab 1107 * @param prevcab the cabinet which will be prepended, 1108 * predecessor of cab 1109 * @return an error code, or MSPACK_ERR_OK if successful 1110 * @see append(), open(), close() 1111 */ 1112 int (*prepend) (struct mscab_decompressor *self, 1113 struct mscabd_cabinet *cab, 1114 struct mscabd_cabinet *prevcab); 1115 1116 /** 1117 * Extracts a file from a cabinet or cabinet set. 1118 * 1119 * This extracts a compressed file in a cabinet and writes it to the given 1120 * filename. 1121 * 1122 * The MS-DOS filename of the file, mscabd_file::filename, is NOT USED 1123 * by extract(). The caller must examine this MS-DOS filename, copy and 1124 * change it as necessary, create directories as necessary, and provide 1125 * the correct filename as a parameter, which will be passed unchanged 1126 * to the decompressor's mspack_system::open() 1127 * 1128 * If the file belongs to a split folder in a multi-part cabinet set, 1129 * and not enough parts of the cabinet set have been loaded and appended 1130 * or prepended, an error will be returned immediately. 1131 * 1132 * @param self a self-referential pointer to the mscab_decompressor 1133 * instance being called 1134 * @param file the file to be decompressed 1135 * @param filename the filename of the file being written to 1136 * @return an error code, or MSPACK_ERR_OK if successful 1137 */ 1138 int (*extract)(struct mscab_decompressor *self, 1139 struct mscabd_file *file, 1140 const char *filename); 1141 1142 /** 1143 * Sets a CAB decompression engine parameter. 1144 * 1145 * The following parameters are defined: 1146 * - #MSCABD_PARAM_SEARCHBUF: How many bytes should be allocated as a 1147 * buffer when using search()? The minimum value is 4. The default 1148 * value is 32768. 1149 * - #MSCABD_PARAM_FIXMSZIP: If non-zero, extract() will ignore bad 1150 * checksums and recover from decompression errors in MS-ZIP 1151 * compressed folders. The default value is 0 (don't recover). 1152 * - #MSCABD_PARAM_DECOMPBUF: How many bytes should be used as an input 1153 * bit buffer by decompressors? The minimum value is 4. The default 1154 * value is 4096. 1155 * 1156 * @param self a self-referential pointer to the mscab_decompressor 1157 * instance being called 1158 * @param param the parameter to set 1159 * @param value the value to set the parameter to 1160 * @return MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS if there 1161 * is a problem with either parameter or value. 1162 * @see search(), extract() 1163 */ 1164 int (*set_param)(struct mscab_decompressor *self, 1165 int param, 1166 int value); 1167 1168 /** 1169 * Returns the error code set by the most recently called method. 1170 * 1171 * This is useful for open() and search(), which do not return an error 1172 * code directly. 1173 * 1174 * @param self a self-referential pointer to the mscab_decompressor 1175 * instance being called 1176 * @return the most recent error code 1177 * @see open(), search() 1178 */ 1179 int (*last_error)(struct mscab_decompressor *self); 1180 }; 1181 1182 /* --- support for .CHM (HTMLHelp) file format ----------------------------- */ 1183 1184 /** 1185 * A structure which represents a file to be placed in a CHM helpfile. 1186 * 1187 * A contiguous array of these structures should be passed to 1188 * mschm_compressor::generate(). The array list is terminated with an 1189 * entry whose mschmc_file::section field is set to #MSCHMC_ENDLIST, the 1190 * other fields in this entry are ignored. 1191 */ 1192 struct mschmc_file { 1193 /** One of #MSCHMC_ENDLIST, #MSCHMC_UNCOMP or #MSCHMC_MSCOMP. */ 1194 int section; 1195 1196 /** The filename of the source file that will be added to the CHM. This 1197 * is passed directly to mspack_system::open(). */ 1198 const char *filename; 1199 1200 /** The full path and filename of the file within the CHM helpfile, a 1201 * UTF-1 encoded null-terminated string. */ 1202 char *chm_filename; 1203 1204 /** The length of the file, in bytes. This will be adhered to strictly 1205 * and a read error will be issued if this many bytes cannot be read 1206 * from the real file at CHM generation time. */ 1207 off_t length; 1208 }; 1209 1210 /** 1211 * A structure which represents a section of a CHM helpfile. 1212 * 1213 * All fields are READ ONLY. 1214 * 1215 * Not used directly, but used as a generic base type for 1216 * mschmd_sec_uncompressed and mschmd_sec_mscompressed. 1217 */ 1218 struct mschmd_section { 1219 /** A pointer to the CHM helpfile that contains this section. */ 1220 struct mschmd_header *chm; 1221 1222 /** 1223 * The section ID. Either 0 for the uncompressed section 1224 * mschmd_sec_uncompressed, or 1 for the LZX compressed section 1225 * mschmd_sec_mscompressed. No other section IDs are known. 1226 */ 1227 unsigned int id; 1228 }; 1229 1230 /** 1231 * A structure which represents the uncompressed section of a CHM helpfile. 1232 * 1233 * All fields are READ ONLY. 1234 */ 1235 struct mschmd_sec_uncompressed { 1236 /** Generic section data. */ 1237 struct mschmd_section base; 1238 1239 /** The file offset of where this section begins in the CHM helpfile. */ 1240 off_t offset; 1241 }; 1242 1243 /** 1244 * A structure which represents the LZX compressed section of a CHM helpfile. 1245 * 1246 * All fields are READ ONLY. 1247 */ 1248 struct mschmd_sec_mscompressed { 1249 /** Generic section data. */ 1250 struct mschmd_section base; 1251 1252 /** A pointer to the meta-file which represents all LZX compressed data. */ 1253 struct mschmd_file *content; 1254 1255 /** A pointer to the file which contains the LZX control data. */ 1256 struct mschmd_file *control; 1257 1258 /** A pointer to the file which contains the LZX reset table. */ 1259 struct mschmd_file *rtable; 1260 1261 /** A pointer to the file which contains the LZX span information. 1262 * Available only in CHM decoder version 2 and above. 1263 */ 1264 struct mschmd_file *spaninfo; 1265 }; 1266 1267 /** 1268 * A structure which represents a CHM helpfile. 1269 * 1270 * All fields are READ ONLY. 1271 */ 1272 struct mschmd_header { 1273 /** The version of the CHM file format used in this file. */ 1274 unsigned int version; 1275 1276 /** 1277 * The "timestamp" of the CHM helpfile. 1278 * 1279 * It is the lower 32 bits of a 64-bit value representing the number of 1280 * centiseconds since 1601-01-01 00:00:00 UTC, plus 42. It is not useful 1281 * as a timestamp, but it is useful as a semi-unique ID. 1282 */ 1283 unsigned int timestamp; 1284 1285 /** 1286 * The default Language and Country ID (LCID) of the user who ran the 1287 * HTMLHelp Compiler. This is not the language of the CHM file itself. 1288 */ 1289 unsigned int language; 1290 1291 /** 1292 * The filename of the CHM helpfile. This is given by the library user 1293 * and may be in any format. 1294 */ 1295 const char *filename; 1296 1297 /** The length of the CHM helpfile, in bytes. */ 1298 off_t length; 1299 1300 /** A list of all non-system files in the CHM helpfile. */ 1301 struct mschmd_file *files; 1302 1303 /** 1304 * A list of all system files in the CHM helpfile. 1305 * 1306 * System files are files which begin with "::". They are meta-files 1307 * generated by the CHM creation process. 1308 */ 1309 struct mschmd_file *sysfiles; 1310 1311 /** The section 0 (uncompressed) data in this CHM helpfile. */ 1312 struct mschmd_sec_uncompressed sec0; 1313 1314 /** The section 1 (MSCompressed) data in this CHM helpfile. */ 1315 struct mschmd_sec_mscompressed sec1; 1316 1317 /** The file offset of the first PMGL/PMGI directory chunk. */ 1318 off_t dir_offset; 1319 1320 /** The number of PMGL/PMGI directory chunks in this CHM helpfile. */ 1321 unsigned int num_chunks; 1322 1323 /** The size of each PMGL/PMGI chunk, in bytes. */ 1324 unsigned int chunk_size; 1325 1326 /** The "density" of the quick-reference section in PMGL/PMGI chunks. */ 1327 unsigned int density; 1328 1329 /** The depth of the index tree. 1330 * 1331 * - if 1, there are no PMGI chunks, only PMGL chunks. 1332 * - if 2, there is 1 PMGI chunk. All chunk indices point to PMGL chunks. 1333 * - if 3, the root PMGI chunk points to secondary PMGI chunks, which in 1334 * turn point to PMGL chunks. 1335 * - and so on... 1336 */ 1337 unsigned int depth; 1338 1339 /** 1340 * The number of the root PMGI chunk. 1341 * 1342 * If there is no index in the CHM helpfile, this will be 0xFFFFFFFF. 1343 */ 1344 unsigned int index_root; 1345 1346 /** 1347 * The number of the first PMGL chunk. Usually zero. 1348 * Available only in CHM decoder version 2 and above. 1349 */ 1350 unsigned int first_pmgl; 1351 1352 /** 1353 * The number of the last PMGL chunk. Usually num_chunks-1. 1354 * Available only in CHM decoder version 2 and above. 1355 */ 1356 unsigned int last_pmgl; 1357 1358 /** 1359 * A cache of loaded chunks, filled in by mschm_decoder::fast_find(). 1360 * Available only in CHM decoder version 2 and above. 1361 */ 1362 unsigned char **chunk_cache; 1363 }; 1364 1365 /** 1366 * A structure which represents a file stored in a CHM helpfile. 1367 * 1368 * All fields are READ ONLY. 1369 */ 1370 struct mschmd_file { 1371 /** 1372 * A pointer to the next file in the list, or NULL if this is the final 1373 * file. 1374 */ 1375 struct mschmd_file *next; 1376 1377 /** 1378 * A pointer to the section that this file is located in. Indirectly, 1379 * it also points to the CHM helpfile the file is located in. 1380 */ 1381 struct mschmd_section *section; 1382 1383 /** The offset within the section data that this file is located at. */ 1384 off_t offset; 1385 1386 /** The length of this file, in bytes */ 1387 off_t length; 1388 1389 /** The filename of this file -- a null terminated string in UTF-8. */ 1390 char *filename; 1391 }; 1392 1393 /** mschmc_file::section value: end of CHM file list */ 1394 #define MSCHMC_ENDLIST (0) 1395 /** mschmc_file::section value: this file is in the Uncompressed section */ 1396 #define MSCHMC_UNCOMP (1) 1397 /** mschmc_file::section value: this file is in the MSCompressed section */ 1398 #define MSCHMC_MSCOMP (2) 1399 1400 /** mschm_compressor::set_param() parameter: "timestamp" header */ 1401 #define MSCHMC_PARAM_TIMESTAMP (0) 1402 /** mschm_compressor::set_param() parameter: "language" header */ 1403 #define MSCHMC_PARAM_LANGUAGE (1) 1404 /** mschm_compressor::set_param() parameter: LZX window size */ 1405 #define MSCHMC_PARAM_LZXWINDOW (2) 1406 /** mschm_compressor::set_param() parameter: intra-chunk quickref density */ 1407 #define MSCHMC_PARAM_DENSITY (3) 1408 /** mschm_compressor::set_param() parameter: whether to create indices */ 1409 #define MSCHMC_PARAM_INDEX (4) 1410 1411 /** 1412 * A compressor for .CHM (Microsoft HTMLHelp) files. 1413 * 1414 * All fields are READ ONLY. 1415 * 1416 * @see mspack_create_chm_compressor(), mspack_destroy_chm_compressor() 1417 */ 1418 struct mschm_compressor { 1419 /** 1420 * Generates a CHM help file. 1421 * 1422 * The help file will contain up to two sections, an Uncompressed 1423 * section and potentially an MSCompressed (LZX compressed) 1424 * section. 1425 * 1426 * While the contents listing of a CHM file is always in lexical order, 1427 * the file list passed in will be taken as the correct order for files 1428 * within the sections. It is in your interest to place similar files 1429 * together for better compression. 1430 * 1431 * There are two modes of generation, to use a temporary file or not to 1432 * use one. See use_temporary_file() for the behaviour of generate() in 1433 * these two different modes. 1434 * 1435 * @param self a self-referential pointer to the mschm_compressor 1436 * instance being called 1437 * @param file_list an array of mschmc_file structures, terminated 1438 * with an entry whose mschmc_file::section field is 1439 * #MSCHMC_ENDLIST. The order of the list is 1440 * preserved within each section. The length of any 1441 * mschmc_file::chm_filename string cannot exceed 1442 * roughly 4096 bytes. Each source file must be able 1443 * to supply as many bytes as given in the 1444 * mschmc_file::length field. 1445 * @param output_file the file to write the generated CHM helpfile to. 1446 * This is passed directly to mspack_system::open() 1447 * @return an error code, or MSPACK_ERR_OK if successful 1448 * @see use_temporary_file() set_param() 1449 */ 1450 int (*generate)(struct mschm_compressor *self, 1451 struct mschmc_file file_list[], 1452 const char *output_file); 1453 1454 /** 1455 * Specifies whether a temporary file is used during CHM generation. 1456 * 1457 * The CHM file format includes data about the compressed section (such 1458 * as its overall size) that is stored in the output CHM file prior to 1459 * the compressed section itself. This unavoidably requires that the 1460 * compressed section has to be generated, before these details can be 1461 * set. There are several ways this can be handled. Firstly, the 1462 * compressed section could be generated entirely in memory before 1463 * writing any of the output CHM file. This approach is not used in 1464 * libmspack, as the compressed section can exceed the addressable 1465 * memory space on most architectures. 1466 * 1467 * libmspack has two options, either to write these unknowable sections 1468 * with blank data, generate the compressed section, then re-open the 1469 * output file for update once the compressed section has been 1470 * completed, or to write the compressed section to a temporary file, 1471 * then write the entire output file at once, performing a simple 1472 * file-to-file copy for the compressed section. 1473 * 1474 * The simple solution of buffering the entire compressed section in 1475 * memory can still be used, if desired. As the temporary file's 1476 * filename is passed directly to mspack_system::open(), it is possible 1477 * for a custom mspack_system implementation to hold this file in memory, 1478 * without writing to a disk. 1479 * 1480 * If a temporary file is set, generate() performs the following 1481 * sequence of events: the temporary file is opened for writing, the 1482 * compression algorithm writes to the temporary file, the temporary 1483 * file is closed. Then the output file is opened for writing and the 1484 * temporary file is re-opened for reading. The output file is written 1485 * and the temporary file is read from. Both files are then closed. The 1486 * temporary file itself is not deleted. If that is desired, the 1487 * temporary file should be deleted after the completion of generate(), 1488 * if it exists. 1489 * 1490 * If a temporary file is set not to be used, generate() performs the 1491 * following sequence of events: the output file is opened for writing, 1492 * then it is written and closed. The output file is then re-opened for 1493 * update, the appropriate sections are seek()ed to and re-written, then 1494 * the output file is closed. 1495 * 1496 * @param self a self-referential pointer to the 1497 * mschm_compressor instance being called 1498 * @param use_temp_file non-zero if the temporary file should be used, 1499 * zero if the temporary file should not be used. 1500 * @param temp_file a file to temporarily write compressed data to, 1501 * before opening it for reading and copying the 1502 * contents to the output file. This is passed 1503 * directly to mspack_system::open(). 1504 * @return an error code, or MSPACK_ERR_OK if successful 1505 * @see generate() 1506 */ 1507 int (*use_temporary_file)(struct mschm_compressor *self, 1508 int use_temp_file, 1509 const char *temp_file); 1510 /** 1511 * Sets a CHM compression engine parameter. 1512 * 1513 * The following parameters are defined: 1514 1515 * - #MSCHMC_PARAM_TIMESTAMP: Sets the "timestamp" of the CHM file 1516 * generated. This is not a timestamp, see mschmd_header::timestamp 1517 * for a description. If this timestamp is 0, generate() will use its 1518 * own algorithm for making a unique ID, based on the lengths and 1519 * names of files in the CHM itself. Defaults to 0, any value between 1520 * 0 and (2^32)-1 is valid. 1521 * - #MSCHMC_PARAM_LANGUAGE: Sets the "language" of the CHM file 1522 * generated. This is not the language used in the CHM file, but the 1523 * language setting of the user who ran the HTMLHelp compiler. It 1524 * defaults to 0x0409. The valid range is between 0x0000 and 0x7F7F. 1525 * - #MSCHMC_PARAM_LZXWINDOW: Sets the size of the LZX history window, 1526 * which is also the interval at which the compressed data stream can be 1527 * randomly accessed. The value is not a size in bytes, but a power of 1528 * two. The default value is 16 (which makes the window 2^16 bytes, or 1529 * 64 kilobytes), the valid range is from 15 (32 kilobytes) to 21 (2 1530 * megabytes). 1531 * - #MSCHMC_PARAM_DENSITY: Sets the "density" of quick reference 1532 * entries stored at the end of directory listing chunk. Each chunk is 1533 * 4096 bytes in size, and contains as many file entries as there is 1534 * room for. At the other end of the chunk, a list of "quick reference" 1535 * pointers is included. The offset of every 'N'th file entry is given a 1536 * quick reference, where N = (2^density) + 1. The default density is 1537 * 2. The smallest density is 0 (N=2), the maximum is 10 (N=1025). As 1538 * each file entry requires at least 5 bytes, the maximum number of 1539 * entries in a single chunk is roughly 800, so the maximum value 10 1540 * can be used to indicate there are no quickrefs at all. 1541 * - #MSCHMC_PARAM_INDEX: Sets whether or not to include quick lookup 1542 * index chunk(s), in addition to normal directory listing chunks. A 1543 * value of zero means no index chunks will be created, a non-zero value 1544 * means index chunks will be created. The default is zero, "don't 1545 * create an index". 1546 * 1547 * @param self a self-referential pointer to the mschm_compressor 1548 * instance being called 1549 * @param param the parameter to set 1550 * @param value the value to set the parameter to 1551 * @return MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS if there 1552 * is a problem with either parameter or value. 1553 * @see generate() 1554 */ 1555 int (*set_param)(struct mschm_compressor *self, 1556 int param, 1557 int value); 1558 1559 /** 1560 * Returns the error code set by the most recently called method. 1561 * 1562 * @param self a self-referential pointer to the mschm_compressor 1563 * instance being called 1564 * @return the most recent error code 1565 * @see set_param(), generate() 1566 */ 1567 int (*last_error)(struct mschm_compressor *self); 1568 }; 1569 1570 /** 1571 * A decompressor for .CHM (Microsoft HTMLHelp) files 1572 * 1573 * All fields are READ ONLY. 1574 * 1575 * @see mspack_create_chm_decompressor(), mspack_destroy_chm_decompressor() 1576 */ 1577 struct mschm_decompressor { 1578 /** 1579 * Opens a CHM helpfile and reads its contents. 1580 * 1581 * If the file opened is a valid CHM helpfile, all headers will be read 1582 * and a mschmd_header structure will be returned, with a full list of 1583 * files. 1584 * 1585 * In the case of an error occuring, NULL is returned and the error code 1586 * is available from last_error(). 1587 * 1588 * The filename pointer should be considered "in use" until close() is 1589 * called on the CHM helpfile. 1590 * 1591 * @param self a self-referential pointer to the mschm_decompressor 1592 * instance being called 1593 * @param filename the filename of the CHM helpfile. This is passed 1594 * directly to mspack_system::open(). 1595 * @return a pointer to a mschmd_header structure, or NULL on failure 1596 * @see close() 1597 */ 1598 struct mschmd_header *(*open)(struct mschm_decompressor *self, 1599 const char *filename); 1600 1601 /** 1602 * Closes a previously opened CHM helpfile. 1603 * 1604 * This closes a CHM helpfile, frees the mschmd_header and all 1605 * mschmd_file structures associated with it (if any). This works on 1606 * both helpfiles opened with open() and helpfiles opened with 1607 * fast_open(). 1608 * 1609 * The CHM header pointer is now invalid and cannot be used again. All 1610 * mschmd_file pointers referencing that CHM are also now invalid, and 1611 * cannot be used again. 1612 * 1613 * @param self a self-referential pointer to the mschm_decompressor 1614 * instance being called 1615 * @param chm the CHM helpfile to close 1616 * @see open(), fast_open() 1617 */ 1618 void (*close)(struct mschm_decompressor *self, 1619 struct mschmd_header *chm); 1620 1621 /** 1622 * Extracts a file from a CHM helpfile. 1623 * 1624 * This extracts a file from a CHM helpfile and writes it to the given 1625 * filename. The filename of the file, mscabd_file::filename, is not 1626 * used by extract(), but can be used by the caller as a guide for 1627 * constructing an appropriate filename. 1628 * 1629 * This method works both with files found in the mschmd_header::files 1630 * and mschmd_header::sysfiles list and mschmd_file structures generated 1631 * on the fly by fast_find(). 1632 * 1633 * @param self a self-referential pointer to the mschm_decompressor 1634 * instance being called 1635 * @param file the file to be decompressed 1636 * @param filename the filename of the file being written to 1637 * @return an error code, or MSPACK_ERR_OK if successful 1638 */ 1639 int (*extract)(struct mschm_decompressor *self, 1640 struct mschmd_file *file, 1641 const char *filename); 1642 1643 /** 1644 * Returns the error code set by the most recently called method. 1645 * 1646 * This is useful for open() and fast_open(), which do not return an 1647 * error code directly. 1648 * 1649 * @param self a self-referential pointer to the mschm_decompressor 1650 * instance being called 1651 * @return the most recent error code 1652 * @see open(), extract() 1653 */ 1654 int (*last_error)(struct mschm_decompressor *self); 1655 1656 /** 1657 * Opens a CHM helpfile quickly. 1658 * 1659 * If the file opened is a valid CHM helpfile, only essential headers 1660 * will be read. A mschmd_header structure will be still be returned, as 1661 * with open(), but the mschmd_header::files field will be NULL. No 1662 * files details will be automatically read. The fast_find() method 1663 * must be used to obtain file details. 1664 * 1665 * In the case of an error occuring, NULL is returned and the error code 1666 * is available from last_error(). 1667 * 1668 * The filename pointer should be considered "in use" until close() is 1669 * called on the CHM helpfile. 1670 * 1671 * @param self a self-referential pointer to the mschm_decompressor 1672 * instance being called 1673 * @param filename the filename of the CHM helpfile. This is passed 1674 * directly to mspack_system::open(). 1675 * @return a pointer to a mschmd_header structure, or NULL on failure 1676 * @see open(), close(), fast_find(), extract() 1677 */ 1678 struct mschmd_header *(*fast_open)(struct mschm_decompressor *self, 1679 const char *filename); 1680 1681 /** 1682 * Finds file details quickly. 1683 * 1684 * Instead of reading all CHM helpfile headers and building a list of 1685 * files, fast_open() and fast_find() are intended for finding file 1686 * details only when they are needed. The CHM file format includes an 1687 * on-disk file index to allow this. 1688 * 1689 * Given a case-sensitive filename, fast_find() will search the on-disk 1690 * index for that file. 1691 * 1692 * If the file was found, the caller-provided mschmd_file structure will 1693 * be filled out like so: 1694 * - section: the correct value for the found file 1695 * - offset: the correct value for the found file 1696 * - length: the correct value for the found file 1697 * - all other structure elements: NULL or 0 1698 * 1699 * If the file was not found, MSPACK_ERR_OK will still be returned as the 1700 * result, but the caller-provided structure will be filled out like so: 1701 * - section: NULL 1702 * - offset: 0 1703 * - length: 0 1704 * - all other structure elements: NULL or 0 1705 * 1706 * This method is intended to be used in conjunction with CHM helpfiles 1707 * opened with fast_open(), but it also works with helpfiles opened 1708 * using the regular open(). 1709 * 1710 * @param self a self-referential pointer to the mschm_decompressor 1711 * instance being called 1712 * @param chm the CHM helpfile to search for the file 1713 * @param filename the filename of the file to search for 1714 * @param f_ptr a pointer to a caller-provded mschmd_file structure 1715 * @param f_size <tt>sizeof(struct mschmd_file)</tt> 1716 * @return an error code, or MSPACK_ERR_OK if successful 1717 * @see open(), close(), fast_find(), extract() 1718 */ 1719 int (*fast_find)(struct mschm_decompressor *self, 1720 struct mschmd_header *chm, 1721 const char *filename, 1722 struct mschmd_file *f_ptr, 1723 int f_size); 1724 }; 1725 1726 /* --- support for .LIT (EBook) file format -------------------------------- */ 1727 1728 /** TODO */ 1729 struct mslit_compressor { 1730 int dummy; 1731 }; 1732 1733 /** TODO */ 1734 struct mslit_decompressor { 1735 int dummy; 1736 }; 1737 1738 1739 /* --- support for .HLP (MS Help) file format ------------------------------ */ 1740 1741 /** TODO */ 1742 struct mshlp_compressor { 1743 int dummy; 1744 }; 1745 1746 /** TODO */ 1747 struct mshlp_decompressor { 1748 int dummy; 1749 }; 1750 1751 1752 /* --- support for SZDD file format ---------------------------------------- */ 1753 1754 /** msszdd_compressor::set_param() parameter: the missing character */ 1755 #define MSSZDDC_PARAM_MISSINGCHAR (0) 1756 1757 /** msszddd_header::format value - a regular SZDD file */ 1758 #define MSSZDD_FMT_NORMAL (0) 1759 1760 /** msszddd_header::format value - a special QBasic SZDD file */ 1761 #define MSSZDD_FMT_QBASIC (1) 1762 1763 /** 1764 * A structure which represents an SZDD compressed file. 1765 * 1766 * All fields are READ ONLY. 1767 */ 1768 struct msszddd_header { 1769 /** The file format; either #MSSZDD_FMT_NORMAL or #MSSZDD_FMT_QBASIC */ 1770 int format; 1771 1772 /** The amount of data in the SZDD file once uncompressed. */ 1773 off_t length; 1774 1775 /** 1776 * The last character in the filename, traditionally replaced with an 1777 * underscore to show the file is compressed. The null character is used 1778 * to show that this character has not been stored (e.g. because the 1779 * filename is not known). Generally, only characters that may appear in 1780 * an MS-DOS filename (except ".") are valid. 1781 */ 1782 char missing_char; 1783 }; 1784 1785 /** 1786 * A compressor for the SZDD file format. 1787 * 1788 * All fields are READ ONLY. 1789 * 1790 * @see mspack_create_szdd_compressor(), mspack_destroy_szdd_compressor() 1791 */ 1792 struct msszdd_compressor { 1793 /** 1794 * Reads an input file and creates a compressed output file in the 1795 * SZDD compressed file format. The SZDD compression format is quick 1796 * but gives poor compression. It is possible for the compressed output 1797 * file to be larger than the input file. 1798 * 1799 * Conventionally, SZDD compressed files have the final character in 1800 * their filename replaced with an underscore, to show they are 1801 * compressed. The missing character is stored in the compressed file 1802 * itself. This is due to the restricted filename conventions of MS-DOS, 1803 * most operating systems, such as UNIX, simply append another file 1804 * extension to the existing filename. As mspack does not deal with 1805 * filenames, this is left up to you. If you wish to set the missing 1806 * character stored in the file header, use set_param() with the 1807 * #MSSZDDC_PARAM_MISSINGCHAR parameter. 1808 * 1809 * "Stream" compression (where the length of the input data is not 1810 * known) is not possible. The length of the input data is stored in the 1811 * header of the SZDD file and must therefore be known before any data 1812 * is compressed. Due to technical limitations of the file format, the 1813 * maximum size of uncompressed file that will be accepted is 2147483647 1814 * bytes. 1815 * 1816 * @param self a self-referential pointer to the msszdd_compressor 1817 * instance being called 1818 * @param input the name of the file to compressed. This is passed 1819 * passed directly to mspack_system::open() 1820 * @param output the name of the file to write compressed data to. 1821 * This is passed directly to mspack_system::open(). 1822 * @param length the length of the uncompressed file, or -1 to indicate 1823 * that this should be determined automatically by using 1824 * mspack_system::seek() on the input file. 1825 * @return an error code, or MSPACK_ERR_OK if successful 1826 * @see set_param() 1827 */ 1828 int (*compress)(struct msszdd_compressor *self, 1829 const char *input, 1830 const char *output, 1831 off_t length); 1832 1833 /** 1834 * Sets an SZDD compression engine parameter. 1835 * 1836 * The following parameters are defined: 1837 1838 * - #MSSZDDC_PARAM_CHARACTER: the "missing character", the last character 1839 * in the uncompressed file's filename, which is traditionally replaced 1840 * with an underscore to show the file is compressed. Traditionally, 1841 * this can only be a character that is a valid part of an MS-DOS, 1842 * filename, but libmspack permits any character between 0x00 and 0xFF 1843 * to be stored. 0x00 is the default, and it represents "no character 1844 * stored". 1845 * 1846 * @param self a self-referential pointer to the msszdd_compressor 1847 * instance being called 1848 * @param param the parameter to set 1849 * @param value the value to set the parameter to 1850 * @return MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS if there 1851 * is a problem with either parameter or value. 1852 * @see compress() 1853 */ 1854 int (*set_param)(struct msszdd_compressor *self, 1855 int param, 1856 int value); 1857 1858 /** 1859 * Returns the error code set by the most recently called method. 1860 * 1861 * @param self a self-referential pointer to the msszdd_compressor 1862 * instance being called 1863 * @return the most recent error code 1864 * @see compress() 1865 */ 1866 int (*last_error)(struct mschm_decompressor *self); 1867 }; 1868 1869 /** 1870 * A decompressor for SZDD compressed files. 1871 * 1872 * All fields are READ ONLY. 1873 * 1874 * @see mspack_create_szdd_decompressor(), mspack_destroy_szdd_decompressor() 1875 */ 1876 struct msszdd_decompressor { 1877 /** 1878 * Opens a SZDD file and reads the header. 1879 * 1880 * If the file opened is a valid SZDD file, all headers will be read and 1881 * a msszddd_header structure will be returned. 1882 * 1883 * In the case of an error occuring, NULL is returned and the error code 1884 * is available from last_error(). 1885 * 1886 * The filename pointer should be considered "in use" until close() is 1887 * called on the SZDD file. 1888 * 1889 * @param self a self-referential pointer to the msszdd_decompressor 1890 * instance being called 1891 * @param filename the filename of the SZDD compressed file. This is 1892 * passed directly to mspack_system::open(). 1893 * @return a pointer to a msszddd_header structure, or NULL on failure 1894 * @see close() 1895 */ 1896 struct msszddd_header *(*open)(struct msszdd_decompressor *self, 1897 const char *filename); 1898 1899 /** 1900 * Closes a previously opened SZDD file. 1901 * 1902 * This closes a SZDD file and frees the msszddd_header associated with 1903 * it. 1904 * 1905 * The SZDD header pointer is now invalid and cannot be used again. 1906 * 1907 * @param self a self-referential pointer to the msszdd_decompressor 1908 * instance being called 1909 * @param szdd the SZDD file to close 1910 * @see open() 1911 */ 1912 void (*close)(struct msszdd_decompressor *self, 1913 struct msszddd_header *szdd); 1914 1915 /** 1916 * Extracts the compressed data from a SZDD file. 1917 * 1918 * This decompresses the compressed SZDD data stream and writes it to 1919 * an output file. 1920 * 1921 * @param self a self-referential pointer to the msszdd_decompressor 1922 * instance being called 1923 * @param szdd the SZDD file to extract data from 1924 * @param filename the filename to write the decompressed data to. This 1925 * is passed directly to mspack_system::open(). 1926 * @return an error code, or MSPACK_ERR_OK if successful 1927 */ 1928 int (*extract)(struct msszdd_decompressor *self, 1929 struct msszddd_header *szdd, 1930 const char *filename); 1931 1932 /** 1933 * Decompresses an SZDD file to an output file in one step. 1934 * 1935 * This opens an SZDD file as input, reads the header, then decompresses 1936 * the compressed data immediately to an output file, finally closing 1937 * both the input and output file. It is more convenient to use than 1938 * open() then extract() then close(), if you do not need to know the 1939 * SZDD output size or missing character. 1940 * 1941 * @param self a self-referential pointer to the msszdd_decompressor 1942 * instance being called 1943 * @param input the filename of the input SZDD file. This is passed 1944 * directly to mspack_system::open(). 1945 * @param output the filename to write the decompressed data to. This 1946 * is passed directly to mspack_system::open(). 1947 * @return an error code, or MSPACK_ERR_OK if successful 1948 */ 1949 int (*decompress)(struct msszdd_decompressor *self, 1950 const char *input, 1951 const char *output); 1952 1953 /** 1954 * Returns the error code set by the most recently called method. 1955 * 1956 * This is useful for open() which does not return an 1957 * error code directly. 1958 * 1959 * @param self a self-referential pointer to the msszdd_decompressor 1960 * instance being called 1961 * @return the most recent error code 1962 * @see open(), extract(), decompress() 1963 */ 1964 int (*last_error)(struct msszdd_decompressor *self); 1965 }; 1966 1967 /* --- support for KWAJ file format ---------------------------------------- */ 1968 1969 /** mskwaj_compressor::set_param() parameter: compression type */ 1970 #define MSKWAJC_PARAM_COMP_TYPE (0) 1971 1972 /** mskwaj_compressor::set_param() parameter: include the length of the 1973 * uncompressed file in the header? 1974 */ 1975 #define MSKWAJC_PARAM_INCLUDE_LENGTH (1) 1976 1977 /** KWAJ compression type: no compression. */ 1978 #define MSKWAJ_COMP_NONE (0) 1979 /** KWAJ compression type: no compression, 0xFF XOR "encryption". */ 1980 #define MSKWAJ_COMP_XOR (1) 1981 /** KWAJ compression type: LZSS (same method as SZDD) */ 1982 #define MSKWAJ_COMP_SZDD (2) 1983 /** KWAJ compression type: LZ+Huffman compression */ 1984 #define MSKWAJ_COMP_LZH (3) 1985 /** KWAJ compression type: MSZIP */ 1986 #define MSKWAJ_COMP_MSZIP (4) 1987 1988 /** KWAJ optional header flag: decompressed file length is included */ 1989 #define MSKWAJ_HDR_HASLENGTH (0x01) 1990 1991 /** KWAJ optional header flag: unknown 2-byte structure is included */ 1992 #define MSKWAJ_HDR_HASUNKNOWN1 (0x02) 1993 1994 /** KWAJ optional header flag: unknown multi-sized structure is included */ 1995 #define MSKWAJ_HDR_HASUNKNOWN2 (0x04) 1996 1997 /** KWAJ optional header flag: file name (no extension) is included */ 1998 #define MSKWAJ_HDR_HASFILENAME (0x08) 1999 2000 /** KWAJ optional header flag: file extension is included */ 2001 #define MSKWAJ_HDR_HASFILEEXT (0x10) 2002 2003 /** KWAJ optional header flag: extra text is included */ 2004 #define MSKWAJ_HDR_HASEXTRATEXT (0x20) 2005 2006 /** 2007 * A structure which represents an KWAJ compressed file. 2008 * 2009 * All fields are READ ONLY. 2010 */ 2011 struct mskwajd_header { 2012 /** The compression type; should be one of #MSKWAJ_COMP_NONE, 2013 * #MSKWAJ_COMP_XOR, #MSKWAJ_COMP_SZDD or #MSKWAJ_COMP_LZH 2014 */ 2015 unsigned short comp_type; 2016 2017 /** The offset in the file where the compressed data stream begins */ 2018 off_t data_offset; 2019 2020 /** Flags indicating which optional headers were included. */ 2021 int headers; 2022 2023 /** The amount of uncompressed data in the file, or 0 if not present. */ 2024 off_t length; 2025 2026 /** output filename, or NULL if not present */ 2027 char *filename; 2028 2029 /** extra uncompressed data (usually text) in the header. 2030 * This data can contain nulls so use extra_length to get the size. 2031 */ 2032 char *extra; 2033 2034 /** length of extra uncompressed data in the header */ 2035 unsigned short extra_length; 2036 }; 2037 2038 /** 2039 * A compressor for the KWAJ file format. 2040 * 2041 * All fields are READ ONLY. 2042 * 2043 * @see mspack_create_kwaj_compressor(), mspack_destroy_kwaj_compressor() 2044 */ 2045 struct mskwaj_compressor { 2046 /** 2047 * Reads an input file and creates a compressed output file in the 2048 * KWAJ compressed file format. The KWAJ compression format is quick 2049 * but gives poor compression. It is possible for the compressed output 2050 * file to be larger than the input file. 2051 * 2052 * @param self a self-referential pointer to the mskwaj_compressor 2053 * instance being called 2054 * @param input the name of the file to compressed. This is passed 2055 * passed directly to mspack_system::open() 2056 * @param output the name of the file to write compressed data to. 2057 * This is passed directly to mspack_system::open(). 2058 * @param length the length of the uncompressed file, or -1 to indicate 2059 * that this should be determined automatically by using 2060 * mspack_system::seek() on the input file. 2061 * @return an error code, or MSPACK_ERR_OK if successful 2062 * @see set_param() 2063 */ 2064 int (*compress)(struct mskwaj_compressor *self, 2065 const char *input, 2066 const char *output, 2067 off_t length); 2068 2069 /** 2070 * Sets an KWAJ compression engine parameter. 2071 * 2072 * The following parameters are defined: 2073 * 2074 * - #MSKWAJC_PARAM_COMP_TYPE: the compression method to use. Must 2075 * be one of #MSKWAJC_COMP_NONE, #MSKWAJC_COMP_XOR, #MSKWAJ_COMP_SZDD 2076 * or #MSKWAJ_COMP_LZH. The default is #MSKWAJ_COMP_LZH. 2077 * 2078 * - #MSKWAJC_PARAM_INCLUDE_LENGTH: a boolean; should the compressed 2079 * output file should include the uncompressed length of the input 2080 * file in the header? This adds 4 bytes to the size of the output 2081 * file. A value of zero says "no", non-zero says "yes". The default 2082 * is "no". 2083 * 2084 * @param self a self-referential pointer to the mskwaj_compressor 2085 * instance being called 2086 * @param param the parameter to set 2087 * @param value the value to set the parameter to 2088 * @return MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS if there 2089 * is a problem with either parameter or value. 2090 * @see generate() 2091 */ 2092 int (*set_param)(struct mskwaj_compressor *self, 2093 int param, 2094 int value); 2095 2096 2097 /** 2098 * Sets the original filename of the file before compression, 2099 * which will be stored in the header of the output file. 2100 * 2101 * The filename should be a null-terminated string, it must be an 2102 * MS-DOS "8.3" type filename (up to 8 bytes for the filename, then 2103 * optionally a "." and up to 3 bytes for a filename extension). 2104 * 2105 * If NULL is passed as the filename, no filename is included in the 2106 * header. This is the default. 2107 * 2108 * @param self a self-referential pointer to the mskwaj_compressor 2109 * instance being called 2110 * @param filename the original filename to use 2111 * @return MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS if the 2112 * filename is too long 2113 */ 2114 int (*set_filename)(struct mskwaj_compressor *self, 2115 const char *filename); 2116 2117 /** 2118 * Sets arbitrary data that will be stored in the header of the 2119 * output file, uncompressed. It can be up to roughly 64 kilobytes, 2120 * as the overall size of the header must not exceed 65535 bytes. 2121 * The data can contain null bytes if desired. 2122 * 2123 * If NULL is passed as the data pointer, or zero is passed as the 2124 * length, no extra data is included in the header. This is the 2125 * default. 2126 * 2127 * @param self a self-referential pointer to the mskwaj_compressor 2128 * instance being called 2129 * @param data a pointer to the data to be stored in the header 2130 * @param bytes the length of the data in bytes 2131 * @return MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS extra data 2132 * is too long 2133 */ 2134 int (*set_extra_data)(struct mskwaj_compressor *self, 2135 void *data, 2136 size_t bytes); 2137 2138 /** 2139 * Returns the error code set by the most recently called method. 2140 * 2141 * @param self a self-referential pointer to the mskwaj_compressor 2142 * instance being called 2143 * @return the most recent error code 2144 * @see compress() 2145 */ 2146 int (*last_error)(struct mschm_decompressor *self); 2147 }; 2148 2149 /** 2150 * A decompressor for KWAJ compressed files. 2151 * 2152 * All fields are READ ONLY. 2153 * 2154 * @see mspack_create_kwaj_decompressor(), mspack_destroy_kwaj_decompressor() 2155 */ 2156 struct mskwaj_decompressor { 2157 /** 2158 * Opens a KWAJ file and reads the header. 2159 * 2160 * If the file opened is a valid KWAJ file, all headers will be read and 2161 * a mskwajd_header structure will be returned. 2162 * 2163 * In the case of an error occuring, NULL is returned and the error code 2164 * is available from last_error(). 2165 * 2166 * The filename pointer should be considered "in use" until close() is 2167 * called on the KWAJ file. 2168 * 2169 * @param self a self-referential pointer to the mskwaj_decompressor 2170 * instance being called 2171 * @param filename the filename of the KWAJ compressed file. This is 2172 * passed directly to mspack_system::open(). 2173 * @return a pointer to a mskwajd_header structure, or NULL on failure 2174 * @see close() 2175 */ 2176 struct mskwajd_header *(*open)(struct mskwaj_decompressor *self, 2177 const char *filename); 2178 2179 /** 2180 * Closes a previously opened KWAJ file. 2181 * 2182 * This closes a KWAJ file and frees the mskwajd_header associated 2183 * with it. The KWAJ header pointer is now invalid and cannot be 2184 * used again. 2185 * 2186 * @param self a self-referential pointer to the mskwaj_decompressor 2187 * instance being called 2188 * @param kwaj the KWAJ file to close 2189 * @see open() 2190 */ 2191 void (*close)(struct mskwaj_decompressor *self, 2192 struct mskwajd_header *kwaj); 2193 2194 /** 2195 * Extracts the compressed data from a KWAJ file. 2196 * 2197 * This decompresses the compressed KWAJ data stream and writes it to 2198 * an output file. 2199 * 2200 * @param self a self-referential pointer to the mskwaj_decompressor 2201 * instance being called 2202 * @param kwaj the KWAJ file to extract data from 2203 * @param filename the filename to write the decompressed data to. This 2204 * is passed directly to mspack_system::open(). 2205 * @return an error code, or MSPACK_ERR_OK if successful 2206 */ 2207 int (*extract)(struct mskwaj_decompressor *self, 2208 struct mskwajd_header *kwaj, 2209 const char *filename); 2210 2211 /** 2212 * Decompresses an KWAJ file to an output file in one step. 2213 * 2214 * This opens an KWAJ file as input, reads the header, then decompresses 2215 * the compressed data immediately to an output file, finally closing 2216 * both the input and output file. It is more convenient to use than 2217 * open() then extract() then close(), if you do not need to know the 2218 * KWAJ output size or output filename. 2219 * 2220 * @param self a self-referential pointer to the mskwaj_decompressor 2221 * instance being called 2222 * @param input the filename of the input KWAJ file. This is passed 2223 * directly to mspack_system::open(). 2224 * @param output the filename to write the decompressed data to. This 2225 * is passed directly to mspack_system::open(). 2226 * @return an error code, or MSPACK_ERR_OK if successful 2227 */ 2228 int (*decompress)(struct mskwaj_decompressor *self, 2229 const char *input, 2230 const char *output); 2231 2232 /** 2233 * Returns the error code set by the most recently called method. 2234 * 2235 * This is useful for open() which does not return an 2236 * error code directly. 2237 * 2238 * @param self a self-referential pointer to the mskwaj_decompressor 2239 * instance being called 2240 * @return the most recent error code 2241 * @see open(), search() 2242 */ 2243 int (*last_error)(struct mskwaj_decompressor *self); 2244 }; 2245 2246 /* --- support for .LZX (Offline Address Book) file format ----------------- */ 2247 2248 /** 2249 * A compressor for the Offline Address Book (OAB) format. 2250 * 2251 * All fields are READ ONLY. 2252 * 2253 * @see mspack_create_oab_compressor(), mspack_destroy_oab_compressor() 2254 */ 2255 struct msoab_compressor { 2256 /** 2257 * Compress a full OAB file. 2258 * 2259 * The input file will be read and the compressed contents written to the 2260 * output file. 2261 * 2262 * @param self a self-referential pointer to the msoab_decompressor 2263 * instance being called 2264 * @param input the filename of the input file. This is passed 2265 * directly to mspack_system::open(). 2266 * @param output the filename of the output file. This is passed 2267 * directly to mspack_system::open(). 2268 * @return an error code, or MSPACK_ERR_OK if successful 2269 */ 2270 int (*compress) (struct msoab_compressor *self, 2271 const char *input, 2272 const char *output); 2273 2274 /** 2275 * Generate a compressed incremental OAB patch file. 2276 * 2277 * The two uncompressed files "input" and "base" will be read, and an 2278 * incremental patch to generate "input" from "base" will be written to 2279 * the output file. 2280 * 2281 * @param self a self-referential pointer to the msoab_compressor 2282 * instance being called 2283 * @param input the filename of the input file containing the new 2284 * version of its contents. This is passed directly 2285 * to mspack_system::open(). 2286 * @param base the filename of the original base file containing 2287 * the old version of its contents, against which the 2288 * incremental patch shall generated. This is passed 2289 * directly to mspack_system::open(). 2290 * @param output the filename of the output file. This is passed 2291 * directly to mspack_system::open(). 2292 * @return an error code, or MSPACK_ERR_OK if successful 2293 */ 2294 int (*compress_incremental) (struct msoab_compressor *self, 2295 const char *input, 2296 const char *base, 2297 const char *output); 2298 }; 2299 2300 /** 2301 * A decompressor for .LZX (Offline Address Book) files 2302 * 2303 * All fields are READ ONLY. 2304 * 2305 * @see mspack_create_oab_decompressor(), mspack_destroy_oab_decompressor() 2306 */ 2307 struct msoab_decompressor { 2308 /** 2309 * Decompresses a full Offline Address Book file. 2310 * 2311 * If the input file is a valid compressed Offline Address Book file, 2312 * it will be read and the decompressed contents will be written to 2313 * the output file. 2314 * 2315 * @param self a self-referential pointer to the msoab_decompressor 2316 * instance being called 2317 * @param input the filename of the input file. This is passed 2318 * directly to mspack_system::open(). 2319 * @param output the filename of the output file. This is passed 2320 * directly to mspack_system::open(). 2321 * @return an error code, or MSPACK_ERR_OK if successful 2322 */ 2323 int (*decompress) (struct msoab_decompressor *self, 2324 const char *input, 2325 const char *output); 2326 2327 /** 2328 * Decompresses an Offline Address Book with an incremental patch file. 2329 * 2330 * This requires both a full UNCOMPRESSED Offline Address Book file to 2331 * act as the "base", and a compressed incremental patch file as input. 2332 * If the input file is valid, it will be decompressed with reference to 2333 * the base file, and the decompressed contents will be written to the 2334 * output file. 2335 * 2336 * There is no way to tell what the right base file is for the given 2337 * incremental patch, but if you get it wrong, this will usually result 2338 * in incorrect data being decompressed, which will then fail a checksum 2339 * test. 2340 * 2341 * @param self a self-referential pointer to the msoab_decompressor 2342 * instance being called 2343 * @param input the filename of the input file. This is passed 2344 * directly to mspack_system::open(). 2345 * @param base the filename of the base file to which the 2346 * incremental patch shall be applied. This is passed 2347 * directly to mspack_system::open(). 2348 * @param output the filename of the output file. This is passed 2349 * directly to mspack_system::open(). 2350 * @return an error code, or MSPACK_ERR_OK if successful 2351 */ 2352 int (*decompress_incremental) (struct msoab_decompressor *self, 2353 const char *input, 2354 const char *base, 2355 const char *output); 2356 2357 /** 2358 * Sets an OAB decompression engine parameter. Available only in OAB 2359 * decompressor version 2 and above. 2360 * 2361 * - #MSOABD_PARAM_DECOMPBUF: How many bytes should be used as an input 2362 * buffer by decompressors? The minimum value is 16. The default value 2363 * is 4096. 2364 * 2365 * @param self a self-referential pointer to the msoab_decompressor 2366 * instance being called 2367 * @param param the parameter to set 2368 * @param value the value to set the parameter to 2369 * @return MSPACK_ERR_OK if all is OK, or MSPACK_ERR_ARGS if there 2370 * is a problem with either parameter or value. 2371 */ 2372 int (*set_param)(struct msoab_decompressor *self, 2373 int param, 2374 int value); 2375 2376 }; 2377 2378 /** msoab_decompressor::set_param() parameter: size of decompression buffer */ 2379 #define MSOABD_PARAM_DECOMPBUF (0) 2380 2381 #ifdef __cplusplus 2382 } 2383 #endif 2384 2385 #endif 2386