X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=include%2Fwimlib%2Fresource.h;h=05ceed70b88b7b24e96f45296e324698cd14321c;hp=3b863f4654d66d1146c6070e42cd79810ddc1c1b;hb=43f92ce30b2398d1823e34e39ff248de521d015c;hpb=a267f3e6b9df128bd4bdf5d39b951868dd4528ab diff --git a/include/wimlib/resource.h b/include/wimlib/resource.h index 3b863f46..05ceed70 100644 --- a/include/wimlib/resource.h +++ b/include/wimlib/resource.h @@ -1,27 +1,23 @@ #ifndef _WIMLIB_RESOURCE_H #define _WIMLIB_RESOURCE_H -#include "wimlib/callback.h" -#include "wimlib/file_io.h" #include "wimlib/list.h" #include "wimlib/sha1.h" #include "wimlib/types.h" -struct wim_lookup_table_entry; +struct blob_descriptor; +struct filedes; struct wim_image_metadata; -/* Specification of a resource in a WIM file. - * - * If a `struct wim_lookup_table_entry' lte has - * (lte->resource_location == RESOURCE_IN_WIM), then lte->wim_res_spec points to - * an instance of this structure. - * - * Normally, there is a one-to-one correspondence between WIM lookup table - * entries ("streams", each of which may be the contents of a file, for example) - * and WIM resources. However, WIM resources with the - * WIM_RESHDR_FLAG_PACKED_STREAMS flag set may actually contain multiple streams - * compressed together. */ -struct wim_resource_spec { +/* + * Description of a "resource" in a WIM file. A "resource" is a standalone, + * possibly compressed region of data. Normally, there is a one-to-one + * correspondence between "blobs" (each of which may be the contents of a file, + * for example) and resources. However, a resource with the + * WIM_RESHDR_FLAG_SOLID flag set is a "solid" resource that contains multiple + * blobs compressed together. + */ +struct wim_resource_descriptor { /* The WIM containing this resource. @wim->in_fd is expected to be a * file descriptor to the underlying WIM file, opened for reading. */ WIMStruct *wim; @@ -39,8 +35,8 @@ struct wim_resource_spec { * to. */ u64 uncompressed_size; - /* The list of streams this resource contains. */ - struct list_head stream_list; + /* The list of blobs this resource contains. */ + struct list_head blob_list; /* Flags for this resource (WIM_RESHDR_FLAG_*). */ u32 flags : 8; @@ -52,6 +48,13 @@ struct wim_resource_spec { /* Temporary flag. */ u32 raw_copy_ok : 1; + + /* Compression type of this resource. */ + u32 compression_type : 22; + + /* Compression chunk size of this resource. Irrelevant if the resource + * is uncompressed. */ + u32 chunk_size; }; /* On-disk version of a WIM resource header. */ @@ -82,41 +85,27 @@ struct wim_reshdr { /* Flags for the `flags' field of WIM resource headers (`struct wim_reshdr'). */ -/* Unknown meaning; may be intended to indicate spaces in the WIM that are free - * to overwrite. Currently ignored by wimlib. */ +/* Unknown meaning; currently ignored by wimlib. */ #define WIM_RESHDR_FLAG_FREE 0x01 -/* The resource is a metadata resource for a WIM image, or is the lookup table - * or XML data for the WIM. */ +/* The resource is a metadata resource for a WIM image, or is the blob table or + * XML data for the WIM. */ #define WIM_RESHDR_FLAG_METADATA 0x02 -/* The resource is compressed using the WIM's default compression type and uses - * the regular chunk table format. */ +/* The resource is a non-solid resource compressed using the WIM's default + * compression type. */ #define WIM_RESHDR_FLAG_COMPRESSED 0x04 -/* Unknown meaning; may be intended to indicate a partial stream. Currently - * ignored by wimlib. */ +/* Unknown meaning; currently ignored by wimlib. */ #define WIM_RESHDR_FLAG_SPANNED 0x08 -/* The resource is packed in a special format that may contain multiple - * underlying streams, or this resource entry represents a stream packed into - * one such resource. When resources have this flag set, the WIM version number - * should be WIM_VERSION_PACKED_STREAMS. */ -#define WIM_RESHDR_FLAG_PACKED_STREAMS 0x10 +/* The resource is a solid compressed resource which may contain multiple blobs. + * This flag is only allowed if the WIM version number is WIM_VERSION_SOLID. */ +#define WIM_RESHDR_FLAG_SOLID 0x10 /* Magic number in the 'uncompressed_size' field of the resource header that - * identifies the main entry for a pack. */ -#define WIM_PACK_MAGIC_NUMBER 0x100000000ULL - -/* Returns true if the specified WIM resource is compressed, using either the - * original chunk table layout or the alternate layout for resources that may - * contain multiple packed streams. */ -static inline bool -resource_is_compressed(const struct wim_resource_spec *rspec) -{ - return (rspec->flags & (WIM_RESHDR_FLAG_COMPRESSED | - WIM_RESHDR_FLAG_PACKED_STREAMS)); -} + * identifies the main entry for a solid resource. */ +#define SOLID_RESOURCE_MAGIC_NUMBER 0x100000000ULL static inline void copy_reshdr(struct wim_reshdr *dest, const struct wim_reshdr *src) @@ -131,23 +120,24 @@ zero_reshdr(struct wim_reshdr *reshdr) } extern void -wim_res_hdr_to_spec(const struct wim_reshdr *reshdr, WIMStruct *wim, - struct wim_resource_spec *rspec); +wim_reshdr_to_desc(const struct wim_reshdr *reshdr, WIMStruct *wim, + struct wim_resource_descriptor *rdesc); extern void -wim_res_spec_to_hdr(const struct wim_resource_spec *rspec, - struct wim_reshdr *reshdr); +wim_reshdr_to_desc_and_blob(const struct wim_reshdr *reshdr, WIMStruct *wim, + struct wim_resource_descriptor *rdesc, + struct blob_descriptor *blob); extern void get_wim_reshdr(const struct wim_reshdr_disk *disk_reshdr, struct wim_reshdr *reshdr); -void +extern void put_wim_reshdr(const struct wim_reshdr *reshdr, struct wim_reshdr_disk *disk_reshdr); -/* Alternate chunk table format for resources with - * WIM_RESHDR_FLAG_PACKED_STREAMS set. */ +/* Alternate chunk table format for resources with WIM_RESHDR_FLAG_SOLID set. + */ struct alt_chunk_table_header_disk { /* Uncompressed size of the resource in bytes. */ le64 res_usize; @@ -159,8 +149,8 @@ struct alt_chunk_table_header_disk { /* Compression format used for compressed chunks: * 0 = None - * 1 = LZX - * 2 = XPRESS + * 1 = XPRESS + * 2 = LZX * 3 = LZMS * * This overrides the compression type specified by the WIM header. */ @@ -170,145 +160,160 @@ struct alt_chunk_table_header_disk { * the chunks (4 bytes per entry). */ } _packed_attribute; -/* Functions to read streams */ +static inline unsigned int +get_chunk_entry_size(u64 res_size, bool is_alt) +{ + if (res_size <= UINT32_MAX || is_alt) + return 4; + else + return 8; +} -extern int -read_partial_wim_stream_into_buf(const struct wim_lookup_table_entry *lte, - size_t size, u64 offset, void *buf); +/* Functions to read blobs */ extern int -read_full_stream_into_buf(const struct wim_lookup_table_entry *lte, void *buf); +read_partial_wim_blob_into_buf(const struct blob_descriptor *blob, + u64 offset, size_t size, void *buf); extern int -read_full_stream_into_alloc_buf(const struct wim_lookup_table_entry *lte, - void **buf_ret); +read_blob_into_buf(const struct blob_descriptor *blob, void *buf); extern int -wim_reshdr_to_data(const struct wim_reshdr *reshdr, - WIMStruct *wim, void **buf_ret); +read_blob_into_alloc_buf(const struct blob_descriptor *blob, void **buf_ret); extern int -skip_wim_stream(struct wim_lookup_table_entry *lte); +wim_reshdr_to_data(const struct wim_reshdr *reshdr, WIMStruct *wim, + void **buf_ret); -/* - * Type of callback function for beginning to read a stream. - * - * @lte: - * Stream that is about to be read. - * - * @is_partial_res: - * Set to true if the stream is just one of several being read from a - * single pack and therefore would be extra expensive to read - * independently. - * - * @ctx: - * User-provided context. - * - * Must return 0 on success, a positive error code on failure, or the special - * value BEGIN_STREAM_STATUS_SKIP_STREAM to indicate that the stream should not - * be read, and read_stream_list() should continue on to the next stream - * (without calling @consume_chunk or @end_stream). - */ -typedef int (*read_stream_list_begin_stream_t)(struct wim_lookup_table_entry *lte, - bool is_partial_res, - void *ctx); +extern int +wim_reshdr_to_hash(const struct wim_reshdr *reshdr, WIMStruct *wim, + u8 hash[SHA1_HASH_SIZE]); -#define BEGIN_STREAM_STATUS_SKIP_STREAM -1 +extern int +skip_wim_resource(const struct wim_resource_descriptor *rdesc); /* - * Type of callback function for finishing reading a stream. - * - * @lte: - * Stream that has been fully read, or stream that started being read but - * could not be fully read due to a read error. - * - * @status: - * 0 if reading the stream was successful; otherwise a nonzero error code - * that specifies the return status. - * - * @ctx: - * User-provided context. + * Callback function for reading chunks. Called whenever the next chunk of + * uncompressed data is available, passing 'ctx' as the last argument. 'size' is + * guaranteed to be nonzero. Must return 0 on success, or a positive wimlib + * error code on failure. */ -typedef int (*read_stream_list_end_stream_t)(struct wim_lookup_table_entry *lte, - int status, - void *ctx); - - -/* Callback functions and contexts for read_stream_list(). */ -struct read_stream_list_callbacks { - - /* Called when a stream is about to be read. */ - read_stream_list_begin_stream_t begin_stream; +struct consume_chunk_callback { + int (*func)(const void *chunk, size_t size, void *ctx); + void *ctx; +}; - /* Called when a chunk of data has been read. */ - consume_data_callback_t consume_chunk; +/* Pass a chunk of data to the specified consume_chunk callback */ +static inline int +consume_chunk(const struct consume_chunk_callback *cb, + const void *chunk, size_t size) +{ + return (*cb->func)(chunk, size, cb->ctx); +} - /* Called when a stream has been fully read. A successful call to - * @begin_stream will always be matched by a call to @end_stream. */ - read_stream_list_end_stream_t end_stream; +/* Callback functions for reading blobs */ +struct read_blob_callbacks { + + /* Called when starting to read a blob. Must return 0 on success, or a + * positive wimlib error code on failure, or in the case of + * read_blob_list(), the special value BEGIN_BLOB_STATUS_SKIP_BLOB which + * indicates that the data for this blob should not be read. */ + int (*begin_blob)(struct blob_descriptor *blob, void *ctx); +#define BEGIN_BLOB_STATUS_SKIP_BLOB (-1) + + /* Called when the next chunk of uncompressed data is available. 'size' + * is guaranteed to be nonzero. Must return 0 on success, or a positive + * wimlib error code on failure. */ + int (*continue_blob)(const struct blob_descriptor *blob, u64 offset, + const void *chunk, size_t size, void *ctx); + + /* Called when a blob has been successfully read (status=0), or when + * begin_blob() was successfully called but an error occurred before the + * blob was fully read (status != 0; in this case the implementation + * should do cleanup and then pass on the status). Must return 0 on + * success, or a positive wimlib error code on failure. */ + int (*end_blob)(struct blob_descriptor *blob, int status, void *ctx); + + /* Parameter passed to each of the callback functions. */ + void *ctx; +}; - /* Parameter passed to @begin_stream. */ - void *begin_stream_ctx; +/* Call cbs->begin_blob() if present. */ +static inline int +call_begin_blob(struct blob_descriptor *blob, + const struct read_blob_callbacks *cbs) +{ + if (!cbs->begin_blob) + return 0; + return (*cbs->begin_blob)(blob, cbs->ctx); +} - /* Parameter passed to @consume_chunk. */ - void *consume_chunk_ctx; +/* Call cbs->continue_blob() if present. */ +static inline int +call_continue_blob(const struct blob_descriptor *blob, u64 offset, + const void *chunk, size_t size, + const struct read_blob_callbacks *cbs) +{ + if (!cbs->continue_blob) + return 0; + return (*cbs->continue_blob)(blob, offset, chunk, size, cbs->ctx); +} - /* Parameter passed to @end_stream. */ - void *end_stream_ctx; -}; +/* Call cbs->end_blob() if present. */ +static inline int +call_end_blob(struct blob_descriptor *blob, int status, + const struct read_blob_callbacks *cbs) +{ + if (!cbs->end_blob) + return status; + return (*cbs->end_blob)(blob, status, cbs->ctx); +} -/* Flags for read_stream_list() */ -#define VERIFY_STREAM_HASHES 0x1 -#define COMPUTE_MISSING_STREAM_HASHES 0x2 -#define STREAM_LIST_ALREADY_SORTED 0x4 +/* Flags for read_blob_list() */ +#define VERIFY_BLOB_HASHES 0x1 +#define COMPUTE_MISSING_BLOB_HASHES 0x2 +#define BLOB_LIST_ALREADY_SORTED 0x4 extern int -read_stream_list(struct list_head *stream_list, - size_t list_head_offset, - const struct read_stream_list_callbacks *cbs, - int flags); - -/* Functions to extract streams. */ +read_blob_list(struct list_head *blob_list, size_t list_head_offset, + const struct read_blob_callbacks *cbs, int flags); extern int -extract_stream(struct wim_lookup_table_entry *lte, - u64 size, - consume_data_callback_t extract_chunk, - void *extract_chunk_arg); +read_blob_with_cbs(struct blob_descriptor *blob, + const struct read_blob_callbacks *cbs); extern int -extract_stream_to_fd(struct wim_lookup_table_entry *lte, - struct filedes *fd, u64 size); +read_blob_with_sha1(struct blob_descriptor *blob, + const struct read_blob_callbacks *cbs); extern int -extract_full_stream_to_fd(struct wim_lookup_table_entry *lte, +extract_blob_prefix_to_fd(struct blob_descriptor *blob, u64 size, struct filedes *fd); extern int -extract_chunk_to_fd(const void *chunk, size_t size, void *_fd_p); +extract_blob_to_fd(struct blob_descriptor *blob, struct filedes *fd); -/* Miscellaneous stream functions. */ +/* Miscellaneous blob functions. */ extern int -sha1_stream(struct wim_lookup_table_entry *lte); +sha1_blob(struct blob_descriptor *blob); /* Functions to read/write metadata resources. */ extern int -read_metadata_resource(WIMStruct *wim, - struct wim_image_metadata *image_metadata); +read_metadata_resource(struct wim_image_metadata *imd); extern int write_metadata_resource(WIMStruct *wim, int image, int write_resource_flags); /* Definitions specific to pipable WIM resources. */ -/* Arbitrary number to begin each stream in the pipable WIM, used for sanity +/* Arbitrary number to begin each blob in the pipable WIM, used for sanity * checking. */ -#define PWM_STREAM_MAGIC 0x2b9b9ba2443db9d8ULL +#define PWM_BLOB_MAGIC 0x2b9b9ba2443db9d8ULL -/* Header that precedes each resource in a pipable WIM. */ -struct pwm_stream_hdr { +/* Header that precedes each blob in a pipable WIM. */ +struct pwm_blob_hdr { le64 magic; /* +0 */ le64 uncompressed_size; /* +8 */ u8 hash[SHA1_HASH_SIZE]; /* +16 */ @@ -316,11 +321,6 @@ struct pwm_stream_hdr { /* +40 */ } _packed_attribute; -/* Extra flag for the @flags field in `struct pipable_wim_stream_hdr': Indicates - * that the SHA1 message digest of the stream has not been calculated. - * Currently only used for the XML data. */ -#define PWM_RESHDR_FLAG_UNHASHED 0x100 - /* Header that precedes each chunk of a compressed resource in a pipable WIM. */ struct pwm_chunk_hdr {