From: Eric Biggers Date: Sat, 14 Dec 2013 17:18:32 +0000 (-0600) Subject: update; add lzms_decompress() stub X-Git-Tag: v1.6.0~144 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=3ffb2cde078ae8f62d542ab89166e1059c13d758 update; add lzms_decompress() stub --- diff --git a/Makefile.am b/Makefile.am index 15b6eacc..223f884e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -33,6 +33,7 @@ libwim_la_SOURCES = \ src/integrity.c \ src/join.c \ src/lookup_table.c \ + src/lzms-decompress.c \ src/lz77.c \ src/divsufsort/divsufsort.c \ src/divsufsort/divsufsort.h \ @@ -77,6 +78,7 @@ libwim_la_SOURCES = \ include/wimlib/integrity.h \ include/wimlib/list.h \ include/wimlib/lookup_table.h \ + include/wimlib/lzms.h \ include/wimlib/lzx.h \ include/wimlib/metadata.h \ include/wimlib/paths.h \ diff --git a/include/wimlib/lookup_table.h b/include/wimlib/lookup_table.h index a6bed894..a22ed3d1 100644 --- a/include/wimlib/lookup_table.h +++ b/include/wimlib/lookup_table.h @@ -115,10 +115,10 @@ struct wim_lookup_table_entry { struct hlist_node hash_list; /* Uncompressed size of the stream. */ - u64 size : 56; + u64 size; /* Stream flags (WIM_RESHDR_FLAG_*). */ - u64 flags : 8; + u16 flags : 8; /* One of the `enum resource_location' values documented above. */ u16 resource_location : 5; diff --git a/include/wimlib/resource.h b/include/wimlib/resource.h index a717e494..8e781c2e 100644 --- a/include/wimlib/resource.h +++ b/include/wimlib/resource.h @@ -131,7 +131,7 @@ extern void wim_res_spec_to_hdr(const struct wim_resource_spec *rspec, struct wim_reshdr *reshdr); -extern void +extern int get_wim_reshdr(const struct wim_reshdr_disk *disk_reshdr, struct wim_reshdr *reshdr); @@ -160,40 +160,40 @@ read_partial_wim_resource(const struct wim_lookup_table_entry *lte, int flags, u64 offset); extern int -read_partial_wim_resource_into_buf(const struct wim_lookup_table_entry *lte, - size_t size, u64 offset, void *buf); +read_partial_wim_stream_into_buf(const struct wim_lookup_table_entry *lte, + size_t size, u64 offset, void *buf); extern int -read_full_resource_into_buf(const struct wim_lookup_table_entry *lte, void *buf); +read_full_stream_into_buf(const struct wim_lookup_table_entry *lte, void *buf); extern int -read_full_resource_into_alloc_buf(const struct wim_lookup_table_entry *lte, - void **buf_ret); +read_full_stream_into_alloc_buf(const struct wim_lookup_table_entry *lte, + void **buf_ret); extern int wim_reshdr_to_data(const struct wim_reshdr *reshdr, WIMStruct *wim, void **buf_ret); extern int -read_resource_prefix(const struct wim_lookup_table_entry *lte, - u64 size, consume_data_callback_t cb, - u32 in_chunk_size, void *ctx_or_buf, int flags); +read_stream_prefix(const struct wim_lookup_table_entry *lte, + u64 size, consume_data_callback_t cb, + u32 in_chunk_size, void *ctx_or_buf, int flags); /* Functions to extract a resource. */ extern int -extract_wim_resource(const struct wim_lookup_table_entry *lte, - u64 size, - consume_data_callback_t extract_chunk, - void *extract_chunk_arg); +extract_stream(const struct wim_lookup_table_entry *lte, + u64 size, + consume_data_callback_t extract_chunk, + void *extract_chunk_arg); extern int -extract_wim_resource_to_fd(const struct wim_lookup_table_entry *lte, - struct filedes *fd, u64 size); +extract_stream_to_fd(const struct wim_lookup_table_entry *lte, + struct filedes *fd, u64 size); /* Miscellaneous resource functions. */ extern int -sha1_resource(struct wim_lookup_table_entry *lte); +sha1_stream(struct wim_lookup_table_entry *lte); /* Functions to read/write metadata resources. */ diff --git a/src/dentry.c b/src/dentry.c index 37405eb0..cc3304ef 100644 --- a/src/dentry.c +++ b/src/dentry.c @@ -1635,7 +1635,7 @@ inode_get_unix_data(const struct wim_inode *inode, if (size != sizeof(struct wimlib_unix_data)) return BAD_UNIX_DATA; - ret = read_full_resource_into_buf(lte, unix_data); + ret = read_full_stream_into_buf(lte, unix_data); if (ret) return ret; diff --git a/src/extract.c b/src/extract.c index fbe5458d..8f658c4f 100644 --- a/src/extract.c +++ b/src/extract.c @@ -1257,7 +1257,7 @@ extract_stream_instances(struct wim_lookup_table_entry *lte, goto out_free_lte_tmp; } filedes_init(&fd, raw_fd); - ret = extract_wim_resource_to_fd(lte, &fd, lte->size); + ret = extract_stream_to_fd(lte, &fd, lte->size); if (filedes_close(&fd) && !ret) ret = WIMLIB_ERR_WRITE; if (ret) @@ -1541,7 +1541,7 @@ extract_dentry_to_stdout(struct wim_dentry *dentry) if (lte) { struct filedes _stdout; filedes_init(&_stdout, STDOUT_FILENO); - ret = extract_wim_resource_to_fd(lte, &_stdout, lte->size); + ret = extract_stream_to_fd(lte, &_stdout, lte->size); } } return ret; diff --git a/src/header.c b/src/header.c index d3ab360c..feea7c68 100644 --- a/src/header.c +++ b/src/header.c @@ -239,6 +239,10 @@ set_wim_hdr_cflags(int ctype, struct wim_header *hdr) hdr->flags |= WIM_HDR_FLAG_COMPRESSION | WIM_HDR_FLAG_COMPRESS_XPRESS; return 0; + case WIMLIB_COMPRESSION_TYPE_LZMS: + hdr->flags |= WIM_HDR_FLAG_COMPRESSION | WIM_HDR_FLAG_COMPRESS_LZMS; + return 0; + default: return WIMLIB_ERR_INVALID_COMPRESSION_TYPE; } diff --git a/src/lookup_table.c b/src/lookup_table.c index 0429a110..005d5ce8 100644 --- a/src/lookup_table.c +++ b/src/lookup_table.c @@ -469,24 +469,24 @@ validate_resource(const struct wim_resource_spec *rspec, u64 offset_save, u64 size_save) { struct wim_lookup_table_entry *lte; - list_for_each_entry(lte, &rspec->lte_list, wim_resource_list) { - if (rspec->flags & WIM_RESHDR_FLAG_COMPRESSED) - lte->flags |= WIM_RESHDR_FLAG_COMPRESSED; - else - lte->flags &= ~WIM_RESHDR_FLAG_COMPRESSED; - - if (!(lte->flags & WIM_RESHDR_FLAG_CONCAT)) { - lte->offset_in_res = offset_save; - lte->size = size_save; - } + if (!list_is_singular(&rspec->lte_list)) { + list_for_each_entry(lte, &rspec->lte_list, wim_resource_list) { + if (rspec->flags & WIM_RESHDR_FLAG_COMPRESSED) + lte->flags |= WIM_RESHDR_FLAG_COMPRESSED; + else + lte->flags &= ~WIM_RESHDR_FLAG_COMPRESSED; + if (!(lte->flags & WIM_RESHDR_FLAG_CONCAT)) { + lte->offset_in_res = offset_save; + lte->size = size_save; + } - if (lte->offset_in_res + lte->size < lte->size || - lte->offset_in_res + lte->size > rspec->uncompressed_size) - { - return WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY; + if (lte->offset_in_res + lte->size < lte->size || + lte->offset_in_res + lte->size > rspec->uncompressed_size) + { + return WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY; + } } - print_lookup_table_entry(lte, stderr); } return 0; } @@ -548,16 +548,22 @@ read_wim_lookup_table(WIMStruct *wim) u16 part_number; struct wim_reshdr reshdr; - get_wim_reshdr(&disk_entry->reshdr, &reshdr); + ret = get_wim_reshdr(&disk_entry->reshdr, &reshdr); + if (ret) { + ERROR("Resource header is invalid!"); + goto out_free_lookup_table; + } - DEBUG("reshdr: size=%"PRIu64", original_size=%"PRIu64", " - "offset=%"PRIu64", flags=0x%02x", + DEBUG("reshdr: size_in_wim=%"PRIu64", " + "uncompressed_size=%"PRIu64", " + "offset_in_wim=%"PRIu64", " + "flags=0x%02x", reshdr.size_in_wim, reshdr.uncompressed_size, reshdr.offset_in_wim, reshdr.flags); cur_entry = new_lookup_table_entry(); if (cur_entry == NULL) { - ERROR("Not enough memory to read lookup table."); + ERROR("Not enough memory to read lookup table!"); ret = WIMLIB_ERR_NOMEM; goto out_free_lookup_table; } @@ -590,7 +596,7 @@ read_wim_lookup_table(WIMStruct *wim) cur_rspec = MALLOC(sizeof(struct wim_resource_spec)); if (cur_rspec == NULL) { - ERROR("Not enough memory to read lookup table."); + ERROR("Not enough memory to read lookup table!"); ret = WIMLIB_ERR_NOMEM; goto out_free_cur_entry; } @@ -1402,7 +1408,7 @@ hash_unhashed_stream(struct wim_lookup_table_entry *lte, * the SHA1 has been calculated. */ back_ptr = retrieve_lte_pointer(lte); - ret = sha1_resource(lte); + ret = sha1_stream(lte); if (ret) return ret; diff --git a/src/lzms-decompress.c b/src/lzms-decompress.c new file mode 100644 index 00000000..9459b0b9 --- /dev/null +++ b/src/lzms-decompress.c @@ -0,0 +1,35 @@ +/* + * lzms-decompress.c + * + * LZMS decompression routines. + */ + +/* + * Copyright (C) 2013 Eric Biggers + * + * This file is part of wimlib, a library for working with WIM files. + * + * wimlib is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at your option) + * any later version. + * + * wimlib is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with wimlib; if not, see http://www.gnu.org/licenses/. + */ + +#include "wimlib/lzms.h" +#include "wimlib/error.h" + +int +lzms_decompress(const void *cdata, unsigned clen, void *udata, unsigned unlen, + unsigned window_size) +{ + ERROR("LZMS decompression stub: not implemented"); + return -1; +} diff --git a/src/metadata_resource.c b/src/metadata_resource.c index b5ed165c..aebc5468 100644 --- a/src/metadata_resource.c +++ b/src/metadata_resource.c @@ -74,11 +74,7 @@ read_metadata_resource(WIMStruct *wim, struct wim_image_metadata *imd) metadata_lte = imd->metadata_lte; metadata_len = metadata_lte->size; - DEBUG("Reading metadata resource: original_size = %"PRIu64", " - "size = %"PRIu64", offset = %"PRIu64"", - metadata_lte->rspec->uncompressed_size, - metadata_lte->rspec->size_in_wim, - metadata_lte->rspec->offset_in_wim); + DEBUG("Reading metadata resource."); /* There is no way the metadata resource could possibly be less than (8 * + WIM_DENTRY_DISK_SIZE) bytes, where the 8 is for security data (with @@ -91,7 +87,7 @@ read_metadata_resource(WIMStruct *wim, struct wim_image_metadata *imd) } /* Read the metadata resource into memory. (It may be compressed.) */ - ret = read_full_resource_into_alloc_buf(metadata_lte, &buf); + ret = read_full_stream_into_alloc_buf(metadata_lte, &buf); if (ret) return ret; diff --git a/src/mount_image.c b/src/mount_image.c index b1a3f1c7..7543b6e4 100644 --- a/src/mount_image.c +++ b/src/mount_image.c @@ -569,8 +569,7 @@ extract_resource_to_staging_dir(struct wim_inode *inode, struct filedes wimlib_fd; filedes_init(&wimlib_fd, fd); extract_size = min(old_lte->size, size); - ret = extract_wim_resource_to_fd(old_lte, &wimlib_fd, - extract_size); + ret = extract_stream_to_fd(old_lte, &wimlib_fd, extract_size); } else { ret = 0; extract_size = 0; @@ -1667,7 +1666,7 @@ wimfs_getxattr(const char *path, const char *name, char *value, if (stream_size > size) return -ERANGE; - ret = read_full_resource_into_buf(lte, value); + ret = read_full_stream_into_buf(lte, value); if (ret) { if (errno) return -errno; @@ -1942,8 +1941,8 @@ wimfs_read(const char *path, char *buf, size_t size, ret = -errno; break; case RESOURCE_IN_WIM: - if (read_partial_wim_resource_into_buf(fd->f_lte, size, - offset, buf)) + if (read_partial_wim_stream_into_buf(fd->f_lte, size, + offset, buf)) ret = -errno; else ret = size; diff --git a/src/ntfs-3g_apply.c b/src/ntfs-3g_apply.c index b49e53a7..86a28c10 100644 --- a/src/ntfs-3g_apply.c +++ b/src/ntfs-3g_apply.c @@ -267,8 +267,8 @@ ntfs_3g_extract_stream(file_spec_t file, const utf16lechar *raw_stream_name, /* Extract stream data to the NTFS attribute. */ extract_ctx.na = na; extract_ctx.offset = 0; - ret = extract_wim_resource(lte, lte->size, - ntfs_3g_extract_wim_chunk, &extract_ctx); + ret = extract_stream(lte, lte->size, + ntfs_3g_extract_wim_chunk, &extract_ctx); /* Clean up and return. */ out_attr_close: ntfs_attr_close(na); diff --git a/src/reparse.c b/src/reparse.c index cbb3a08c..d996e3df 100644 --- a/src/reparse.c +++ b/src/reparse.c @@ -299,7 +299,7 @@ wim_inode_get_reparse_data(const struct wim_inode * restrict inode, rpdatalen = lte->size; /* Read the data from the WIM file */ - ret = read_full_resource_into_buf(lte, rpbuf + 8); + ret = read_full_stream_into_buf(lte, rpbuf + 8); if (ret) return ret; diff --git a/src/resource.c b/src/resource.c index 1d82a967..1e64f260 100644 --- a/src/resource.c +++ b/src/resource.c @@ -31,6 +31,7 @@ #include "wimlib/error.h" #include "wimlib/file_io.h" #include "wimlib/lookup_table.h" +#include "wimlib/lzms.h" #include "wimlib/resource.h" #include "wimlib/sha1.h" @@ -95,22 +96,19 @@ * separate @wim_chunk_size is needed because it determines the window size used * for LZX compression. */ static int -decompress(const void *cchunk, unsigned clen, - void *uchunk, unsigned ulen, +decompress(const void *cchunk, unsigned clen, void *uchunk, unsigned ulen, int ctype, u32 wim_chunk_size) { switch (ctype) { - case WIMLIB_COMPRESSION_TYPE_XPRESS: - return wimlib_xpress_decompress(cchunk, - clen, - uchunk, - ulen); case WIMLIB_COMPRESSION_TYPE_LZX: - return wimlib_lzx_decompress2(cchunk, - clen, - uchunk, - ulen, - wim_chunk_size); + return wimlib_lzx_decompress2(cchunk, clen, + uchunk, ulen, wim_chunk_size); + case WIMLIB_COMPRESSION_TYPE_XPRESS: + return wimlib_xpress_decompress(cchunk, clen, + uchunk, ulen); + case WIMLIB_COMPRESSION_TYPE_LZMS: + return lzms_decompress(cchunk, clen, + uchunk, ulen, wim_chunk_size); default: wimlib_assert(0); return -1; @@ -523,12 +521,8 @@ read_error: /* Read raw data from a file descriptor at the specified offset. */ static int -read_raw_file_data(struct filedes *in_fd, - u64 size, - consume_data_callback_t cb, - u32 cb_chunk_size, - void *ctx_or_buf, - u64 offset) +read_raw_file_data(struct filedes *in_fd, u64 size, consume_data_callback_t cb, + u32 cb_chunk_size, void *ctx_or_buf, u64 offset) { int ret; u8 *tmp_buf; @@ -581,7 +575,7 @@ out: * * Read a range of data from an uncompressed or compressed resource in a WIM * file. Data is written into a buffer or fed into a callback function, as - * documented in read_resource_prefix(). + * documented in read_stream_prefix(). * * By default, this function provides the uncompressed data of the resource, and * @size and @offset and interpreted relative to the uncompressed contents of @@ -610,8 +604,8 @@ out: int read_partial_wim_resource(const struct wim_lookup_table_entry *lte, u64 size, consume_data_callback_t cb, - u32 cb_chunk_size, - void *ctx_or_buf, int flags, u64 offset) + u32 cb_chunk_size, void *ctx_or_buf, + int flags, u64 offset) { const struct wim_resource_spec *rspec; struct filedes *in_fd; @@ -667,26 +661,23 @@ read_partial_wim_resource(const struct wim_lookup_table_entry *lte, } int -read_partial_wim_resource_into_buf(const struct wim_lookup_table_entry *lte, - size_t size, u64 offset, void *buf) +read_partial_wim_stream_into_buf(const struct wim_lookup_table_entry *lte, + size_t size, u64 offset, void *buf) { return read_partial_wim_resource(lte, size, NULL, 0, buf, 0, offset); } static int -read_wim_resource_prefix(const struct wim_lookup_table_entry *lte, - u64 size, - consume_data_callback_t cb, - u32 cb_chunk_size, - void *ctx_or_buf, - int flags) +read_wim_stream_prefix(const struct wim_lookup_table_entry *lte, u64 size, + consume_data_callback_t cb, u32 cb_chunk_size, + void *ctx_or_buf, int flags) { return read_partial_wim_resource(lte, size, cb, cb_chunk_size, ctx_or_buf, flags, 0); } #ifndef __WIN32__ -/* This function handles reading resource data that is located in an external +/* This function handles reading stream data that is located in an external * file, such as a file that has been added to the WIM image through execution * of a wimlib_add_command. * @@ -696,12 +687,9 @@ read_wim_resource_prefix(const struct wim_lookup_table_entry *lte, * encrypted), so Windows uses its own code for its equivalent case. */ static int -read_file_on_disk_prefix(const struct wim_lookup_table_entry *lte, - u64 size, - consume_data_callback_t cb, - u32 cb_chunk_size, - void *ctx_or_buf, - int _ignored_flags) +read_file_on_disk_prefix(const struct wim_lookup_table_entry *lte, u64 size, + consume_data_callback_t cb, u32 cb_chunk_size, + void *ctx_or_buf, int _ignored_flags) { int ret; int raw_fd; @@ -722,13 +710,12 @@ read_file_on_disk_prefix(const struct wim_lookup_table_entry *lte, } #endif /* !__WIN32__ */ -/* This function handles the trivial case of reading resource data that is, in +/* This function handles the trivial case of reading stream data that is, in * fact, already located in an in-memory buffer. */ static int read_buffer_prefix(const struct wim_lookup_table_entry *lte, u64 size, consume_data_callback_t cb, - u32 cb_chunk_size, - void *ctx_or_buf, int _ignored_flags) + u32 cb_chunk_size, void *ctx_or_buf, int _ignored_flags) { wimlib_assert(size <= lte->size); @@ -752,18 +739,16 @@ read_buffer_prefix(const struct wim_lookup_table_entry *lte, return 0; } -typedef int (*read_resource_prefix_handler_t)(const struct wim_lookup_table_entry *lte, - u64 size, - consume_data_callback_t cb, - u32 cb_chunk_size, - void *ctx_or_buf, - int flags); +typedef int (*read_stream_prefix_handler_t)(const struct wim_lookup_table_entry *lte, + u64 size, consume_data_callback_t cb, + u32 cb_chunk_size, void *ctx_or_buf, + int flags); /* - * read_resource_prefix()- + * read_stream_prefix()- * - * Reads the first @size bytes from a generic "resource", which may be located - * in any one of several locations, such as in a WIM file (compressed or + * Reads the first @size bytes from a generic "stream", which may be located in + * any one of several locations, such as in a WIM file (compressed or * uncompressed), in an external file, or directly in an in-memory buffer. * * This function feeds the data either to a callback function (@cb != NULL, @@ -773,28 +758,28 @@ typedef int (*read_resource_prefix_handler_t)(const struct wim_lookup_table_entr * * When (@cb != NULL), @cb_chunk_size specifies the maximum size of data chunks * to feed the callback function. @cb_chunk_size must be positive, and if the - * resource is in a WIM file, must be a power of 2. All chunks, except possibly + * stream is in a WIM file, must be a power of 2. All chunks, except possibly * the last one, will be this size. If (@cb == NULL), @cb_chunk_size is * ignored. * - * If the resource is located in a WIM file, @flags can be set as documented in + * If the stream is located in a WIM file, @flags can be set as documented in * read_partial_wim_resource(). Otherwise @flags are ignored. * * Returns 0 on success; nonzero on error. A nonzero value will be returned if - * the resource data cannot be successfully read (for a number of different - * reasons, depending on the resource location), or if a callback function was + * the stream data cannot be successfully read (for a number of different + * reasons, depending on the stream location), or if a callback function was * specified and it returned nonzero. */ int -read_resource_prefix(const struct wim_lookup_table_entry *lte, - u64 size, consume_data_callback_t cb, u32 cb_chunk_size, - void *ctx_or_buf, int flags) +read_stream_prefix(const struct wim_lookup_table_entry *lte, u64 size, + consume_data_callback_t cb, u32 cb_chunk_size, + void *ctx_or_buf, int flags) { /* This function merely verifies several preconditions, then passes * control to an appropriate function for understanding each possible - * resource location. */ - static const read_resource_prefix_handler_t handlers[] = { - [RESOURCE_IN_WIM] = read_wim_resource_prefix, + * stream location. */ + static const read_stream_prefix_handler_t handlers[] = { + [RESOURCE_IN_WIM] = read_wim_stream_prefix, #ifdef __WIN32__ [RESOURCE_IN_FILE_ON_DISK] = read_win32_file_prefix, #else @@ -818,27 +803,25 @@ read_resource_prefix(const struct wim_lookup_table_entry *lte, ctx_or_buf, flags); } -/* Read the full uncompressed data of the specified resource into the specified - * buffer, which must have space for at least lte->resource_entry.original_size - * bytes. */ +/* Read the full uncompressed data of the specified stream into the specified + * buffer, which must have space for at least lte->size bytes. */ int -read_full_resource_into_buf(const struct wim_lookup_table_entry *lte, - void *buf) +read_full_stream_into_buf(const struct wim_lookup_table_entry *lte, void *buf) { - return read_resource_prefix(lte, lte->size, NULL, 0, buf, 0); + return read_stream_prefix(lte, lte->size, NULL, 0, buf, 0); } -/* Read the full uncompressed data of the specified resource. A buffer - * sufficient to hold the data is allocated and returned in @buf_ret. */ +/* Read the full uncompressed data of the specified stream. A buffer sufficient + * to hold the data is allocated and returned in @buf_ret. */ int -read_full_resource_into_alloc_buf(const struct wim_lookup_table_entry *lte, - void **buf_ret) +read_full_stream_into_alloc_buf(const struct wim_lookup_table_entry *lte, + void **buf_ret) { int ret; void *buf; if ((size_t)lte->size != lte->size) { - ERROR("Can't read %"PRIu64" byte resource into " + ERROR("Can't read %"PRIu64" byte stream into " "memory", lte->size); return WIMLIB_ERR_NOMEM; } @@ -847,7 +830,7 @@ read_full_resource_into_alloc_buf(const struct wim_lookup_table_entry *lte, if (buf == NULL) return WIMLIB_ERR_NOMEM; - ret = read_full_resource_into_buf(lte, buf); + ret = read_full_stream_into_buf(lte, buf); if (ret) { FREE(buf); return ret; @@ -857,8 +840,7 @@ read_full_resource_into_alloc_buf(const struct wim_lookup_table_entry *lte, return 0; } -/* Retrieve the full uncompressed data of the specified WIM resource, provided - * as a raw `struct resource_entry'. */ +/* Retrieve the full uncompressed data of the specified WIM resource. */ static int wim_resource_spec_to_data(struct wim_resource_spec *rspec, void **buf_ret) { @@ -875,13 +857,14 @@ wim_resource_spec_to_data(struct wim_resource_spec *rspec, void **buf_ret) lte->size = rspec->uncompressed_size; lte->offset_in_res = 0; - ret = read_full_resource_into_alloc_buf(lte, buf_ret); + ret = read_full_stream_into_alloc_buf(lte, buf_ret); lte_unbind_wim_resource_spec(lte); free_lookup_table_entry(lte); return ret; } +/* Retrieve the full uncompressed data of the specified WIM resource. */ int wim_reshdr_to_data(const struct wim_reshdr *reshdr, WIMStruct *wim, void **buf_ret) { @@ -901,8 +884,7 @@ struct extract_ctx { }; static int -extract_chunk_sha1_wrapper(const void *chunk, size_t chunk_size, - void *_ctx) +extract_chunk_sha1_wrapper(const void *chunk, size_t chunk_size, void *_ctx) { struct extract_ctx *ctx = _ctx; @@ -910,17 +892,15 @@ extract_chunk_sha1_wrapper(const void *chunk, size_t chunk_size, return ctx->extract_chunk(chunk, chunk_size, ctx->extract_chunk_arg); } -/* Extracts the first @size bytes of a resource to somewhere. In the process, - * the SHA1 message digest of the uncompressed resource is checked if the full - * resource is being extracted. +/* Extracts the first @size bytes of a stream to somewhere. In the process, the + * SHA1 message digest of the uncompressed stream is checked if the full stream + * is being extracted. * * @extract_chunk is a function that will be called to extract each chunk of the - * resource. */ + * stream. */ int -extract_wim_resource(const struct wim_lookup_table_entry *lte, - u64 size, - consume_data_callback_t extract_chunk, - void *extract_chunk_arg) +extract_stream(const struct wim_lookup_table_entry *lte, u64 size, + consume_data_callback_t extract_chunk, void *extract_chunk_arg) { int ret; if (size == lte->size) { @@ -929,17 +909,17 @@ extract_wim_resource(const struct wim_lookup_table_entry *lte, ctx.extract_chunk = extract_chunk; ctx.extract_chunk_arg = extract_chunk_arg; sha1_init(&ctx.sha_ctx); - ret = read_resource_prefix(lte, size, - extract_chunk_sha1_wrapper, - lte_cchunk_size(lte), - &ctx, 0); + ret = read_stream_prefix(lte, size, + extract_chunk_sha1_wrapper, + lte_cchunk_size(lte), + &ctx, 0); if (ret == 0) { u8 hash[SHA1_HASH_SIZE]; sha1_final(hash, &ctx.sha_ctx); if (!hashes_equal(hash, lte->hash)) { if (wimlib_print_errors) { ERROR("Invalid SHA1 message digest " - "on the following WIM resource:"); + "on the following WIM stream:"); print_lookup_table_entry(lte, stderr); if (lte->resource_location == RESOURCE_IN_WIM) ERROR("The WIM file appears to be corrupt!"); @@ -949,9 +929,9 @@ extract_wim_resource(const struct wim_lookup_table_entry *lte, } } else { /* Don't do SHA1 */ - ret = read_resource_prefix(lte, size, extract_chunk, - lte_cchunk_size(lte), - extract_chunk_arg, 0); + ret = read_stream_prefix(lte, size, extract_chunk, + lte_cchunk_size(lte), + extract_chunk_arg, 0); } return ret; } @@ -966,14 +946,14 @@ extract_wim_chunk_to_fd(const void *buf, size_t len, void *_fd_p) return ret; } -/* Extract the first @size bytes of the specified resource to the specified file - * descriptor. If @size is the full size of the resource, its SHA1 message - * digest is also checked. */ +/* Extract the first @size bytes of the specified stream to the specified file + * descriptor. If @size is the full size of the stream, its SHA1 message digest + * is also checked. */ int -extract_wim_resource_to_fd(const struct wim_lookup_table_entry *lte, - struct filedes *fd, u64 size) +extract_stream_to_fd(const struct wim_lookup_table_entry *lte, + struct filedes *fd, u64 size) { - return extract_wim_resource(lte, size, extract_wim_chunk_to_fd, fd); + return extract_stream(lte, size, extract_wim_chunk_to_fd, fd); } @@ -984,17 +964,17 @@ sha1_chunk(const void *buf, size_t len, void *ctx) return 0; } -/* Calculate the SHA1 message digest of a resource, storing it in @lte->hash. */ +/* Calculate the SHA1 message digest of a stream, storing it in @lte->hash. */ int -sha1_resource(struct wim_lookup_table_entry *lte) +sha1_stream(struct wim_lookup_table_entry *lte) { int ret; SHA_CTX sha_ctx; sha1_init(&sha_ctx); - ret = read_resource_prefix(lte, lte->size, - sha1_chunk, lte_cchunk_size(lte), - &sha_ctx, 0); + ret = read_stream_prefix(lte, lte->size, + sha1_chunk, lte_cchunk_size(lte), + &sha_ctx, 0); if (ret == 0) sha1_final(lte->hash, &sha_ctx); @@ -1035,14 +1015,10 @@ wim_res_spec_to_hdr(const struct wim_resource_spec *rspec, /* Translates a WIM resource header from the on-disk format into an in-memory * format. */ -void +int get_wim_reshdr(const struct wim_reshdr_disk *disk_reshdr, struct wim_reshdr *reshdr) { - /* Note: disk_reshdr may not be 8 byte aligned--- in that case, the - * offset and original_size members will be unaligned. (This is okay - * since `struct resource_reshdr_disk' is declared as packed.) */ - reshdr->offset_in_wim = le64_to_cpu(disk_reshdr->offset_in_wim); reshdr->size_in_wim = (((u64)disk_reshdr->size_in_wim[0] << 0) | ((u64)disk_reshdr->size_in_wim[1] << 8) | @@ -1055,14 +1031,13 @@ get_wim_reshdr(const struct wim_reshdr_disk *disk_reshdr, reshdr->flags = disk_reshdr->flags; /* Truncate numbers to 62 bits to avoid possible overflows. */ - if (reshdr->offset_in_wim & 0xc000000000000000ULL) { - WARNING("Truncating offset in resource reshdr"); - reshdr->offset_in_wim &= 0x3fffffffffffffffULL; - } - if (reshdr->uncompressed_size & 0xc000000000000000ULL) { - WARNING("Truncating original_size in resource reshdr"); - reshdr->uncompressed_size &= 0x3fffffffffffffffULL; - } + if (reshdr->offset_in_wim & 0xc000000000000000ULL) + return WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY; + + if (reshdr->uncompressed_size & 0xc000000000000000ULL) + return WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY; + + return 0; } /* Translates a WIM resource header from an in-memory format into the on-disk @@ -1071,9 +1046,6 @@ void put_wim_reshdr(const struct wim_reshdr *reshdr, struct wim_reshdr_disk *disk_reshdr) { - /* Note: disk_reshdr may not be 8 byte aligned--- in that case, the - * offset and original_size members will be unaligned. (This is okay - * since `struct resource_reshdr_disk' is declared as packed.) */ disk_reshdr->size_in_wim[0] = reshdr->size_in_wim >> 0; disk_reshdr->size_in_wim[1] = reshdr->size_in_wim >> 8; disk_reshdr->size_in_wim[2] = reshdr->size_in_wim >> 16; diff --git a/src/unix_apply.c b/src/unix_apply.c index ca0f485c..152361b0 100644 --- a/src/unix_apply.c +++ b/src/unix_apply.c @@ -122,7 +122,7 @@ unix_extract_unnamed_stream(file_spec_t file, if (raw_fd < 0) return WIMLIB_ERR_OPEN; filedes_init(&fd, raw_fd); - ret = extract_wim_resource_to_fd(lte, &fd, lte->size); + ret = extract_stream_to_fd(lte, &fd, lte->size); if (filedes_close(&fd) && !ret) ret = WIMLIB_ERR_WRITE; return ret; diff --git a/src/wim.c b/src/wim.c index adfbeff2..11bb2e50 100644 --- a/src/wim.c +++ b/src/wim.c @@ -297,6 +297,8 @@ wimlib_get_compression_type_string(int ctype) return T("LZX"); case WIMLIB_COMPRESSION_TYPE_XPRESS: return T("XPRESS"); + case WIMLIB_COMPRESSION_TYPE_LZMS: + return T("LZMS"); default: return T("Invalid"); } @@ -449,6 +451,7 @@ wimlib_set_output_compression_type(WIMStruct *wim, int ctype) case WIMLIB_COMPRESSION_TYPE_NONE: case WIMLIB_COMPRESSION_TYPE_LZX: case WIMLIB_COMPRESSION_TYPE_XPRESS: + case WIMLIB_COMPRESSION_TYPE_LZMS: wim->out_compression_type = ctype; /* Reset the chunk size if it's no longer valid. */ @@ -478,6 +481,9 @@ wimlib_set_output_chunk_size(WIMStruct *wim, uint32_t chunk_size) ERROR("Valid chunk sizes for LZX are " "32768, 65536, 131072, ..., 2097152."); break; + case WIMLIB_COMPRESSION_TYPE_LZMS: + ERROR("Valid chunk sizes for LZMS are 131072."); + break; } return WIMLIB_ERR_INVALID_CHUNK_SIZE; } @@ -602,11 +608,8 @@ begin_read(WIMStruct *wim, const void *wim_filename_or_fd, wim->compression_type = WIMLIB_COMPRESSION_TYPE_LZX; } else if (wim->hdr.flags & WIM_HDR_FLAG_COMPRESS_XPRESS) { wim->compression_type = WIMLIB_COMPRESSION_TYPE_XPRESS; - #if 1 - /* TODO */ } else if (wim->hdr.flags & WIM_HDR_FLAG_COMPRESS_LZMS) { wim->compression_type = WIMLIB_COMPRESSION_TYPE_LZMS; - #endif } else { ERROR("The compression flag is set on \"%"TS"\", but " "a flag for a recognized format is not", diff --git a/src/win32_apply.c b/src/win32_apply.c index 1a4adf5c..3415753e 100644 --- a/src/win32_apply.c +++ b/src/win32_apply.c @@ -195,7 +195,7 @@ win32_extract_stream(const wchar_t *path, const wchar_t *stream_name, ret = 0; if (!lte) goto out_close_handle; - ret = extract_wim_resource(lte, lte->size, win32_extract_wim_chunk, h); + ret = extract_stream(lte, lte->size, win32_extract_wim_chunk, h); out_close_handle: if (!CloseHandle(h)) goto error; diff --git a/src/win32_capture.c b/src/win32_capture.c index 6197d9f1..eb8bd7f9 100644 --- a/src/win32_capture.c +++ b/src/win32_capture.c @@ -971,10 +971,10 @@ win32_capture_stream(const wchar_t *path, ret = win32_get_encrypted_file_size(path, &encrypted_size); if (ret) goto out_free_spath; - lte->resource_entry.original_size = encrypted_size; + lte->size = encrypted_size; } else { lte->resource_location = RESOURCE_IN_FILE_ON_DISK; - lte->resource_entry.original_size = (u64)dat->StreamSize.QuadPart; + lte->size = (u64)dat->StreamSize.QuadPart; } u32 stream_id; diff --git a/src/write.c b/src/write.c index 053893da..63c91b2a 100644 --- a/src/write.c +++ b/src/write.c @@ -119,6 +119,11 @@ compress_chunk(const void * uncompressed_data, uncompressed_len, compressed_data, comp_ctx); + case WIMLIB_COMPRESSION_TYPE_LZMS: + /* TODO */ + WARNING("LZMS compression not yet implemented!"); + return 0; + default: wimlib_assert(0); return 0; @@ -526,9 +531,8 @@ try_write_again: in_chunk_size = lte_cchunk_size(lte); else in_chunk_size = out_chunk_size; - ret = read_resource_prefix(lte, read_size, - write_resource_cb, - in_chunk_size, &write_ctx, resource_flags); + ret = read_stream_prefix(lte, read_size, write_resource_cb, + in_chunk_size, &write_ctx, resource_flags); if (ret) goto out_free_chunk_tab; @@ -1476,9 +1480,8 @@ submit_stream_for_compression(struct wim_lookup_table_entry *lte, ctx->next_lte = lte; INIT_LIST_HEAD(<e->msg_list); list_add_tail(<e->being_compressed_list, &ctx->outstanding_streams); - ret = read_resource_prefix(lte, lte->size, - main_writer_thread_cb, - ctx->out_chunk_size, ctx, 0); + ret = read_stream_prefix(lte, lte->size, main_writer_thread_cb, + ctx->out_chunk_size, ctx, 0); if (ret) return ret; wimlib_assert(ctx->next_chunk == ctx->next_num_chunks);