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"
10 struct wim_lookup_table_entry;
11 struct wim_image_metadata;
14 * Specification of a resource in a WIM file.
16 * If a `struct wim_lookup_table_entry' lte has (lte->resource_location ==
17 * RESOURCE_IN_WIM), then lte->rspec points to an instance of this structure.
19 * Normally, there is a one-to-one correspondence between lookup table entries
20 * ("streams", each of which may be the contents of a file, for example) and
21 * resources. However, a resource with the WIM_RESHDR_FLAG_SOLID flag set is a
22 * "solid" resource that may contain multiple streams compressed together.
24 struct wim_resource_spec {
25 /* The WIM containing this resource. @wim->in_fd is expected to be a
26 * file descriptor to the underlying WIM file, opened for reading. */
29 /* The offset, in bytes, from the start of WIM file at which this
33 /* The size of this resource in the WIM file. For compressed resources
34 * this is the compressed size, including overhead such as the chunk
38 /* The number of bytes of uncompressed data this resource decompresses
40 u64 uncompressed_size;
42 /* The list of streams this resource contains. */
43 struct list_head stream_list;
45 /* Flags for this resource (WIM_RESHDR_FLAG_*). */
48 /* [wimlib extension] This flag will be set if the WIM is pipable. In
49 * such cases, the resource will be in a slightly different format if it
56 /* Compression type of this resource. */
57 u32 compression_type : 22;
59 /* Compression chunk size of this resource. Irrelevant if the resource
64 /* On-disk version of a WIM resource header. */
65 struct wim_reshdr_disk {
66 /* Size of the resource as it appears in the WIM file (possibly
70 /* Zero or more of the WIM_RESHDR_FLAG_* flags. These indicate, for
71 * example, whether the resource is compressed or not. */
74 /* Offset of the resource from the start of the WIM file, in bytes. */
77 /* Uncompressed size of the resource, in bytes. */
78 le64 uncompressed_size;
81 /* In-memory version of a WIM resource header (`struct wim_reshdr_disk'). */
86 u64 uncompressed_size;
89 /* Flags for the `flags' field of WIM resource headers (`struct wim_reshdr').
92 /* Unknown meaning; may be intended to indicate spaces in the WIM that are free
93 * to overwrite. Currently ignored by wimlib. */
94 #define WIM_RESHDR_FLAG_FREE 0x01
96 /* The resource is a metadata resource for a WIM image, or is the lookup table
97 * or XML data for the WIM. */
98 #define WIM_RESHDR_FLAG_METADATA 0x02
100 /* The resource is a non-solid resource compressed using the WIM's default
101 * compression type. */
102 #define WIM_RESHDR_FLAG_COMPRESSED 0x04
104 /* Unknown meaning; may be intended to indicate a partial stream. Currently
105 * ignored by wimlib. */
106 #define WIM_RESHDR_FLAG_SPANNED 0x08
108 /* The resource is a solid compressed resource which may contain multiple
109 * streams. This flag is only allowed if the WIM version number is
110 * WIM_VERSION_SOLID. */
111 #define WIM_RESHDR_FLAG_SOLID 0x10
113 /* Magic number in the 'uncompressed_size' field of the resource header that
114 * identifies the main entry for a solid resource. */
115 #define SOLID_RESOURCE_MAGIC_NUMBER 0x100000000ULL
117 /* Returns true if the specified WIM resource is compressed (may be either solid
120 resource_is_compressed(const struct wim_resource_spec *rspec)
122 return (rspec->flags & (WIM_RESHDR_FLAG_COMPRESSED |
123 WIM_RESHDR_FLAG_SOLID));
127 copy_reshdr(struct wim_reshdr *dest, const struct wim_reshdr *src)
129 memcpy(dest, src, sizeof(struct wim_reshdr));
133 zero_reshdr(struct wim_reshdr *reshdr)
135 memset(reshdr, 0, sizeof(struct wim_reshdr));
139 wim_res_hdr_to_spec(const struct wim_reshdr *reshdr, WIMStruct *wim,
140 struct wim_resource_spec *rspec);
143 wim_res_spec_to_hdr(const struct wim_resource_spec *rspec,
144 struct wim_reshdr *reshdr);
147 get_wim_reshdr(const struct wim_reshdr_disk *disk_reshdr,
148 struct wim_reshdr *reshdr);
151 put_wim_reshdr(const struct wim_reshdr *reshdr,
152 struct wim_reshdr_disk *disk_reshdr);
154 /* Alternate chunk table format for resources with WIM_RESHDR_FLAG_SOLID set.
156 struct alt_chunk_table_header_disk {
157 /* Uncompressed size of the resource in bytes. */
160 /* Number of bytes each compressed chunk decompresses into, except
161 * possibly the last which decompresses into the remainder. This
162 * overrides the chunk size specified by the WIM header. */
165 /* Compression format used for compressed chunks:
171 * This overrides the compression type specified by the WIM header. */
172 le32 compression_format;
174 /* This header is directly followed by a table of compressed sizes of
175 * the chunks (4 bytes per entry). */
178 static inline unsigned int
179 get_chunk_entry_size(u64 res_size, bool is_alt)
181 if (res_size <= UINT32_MAX || is_alt)
187 /* Functions to read streams */
190 read_partial_wim_stream_into_buf(const struct wim_lookup_table_entry *lte,
191 size_t size, u64 offset, void *buf);
194 read_full_stream_into_buf(const struct wim_lookup_table_entry *lte, void *buf);
197 read_full_stream_into_alloc_buf(const struct wim_lookup_table_entry *lte,
201 wim_reshdr_to_data(const struct wim_reshdr *reshdr,
202 WIMStruct *wim, void **buf_ret);
205 wim_reshdr_to_hash(const struct wim_reshdr *reshdr, WIMStruct *wim,
206 u8 hash[SHA1_HASH_SIZE]);
209 skip_wim_stream(struct wim_lookup_table_entry *lte);
212 * Type of callback function for beginning to read a stream.
215 * Stream that is about to be read.
218 * User-provided context.
220 * Must return 0 on success, a positive error code on failure, or the special
221 * value BEGIN_STREAM_STATUS_SKIP_STREAM to indicate that the stream should not
222 * be read, and read_stream_list() should continue on to the next stream
223 * (without calling @consume_chunk or @end_stream).
225 typedef int (*read_stream_list_begin_stream_t)(struct wim_lookup_table_entry *lte,
228 #define BEGIN_STREAM_STATUS_SKIP_STREAM -1
231 * Type of callback function for finishing reading a stream.
234 * Stream that has been fully read, or stream that started being read but
235 * could not be fully read due to a read error.
238 * 0 if reading the stream was successful; otherwise a nonzero error code
239 * that specifies the return status.
242 * User-provided context.
244 typedef int (*read_stream_list_end_stream_t)(struct wim_lookup_table_entry *lte,
249 /* Callback functions and contexts for read_stream_list(). */
250 struct read_stream_list_callbacks {
252 /* Called when a stream is about to be read. */
253 read_stream_list_begin_stream_t begin_stream;
255 /* Called when a chunk of data has been read. */
256 consume_data_callback_t consume_chunk;
258 /* Called when a stream has been fully read. A successful call to
259 * @begin_stream will always be matched by a call to @end_stream. */
260 read_stream_list_end_stream_t end_stream;
262 /* Parameter passed to @begin_stream. */
263 void *begin_stream_ctx;
265 /* Parameter passed to @consume_chunk. */
266 void *consume_chunk_ctx;
268 /* Parameter passed to @end_stream. */
269 void *end_stream_ctx;
272 /* Flags for read_stream_list() */
273 #define VERIFY_STREAM_HASHES 0x1
274 #define COMPUTE_MISSING_STREAM_HASHES 0x2
275 #define STREAM_LIST_ALREADY_SORTED 0x4
278 read_stream_list(struct list_head *stream_list,
279 size_t list_head_offset,
280 const struct read_stream_list_callbacks *cbs,
283 /* Functions to extract streams. */
286 extract_stream(struct wim_lookup_table_entry *lte,
288 consume_data_callback_t extract_chunk,
289 void *extract_chunk_arg);
292 extract_stream_to_fd(struct wim_lookup_table_entry *lte,
293 struct filedes *fd, u64 size);
296 extract_full_stream_to_fd(struct wim_lookup_table_entry *lte,
299 /* Miscellaneous stream functions. */
302 sha1_stream(struct wim_lookup_table_entry *lte);
304 /* Functions to read/write metadata resources. */
307 read_metadata_resource(struct wim_image_metadata *imd);
310 write_metadata_resource(WIMStruct *wim, int image, int write_resource_flags);
312 /* Definitions specific to pipable WIM resources. */
314 /* Arbitrary number to begin each stream in the pipable WIM, used for sanity
316 #define PWM_STREAM_MAGIC 0x2b9b9ba2443db9d8ULL
318 /* Header that precedes each resource in a pipable WIM. */
319 struct pwm_stream_hdr {
321 le64 uncompressed_size; /* +8 */
322 u8 hash[SHA1_HASH_SIZE]; /* +16 */
323 le32 flags; /* +36 */
327 /* Extra flag for the @flags field in `struct pipable_wim_stream_hdr': Indicates
328 * that the SHA1 message digest of the stream has not been calculated.
329 * Currently only used for the XML data. */
330 #define PWM_RESHDR_FLAG_UNHASHED 0x100
332 /* Header that precedes each chunk of a compressed resource in a pipable WIM.
334 struct pwm_chunk_hdr {
335 le32 compressed_size;
338 #endif /* _WIMLIB_RESOURCE_H */