X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=include%2Fwimlib%2Fresource.h;h=39b32dec89af13d9bc1802b3939eccebcbe022cd;hp=249b0bc8d590f9ed992692bc46b02745d44f9490;hb=b2eba082865fb3bec25cdedaf617bc4d209407f8;hpb=c5746b5e79df3d5c129f6185cf5fa130ab0512df diff --git a/include/wimlib/resource.h b/include/wimlib/resource.h index 249b0bc8..39b32dec 100644 --- a/include/wimlib/resource.h +++ b/include/wimlib/resource.h @@ -1,82 +1,81 @@ #ifndef _WIMLIB_RESOURCE_H #define _WIMLIB_RESOURCE_H -#include "wimlib/types.h" -#include "wimlib/endianness.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") and WIM resources. However, the flag - * WIM_RESHDR_FLAG_CONCAT can be used to specify that two streams be combined - * into the same resource and compressed together. Caveats about this flag are - * noted in the comment above the definition of WIM_VERSION_STREAM_CONCAT. */ -struct wim_resource_spec { - /* The WIM file containing this resource. */ +/* + * 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; - /* Offset, in bytes, from the start of WIM file at which this resource - * starts. */ + /* The offset, in bytes, from the start of WIM file at which this + * resource starts. */ u64 offset_in_wim; /* The size of this resource in the WIM file. For compressed resources - * this is the compressed size. */ + * this is the compressed size, including overhead such as the chunk + * table. */ u64 size_in_wim; - /* Number of bytes of uncompressed data this resource uncompresses to. - */ + /* The number of bytes of uncompressed data this resource decompresses + * to. */ u64 uncompressed_size; - /* List of streams this resource contains. */ - struct list_head lte_list; + /* The list of blobs this resource contains. */ + struct list_head blob_list; - /* Resource flags. */ + /* Flags for this resource (WIM_RESHDR_FLAG_*). */ u32 flags : 8; - /* This flag will be set if the WIM is pipable and therefore the - * resource will be in a slightly different format if it is compressed - * (wimlib extension). */ + /* [wimlib extension] This flag will be set if the WIM is pipable. In + * such cases, the resource will be in a slightly different format if it + * is compressed. */ u32 is_pipable : 1; - /* Compression type of this resource as one of WIMLIB_COMPRESSION_TYPE_* - * constants. */ - u32 ctype : 3; + /* Temporary flag. */ + u32 raw_copy_ok : 1; - /* Compression chunk size. */ - u32 cchunk_size; -}; + /* 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: This structure specifies the - * location, size, and flags (e.g. compressed or not compressed) for a resource - * in the WIM file. */ +/* On-disk version of a WIM resource header. */ struct wim_reshdr_disk { /* Size of the resource as it appears in the WIM file (possibly * compressed). */ u8 size_in_wim[7]; - /* WIM_RESHDR_FLAG_* flags. */ + /* Zero or more of the WIM_RESHDR_FLAG_* flags. These indicate, for + * example, whether the resource is compressed or not. */ u8 flags; - /* Offset of the resource from the start of the WIM file. */ + /* Offset of the resource from the start of the WIM file, in bytes. */ le64 offset_in_wim; - /* Uncompressed size of the resource. */ + /* Uncompressed size of the resource, in bytes. */ le64 uncompressed_size; } _packed_attribute; -/* In-memory version of wim_reshdr_disk. */ +/* In-memory version of a WIM resource header (`struct wim_reshdr_disk'). */ struct wim_reshdr { u64 size_in_wim : 56; u64 flags : 8; @@ -84,31 +83,39 @@ struct wim_reshdr { u64 uncompressed_size; }; -/* Flags for the `flags' field of the struct resource_entry structure. */ +/* Flags for the `flags' field of WIM resource headers (`struct wim_reshdr'). + */ -/* I haven't seen this flag used in any of the WIMs I have examined. I assume - * it means that there are no references to the stream, so the space is free. - * However, even after deleting files from a WIM mounted with `imagex.exe - * /mountrw', I could not see this flag being used. Either way, wimlib doesn't - * actually use this flag for anything. */ +/* Unknown meaning; currently ignored by wimlib. */ #define WIM_RESHDR_FLAG_FREE 0x01 -/* Indicates that the stream is a metadata resource for a WIM image. This flag - * is also set in the resource entry for the lookup table in the WIM header. */ +/* 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 -/* Indicates that the stream is compressed (using the WIM's set compression - * type). */ +/* The resource is a non-solid resource compressed using the WIM's default + * compression type. */ #define WIM_RESHDR_FLAG_COMPRESSED 0x04 -/* I haven't seen this flag used in any of the WIMs I have examined. Perhaps it - * means that a stream could possibly be split among multiple split WIM parts. - * However, `imagex.exe /split' does not seem to create any WIMs like this. - * Either way, wimlib doesn't actually use this flag for anything. */ +/* Unknown meaning; currently ignored by wimlib. */ #define WIM_RESHDR_FLAG_SPANNED 0x08 -/* TODO */ -#define WIM_RESHDR_FLAG_CONCAT 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 solid resource. */ +#define SOLID_RESOURCE_MAGIC_NUMBER 0x100000000ULL + +/* Returns true if the specified WIM resource is compressed (may be either solid + * or non-solid) */ +static inline bool +resource_is_compressed(const struct wim_resource_descriptor *rdesc) +{ + return (rdesc->flags & (WIM_RESHDR_FLAG_COMPRESSED | + WIM_RESHDR_FLAG_SOLID)); +} static inline void copy_reshdr(struct wim_reshdr *dest, const struct wim_reshdr *src) @@ -122,16 +129,11 @@ zero_reshdr(struct wim_reshdr *reshdr) memset(reshdr, 0, sizeof(struct wim_reshdr)); } - extern void -wim_res_hdr_to_spec(const struct wim_reshdr *reshdr, WIMStruct *wim, - struct wim_resource_spec *rspec); +wim_res_hdr_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); - -extern int get_wim_reshdr(const struct wim_reshdr_disk *disk_reshdr, struct wim_reshdr *reshdr); @@ -139,93 +141,164 @@ void put_wim_reshdr(const struct wim_reshdr *reshdr, struct wim_reshdr_disk *disk_reshdr); -/* wimlib internal flags used when reading or writing resources. */ -#define WIMLIB_WRITE_RESOURCE_FLAG_RECOMPRESS 0x00000001 -#define WIMLIB_WRITE_RESOURCE_FLAG_PIPABLE 0x00000002 -#define WIMLIB_WRITE_RESOURCE_MASK 0x0000ffff - -#define WIMLIB_READ_RESOURCE_FLAG_RAW_FULL 0x80000000 -#define WIMLIB_READ_RESOURCE_FLAG_RAW_CHUNKS 0x40000000 -#define WIMLIB_READ_RESOURCE_FLAG_RAW (WIMLIB_READ_RESOURCE_FLAG_RAW_FULL | \ - WIMLIB_READ_RESOURCE_FLAG_RAW_CHUNKS) -#define WIMLIB_READ_RESOURCE_MASK 0xffff0000 +/* 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; + + /* Number of bytes each compressed chunk decompresses into, except + * possibly the last which decompresses into the remainder. This + * overrides the chunk size specified by the WIM header. */ + le32 chunk_size; + + /* Compression format used for compressed chunks: + * 0 = None + * 1 = XPRESS + * 2 = LZX + * 3 = LZMS + * + * This overrides the compression type specified by the WIM header. */ + le32 compression_format; + + /* This header is directly followed by a table of compressed sizes of + * the chunks (4 bytes per entry). */ +} _packed_attribute; +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; +} -/* Functions to read a resource. */ +/* Functions to read blobs */ extern int -read_partial_wim_resource(const struct wim_lookup_table_entry *lte, - u64 size, consume_data_callback_t cb, - u32 in_chunk_size, void *ctx_or_buf, - int flags, u64 offset); +read_partial_wim_blob_into_buf(const struct blob_descriptor *blob, + size_t size, u64 offset, void *buf); extern int -read_partial_wim_stream_into_buf(const struct wim_lookup_table_entry *lte, - size_t size, u64 offset, void *buf); -extern int -read_full_stream_into_buf(const struct wim_lookup_table_entry *lte, void *buf); +read_full_blob_into_buf(const struct blob_descriptor *blob, void *buf); extern int -read_full_stream_into_alloc_buf(const struct wim_lookup_table_entry *lte, - void **buf_ret); +read_full_blob_into_alloc_buf(const struct blob_descriptor *blob, void **buf_ret); extern int wim_reshdr_to_data(const struct wim_reshdr *reshdr, WIMStruct *wim, void **buf_ret); extern int -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); +wim_reshdr_to_hash(const struct wim_reshdr *reshdr, WIMStruct *wim, + u8 hash[SHA1_HASH_SIZE]); + +extern int +skip_wim_resource(struct wim_resource_descriptor *rdesc); -/* Functions to read a list of resources. */ +/* + * Type of callback function for beginning to read a blob. + * + * @blob: + * Blob that is about to be read. + * + * @ctx: + * User-provided context. + * + * Must return 0 on success, a positive error code on failure, or the special + * value BEGIN_BLOB_STATUS_SKIP_BLOB to indicate that the blob should not be + * read, and read_blob_list() should continue on to the next blob (without + * calling @consume_chunk or @end_blob). + */ +typedef int (*read_blob_list_begin_blob_t)(struct blob_descriptor *blob, void *ctx); + +#define BEGIN_BLOB_STATUS_SKIP_BLOB -1 + +/* + * Type of callback function for finishing reading a blob. + * + * @blob: + * Blob that has been fully read, or blob that started being read but could + * not be fully read due to a read error. + * + * @status: + * 0 if reading the blob was successful; otherwise a nonzero error code + * that specifies the return status. + * + * @ctx: + * User-provided context. + */ +typedef int (*read_blob_list_end_blob_t)(struct blob_descriptor *blob, + int status, + void *ctx); + + +/* Callback functions and contexts for read_blob_list(). */ +struct read_blob_list_callbacks { -typedef int (*read_stream_list_begin_stream_t)(struct wim_lookup_table_entry *lte, void *ctx); -typedef int (*read_stream_list_end_stream_t)(struct wim_lookup_table_entry *lte, void *ctx); + /* Called when a blob is about to be read. */ + read_blob_list_begin_blob_t begin_blob; + + /* Called when a chunk of data has been read. */ + consume_data_callback_t consume_chunk; + + /* Called when a blob has been fully read. A successful call to + * @begin_blob will always be matched by a call to @end_blob. */ + read_blob_list_end_blob_t end_blob; + + /* Parameter passed to @begin_blob. */ + void *begin_blob_ctx; + + /* Parameter passed to @consume_chunk. */ + void *consume_chunk_ctx; + + /* Parameter passed to @end_blob. */ + void *end_blob_ctx; +}; + +/* 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, - read_stream_list_begin_stream_t begin_stream, - consume_data_callback_t consume_chunk, - read_stream_list_end_stream_t end_stream, - u32 cb_chunk_size, - void *cb_ctx); +read_blob_list(struct list_head *blob_list, size_t list_head_offset, + const struct read_blob_list_callbacks *cbs, int flags); + +/* Functions to extract blobs. */ -/* Functions to extract a resource. */ +extern int +extract_blob(struct blob_descriptor *blob, u64 size, + consume_data_callback_t extract_chunk, void *extract_chunk_arg); extern int -extract_stream(const struct wim_lookup_table_entry *lte, - u64 size, - consume_data_callback_t extract_chunk, - void *extract_chunk_arg); +extract_blob_to_fd(struct blob_descriptor *blob, struct filedes *fd, u64 size); extern int -extract_stream_to_fd(const struct wim_lookup_table_entry *lte, - struct filedes *fd, u64 size); +extract_full_blob_to_fd(struct blob_descriptor *blob, struct filedes *fd); -/* Miscellaneous resource 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 */ @@ -233,16 +306,10 @@ 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 { le32 compressed_size; } _packed_attribute; - #endif /* _WIMLIB_RESOURCE_H */