/** Compressed resources in the WIM use XPRESS compression. */
WIMLIB_COMPRESSION_TYPE_XPRESS = 2,
+
+ /** Compressed resources in the WIM use LZMS compression. Currently,
+ * wimlib has a decompressor for this format but not a compressor. LZMS
+ * compression is only compatible with wimlib v1.6.0 and later and with
+ * WIMGAPI Windows 8 and later (and some restrictions apply on the
+ * latter). */
+ WIMLIB_COMPRESSION_TYPE_LZMS = 3,
};
/** @} */
WIMLIB_SCAN_DENTRY_OK = 0,
/** File or directory is being excluded from capture due
- * to the capture configuration file. */
+ * to the capture configuration file, or being an
+ * absolute symbolic link that points outside of the
+ * capture directory without ::WIMLIB_ADD_FLAG_NORPFIX.
+ */
WIMLIB_SCAN_DENTRY_EXCLUDED,
/** File or directory is being excluded from capture due
* ::WIMLIB_PROGRESS_MSG_SCAN_BEGIN and
* ::WIMLIB_PROGRESS_MSG_SCAN_END. */
const wimlib_tchar *wim_target_path;
+
+ /** Number of directories scanned so far, including the root
+ * directory but excluding any unsupported/excluded directories.
+ * */
+ uint64_t num_dirs_scanned;
+
+ /** Number of non-directories scanned so far, excluding any
+ * unsupported/excluded files. */
+ uint64_t num_nondirs_scanned;
+
+ /** Number of bytes of file data that have been detected so far.
+ * This data may not actually have been read yet, and it will
+ * not actually be written to the WIM file until wimlib_write()
+ * or wimlib_overwrite() has been called. */
+ uint64_t num_bytes_scanned;
} scan;
/** Valid on messages ::WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_BEGIN,
uint32_t reserved[9];
};
-/** Information about a unique resource in the WIM file.
- */
+/** Information about a unique stream in the WIM file. (A stream is the same
+ * thing as a "resource", except in the case of packed resources.) */
struct wimlib_resource_entry {
- /** Uncompressed size of the resource in bytes. */
+ /** Uncompressed size of the stream in bytes. */
uint64_t uncompressed_size;
- /** Compressed size of the resource in bytes. This will be the same as
- * @p uncompressed_size if the resource is uncompressed. */
+ /** Compressed size of the stream in bytes. This will be the same as @p
+ * uncompressed_size if the stream is uncompressed. Or, if @p
+ * is_packed_streams is 1, this will be 0. */
uint64_t compressed_size;
- /** Offset, in bytes, of this resource from the start of the WIM file.
+ /** Offset, in bytes, of this stream from the start of the WIM file. Or
+ * if @p packed is 1, then this is actually the offset at which this
+ * stream begins in the uncompressed contents of the packed resource.
*/
uint64_t offset;
- /** SHA1 message digest of the resource's uncompressed contents. */
+ /** SHA1 message digest of the stream's uncompressed contents. */
uint8_t sha1_hash[20];
- /** Which part number of the split WIM this resource is in. This should
+ /** Which part number of the split WIM this stream is in. This should
* be the same as the part number provided by wimlib_get_wim_info(). */
uint32_t part_number;
- /** Number of times this resource is referenced over all WIM images. */
+ /** Number of times this stream is referenced over all WIM images. */
uint32_t reference_count;
- /** 1 if this resource is compressed. */
+ /** 1 if this stream is compressed. */
uint32_t is_compressed : 1;
- /** 1 if this resource is a metadata resource rather than a file
- * resource. */
+ /** 1 if this stream is a metadata resource rather than a file resource.
+ * */
uint32_t is_metadata : 1;
uint32_t is_free : 1;
uint32_t is_spanned : 1;
- /** 1 if this resource was not found in the lookup table of the
+ /** 1 if this stream was not found in the lookup table of the
* ::WIMStruct. This normally implies a missing call to
* wimlib_reference_resource_files() or wimlib_reference_resources().
- */
+ * */
uint32_t is_missing : 1;
- uint32_t reserved_flags : 27;
- uint64_t reserved[4];
+ /** 1 if this stream is located in a packed resource which may contain
+ * other streams (all compressed together) as well. */
+ uint32_t packed : 1;
+
+ uint32_t reserved_flags : 26;
+
+ /** If @p packed is 1, then this will specify the offset of the packed
+ * resource in the WIM. */
+ uint64_t raw_resource_offset_in_wim;
+
+ /** If @p is_packed_streams is 1, then this will specify the compressed
+ * size of the packed resource in the WIM. */
+ uint64_t raw_resource_compressed_size;
+
+ uint64_t reserved[2];
};
/** A stream of a file in the WIM. */
/** This flag no longer does anything but is reserved for future use. */
#define WIMLIB_EXTRACT_FLAG_VERBOSE 0x00000008
-/** Read the WIM file sequentially while extracting the image. */
+/** Read the WIM file sequentially while extracting the image. As of wimlib
+ * v1.6.0 this is the default behavior, and this flag no longer does anything.
+ */
#define WIMLIB_EXTRACT_FLAG_SEQUENTIAL 0x00000010
/** Extract special UNIX data captured with ::WIMLIB_ADD_FLAG_UNIX_DATA. Only
* behavior is currently less than satisfactory. Do not use (yet). */
#define WIMLIB_EXTRACT_FLAG_RESUME 0x00010000
+/** Perform the extraction ordered by the tree of files to extract rather than
+ * how the underlying streams are arranged in the WIM file. For regular WIM
+ * files this may decrease or increase performance, depending on various
+ * factors. For WIM files containing packed streams this will decrease
+ * performance. */
+#define WIMLIB_EXTRACT_FLAG_FILE_ORDER 0x00020000
+
/** @} */
/** @ingroup G_mounting_wim_images
* @{ */
#define WIMLIB_WRITE_FLAG_RESERVED 0x00000800
+/** When writing streams in the resulting WIM file, pack multiple streams into a
+ * single WIM resource instead of compressing them independently. This tends to
+ * produce a better compression ratio at the cost of less random access.
+ * Furthermore, WIMs created with this flag are only compatible with wimlib
+ * v1.6.0 or later and WIMGAPI Windows 8 or later, seemingly for Windows Setup
+ * only and <b>not including ImageX and Dism</b>. WIMs created with this flag
+ * use version number 3584 in their header instead of 68864. If this flag is
+ * passed to wimlib_overwrite() and the WIM did not previously contain packed
+ * streams, the WIM's version number will be changed to 3584 and the new streams
+ * will be written packed. */
+#define WIMLIB_WRITE_FLAG_PACK_STREAMS 0x00001000
+
+/** Compress all streams independently. This produces a WIM optimized for
+ * random access and compatibility, as noted in the documentation for
+ * ::WIMLIB_WRITE_RESOURCE_FLAG_PACK_STREAMS. For wimlib_write(), this is the
+ * default behavior. For wimlib_overwrite(), this is the default if the WIM file
+ * did not already contain packed streams. Also, for wimlib_overwrite(), if the
+ * WIM already contained packed streams, specifying this flag but not
+ * ::WIMLIB_WRITE_FLAG_REBUILD will cause new streams to be written unpacked,
+ * but the WIM itself will not be rebuilt and may still contain packed streams.
+ */
+#define WIMLIB_WRITE_FLAG_NO_PACK_STREAMS 0x00002000
+
/** @} */
/** @ingroup G_general
* @{ */
int wim_write_flags,
wimlib_progress_func_t progress_func);
+/**
+ * @ingroup G_compression
+ *
+ * Decompresses a block of LZMS-compressed data.
+ *
+ * This function is exported for convenience only and should only be used by
+ * library clients looking to make use of wimlib's compression code for another
+ * purpose.
+ *
+ * This decompressor only implements "raw" decompression, which decompresses a
+ * single LZMS-compressed block. This behavior is the same as that of
+ * Decompress() in the Windows 8 compression API when using a compression handle
+ * created with CreateDecompressor() with the Algorithm parameter specified as
+ * COMPRESS_ALGORITHM_LZMS | COMPRESS_RAW. Presumably, non-raw LZMS data
+ * is a container format from which the locations and sizes (both compressed and
+ * uncompressed) of the constituent blocks can be determined.
+ *
+ * This function should not be called for blocks with compressed size equal to
+ * uncompressed size, since such blocks are actually stored uncompressed.
+ *
+ * @param compressed_data
+ * Pointer to the compressed data.
+ *
+ * @param compressed_len
+ * Length of the compressed data, in bytes.
+ *
+ * @param uncompressed_data
+ * Pointer to the buffer into which to write the uncompressed data.
+ *
+ * @param uncompressed_len
+ * Length of the uncompressed data.
+ *
+ * @return
+ * 0 on success; non-zero on failure.
+ */
+extern int
+wimlib_lzms_decompress(const void *compressed_data, unsigned compressed_len,
+ void *uncompressed_data, unsigned uncompressed_len);
+
/**
* @ingroup G_compression
*
* library clients looking to make use of wimlib's compression code for another
* purpose.
*
+ * @param window_size
+ * Size of the LZX window. Must be a power of 2 between 2^15 and 2^21,
+ * inclusively.
+ *
* @param params
* Compression parameters to use, or @c NULL to use the default parameters.
*
* @return 0 on success; nonzero on error.
*
* @retval ::WIMLIB_ERR_INVALID_PARAM
- * The compression parameters were invalid.
+ * The window size or compression parameters were invalid.
* @retval ::WIMLIB_ERR_NOMEM
* Not enough memory to allocate the compression context.
*/
extern int
-wimlib_lzx_alloc_context(const struct wimlib_lzx_params *params,
+wimlib_lzx_alloc_context(uint32_t window_size,
+ const struct wimlib_lzx_params *params,
struct wimlib_lzx_context **ctx_pp);
/**
wimlib_lzx_decompress(const void *compressed_data, unsigned compressed_len,
void *uncompressed_data, unsigned uncompressed_len);
+/**
+ * @ingroup G_compression
+ *
+ * Equivalent to wimlib_lzx_decompress(), except the window size is specified in
+ * @p max_window_size as any power of 2 between 2^15 and 2^21, inclusively, and
+ * @p uncompressed_len may be any size less than or equal to @p max_window_size.
+ */
+extern int
+wimlib_lzx_decompress2(const void *compressed_data, unsigned compressed_len,
+ void *uncompressed_data, unsigned uncompressed_len,
+ uint32_t max_window_size);
+
/**
* @ingroup G_compression
*
* chunk of the WIM does not match the corresponding message digest given
* in the integrity table.
* @retval ::WIMLIB_ERR_INVALID_CHUNK_SIZE
- * Resources in @p wim_file are compressed, but the chunk size is not 32768.
+ * Resources in @p wim_file are compressed, but the chunk size was invalid
+ * for the WIM's compression format.
* @retval ::WIMLIB_ERR_INVALID_COMPRESSION_TYPE
* The header of @p wim_file says that resources in the WIM are compressed,
* but the header flag indicating LZX or XPRESS compression is not set.
* Set the compression chunk size of a WIM to use in subsequent calls to
* wimlib_write() or wimlib_overwrite().
*
+ * A compression chunk size will result in a greater compression ratio, but the
+ * speed of random access to the WIM will be reduced, and the effect of an
+ * increased compression chunk size is limited by the size of each file being
+ * compressed.
+ *
+ * <b>WARNING: Changing the compression chunk size to any value other than the
+ * default of 32768 bytes eliminates compatibility with Microsoft's software,
+ * except when increasing the XPRESS chunk size before Windows 8. Chunk sizes
+ * other than 32768 are also incompatible with wimlib v1.5.3 and earlier.</b>
+ *
* @param wim
* ::WIMStruct for a WIM.
* @param out_chunk_size
* The chunk size (in bytes) to set. The valid chunk sizes are dependent
* on the compression format. The XPRESS compression format supports chunk
* sizes that are powers of 2 with exponents between 15 and 26 inclusively,
- * whereas the LZX compression format currently only supports a chunk size
- * of 32768.
+ * whereas the LZX compression format supports chunk sizes that are powers
+ * of 2 with exponents between 15 and 21 inclusively.
*
* @return 0 on success; nonzero on error.
*
* library clients looking to make use of wimlib's compression code for another
* purpose.
*
- * As of wimlib v1.5.4, this function can be used with @p chunk_size greater
+ * As of wimlib v1.6.0, this function can be used with @p chunk_size greater
* than 32768 bytes and is only limited by available memory. However, the
* XPRESS format itself still caps match offsets to 65535, so if a larger chunk
* size is chosen, then the matching will effectively occur in a sliding window