1 #ifndef _WIMLIB_RESOURCE_H
2 #define _WIMLIB_RESOURCE_H
4 #include "wimlib/callback.h"
5 #include "wimlib/list.h"
6 #include "wimlib/sha1.h"
7 #include "wimlib/types.h"
9 struct blob_descriptor;
11 struct wim_image_metadata;
14 * Description of a "resource" in a WIM file. A "resource" is a standalone,
15 * possibly compressed region of data. Normally, there is a one-to-one
16 * correspondence between "blobs" (each of which may be the contents of a file,
17 * for example) and resources. However, a resource with the
18 * WIM_RESHDR_FLAG_SOLID flag set is a "solid" resource that contains multiple
19 * blobs compressed together.
21 struct wim_resource_descriptor {
22 /* The WIM containing this resource. @wim->in_fd is expected to be a
23 * file descriptor to the underlying WIM file, opened for reading. */
26 /* The offset, in bytes, from the start of WIM file at which this
30 /* The size of this resource in the WIM file. For compressed resources
31 * this is the compressed size, including overhead such as the chunk
35 /* The number of bytes of uncompressed data this resource decompresses
37 u64 uncompressed_size;
39 /* The list of blobs this resource contains. */
40 struct list_head blob_list;
42 /* Flags for this resource (WIM_RESHDR_FLAG_*). */
45 /* [wimlib extension] This flag will be set if the WIM is pipable. In
46 * such cases, the resource will be in a slightly different format if it
53 /* Compression type of this resource. */
54 u32 compression_type : 22;
56 /* Compression chunk size of this resource. Irrelevant if the resource
61 /* On-disk version of a WIM resource header. */
62 struct wim_reshdr_disk {
63 /* Size of the resource as it appears in the WIM file (possibly
67 /* Zero or more of the WIM_RESHDR_FLAG_* flags. These indicate, for
68 * example, whether the resource is compressed or not. */
71 /* Offset of the resource from the start of the WIM file, in bytes. */
74 /* Uncompressed size of the resource, in bytes. */
75 le64 uncompressed_size;
78 /* In-memory version of a WIM resource header (`struct wim_reshdr_disk'). */
83 u64 uncompressed_size;
86 /* Flags for the `flags' field of WIM resource headers (`struct wim_reshdr').
89 /* Unknown meaning; currently ignored by wimlib. */
90 #define WIM_RESHDR_FLAG_FREE 0x01
92 /* The resource is a metadata resource for a WIM image, or is the blob table or
93 * XML data for the WIM. */
94 #define WIM_RESHDR_FLAG_METADATA 0x02
96 /* The resource is a non-solid resource compressed using the WIM's default
97 * compression type. */
98 #define WIM_RESHDR_FLAG_COMPRESSED 0x04
100 /* Unknown meaning; currently ignored by wimlib. */
101 #define WIM_RESHDR_FLAG_SPANNED 0x08
103 /* The resource is a solid compressed resource which may contain multiple blobs.
104 * This flag is only allowed if the WIM version number is WIM_VERSION_SOLID. */
105 #define WIM_RESHDR_FLAG_SOLID 0x10
107 /* Magic number in the 'uncompressed_size' field of the resource header that
108 * identifies the main entry for a solid resource. */
109 #define SOLID_RESOURCE_MAGIC_NUMBER 0x100000000ULL
111 /* Returns true if the specified WIM resource is compressed (may be either solid
114 resource_is_compressed(const struct wim_resource_descriptor *rdesc)
116 return (rdesc->flags & (WIM_RESHDR_FLAG_COMPRESSED |
117 WIM_RESHDR_FLAG_SOLID));
121 copy_reshdr(struct wim_reshdr *dest, const struct wim_reshdr *src)
123 memcpy(dest, src, sizeof(struct wim_reshdr));
127 zero_reshdr(struct wim_reshdr *reshdr)
129 memset(reshdr, 0, sizeof(struct wim_reshdr));
133 wim_res_hdr_to_desc(const struct wim_reshdr *reshdr, WIMStruct *wim,
134 struct wim_resource_descriptor *rdesc);
137 wim_res_desc_to_hdr(const struct wim_resource_descriptor *rdesc,
138 struct wim_reshdr *reshdr);
141 get_wim_reshdr(const struct wim_reshdr_disk *disk_reshdr,
142 struct wim_reshdr *reshdr);
145 put_wim_reshdr(const struct wim_reshdr *reshdr,
146 struct wim_reshdr_disk *disk_reshdr);
148 /* Alternate chunk table format for resources with WIM_RESHDR_FLAG_SOLID set.
150 struct alt_chunk_table_header_disk {
151 /* Uncompressed size of the resource in bytes. */
154 /* Number of bytes each compressed chunk decompresses into, except
155 * possibly the last which decompresses into the remainder. This
156 * overrides the chunk size specified by the WIM header. */
159 /* Compression format used for compressed chunks:
165 * This overrides the compression type specified by the WIM header. */
166 le32 compression_format;
168 /* This header is directly followed by a table of compressed sizes of
169 * the chunks (4 bytes per entry). */
172 static inline unsigned int
173 get_chunk_entry_size(u64 res_size, bool is_alt)
175 if (res_size <= UINT32_MAX || is_alt)
181 /* Functions to read blobs */
184 read_partial_wim_blob_into_buf(const struct blob_descriptor *blob,
185 size_t size, u64 offset, void *buf);
188 read_full_blob_into_buf(const struct blob_descriptor *blob, void *buf);
191 read_full_blob_into_alloc_buf(const struct blob_descriptor *blob, void **buf_ret);
194 wim_reshdr_to_data(const struct wim_reshdr *reshdr,
195 WIMStruct *wim, void **buf_ret);
198 wim_reshdr_to_hash(const struct wim_reshdr *reshdr, WIMStruct *wim,
199 u8 hash[SHA1_HASH_SIZE]);
202 skip_wim_resource(struct wim_resource_descriptor *rdesc);
205 * Type of callback function for beginning to read a blob.
208 * Blob that is about to be read.
211 * User-provided context.
213 * Must return 0 on success, a positive error code on failure, or the special
214 * value BEGIN_BLOB_STATUS_SKIP_BLOB to indicate that the blob should not be
215 * read, and read_blob_list() should continue on to the next blob (without
216 * calling @consume_chunk or @end_blob).
218 typedef int (*read_blob_list_begin_blob_t)(struct blob_descriptor *blob, void *ctx);
220 #define BEGIN_BLOB_STATUS_SKIP_BLOB -1
223 * Type of callback function for finishing reading a blob.
226 * Blob that has been fully read, or blob that started being read but could
227 * not be fully read due to a read error.
230 * 0 if reading the blob was successful; otherwise a nonzero error code
231 * that specifies the return status.
234 * User-provided context.
236 typedef int (*read_blob_list_end_blob_t)(struct blob_descriptor *blob,
241 /* Callback functions and contexts for read_blob_list(). */
242 struct read_blob_list_callbacks {
244 /* Called when a blob is about to be read. */
245 read_blob_list_begin_blob_t begin_blob;
247 /* Called when a chunk of data has been read. */
248 consume_data_callback_t consume_chunk;
250 /* Called when a blob has been fully read. A successful call to
251 * @begin_blob will always be matched by a call to @end_blob. */
252 read_blob_list_end_blob_t end_blob;
254 /* Parameter passed to @begin_blob. */
255 void *begin_blob_ctx;
257 /* Parameter passed to @consume_chunk. */
258 void *consume_chunk_ctx;
260 /* Parameter passed to @end_blob. */
264 /* Flags for read_blob_list() */
265 #define VERIFY_BLOB_HASHES 0x1
266 #define COMPUTE_MISSING_BLOB_HASHES 0x2
267 #define BLOB_LIST_ALREADY_SORTED 0x4
270 read_blob_list(struct list_head *blob_list, size_t list_head_offset,
271 const struct read_blob_list_callbacks *cbs, int flags);
273 /* Functions to extract blobs. */
276 extract_blob(struct blob_descriptor *blob, u64 size,
277 consume_data_callback_t extract_chunk, void *extract_chunk_arg);
280 extract_blob_to_fd(struct blob_descriptor *blob, struct filedes *fd, u64 size);
283 extract_full_blob_to_fd(struct blob_descriptor *blob, struct filedes *fd);
285 /* Miscellaneous blob functions. */
288 sha1_blob(struct blob_descriptor *blob);
290 /* Functions to read/write metadata resources. */
293 read_metadata_resource(struct wim_image_metadata *imd);
296 write_metadata_resource(WIMStruct *wim, int image, int write_resource_flags);
298 /* Definitions specific to pipable WIM resources. */
300 /* Arbitrary number to begin each blob in the pipable WIM, used for sanity
302 #define PWM_BLOB_MAGIC 0x2b9b9ba2443db9d8ULL
304 /* Header that precedes each resource in a pipable WIM. */
305 struct pwm_blob_hdr {
307 le64 uncompressed_size; /* +8 */
308 u8 hash[SHA1_HASH_SIZE]; /* +16 */
309 le32 flags; /* +36 */
313 /* Extra flag for the @flags field in `struct pwm_blob_hdr': Indicates that the
314 * SHA-1 message digest of the stream has not been calculated. Currently only
315 * used for the XML data. */
316 #define PWM_RESHDR_FLAG_UNHASHED 0x100
318 /* Header that precedes each chunk of a compressed resource in a pipable WIM.
320 struct pwm_chunk_hdr {
321 le32 compressed_size;
324 #endif /* _WIMLIB_RESOURCE_H */