]> wimlib.net Git - wimlib/blob - include/wimlib/resource.h
Rewrite of write_stream_list(), and writing packed resources
[wimlib] / include / wimlib / resource.h
1 #ifndef _WIMLIB_RESOURCE_H
2 #define _WIMLIB_RESOURCE_H
3
4 #include "wimlib/callback.h"
5 #include "wimlib/file_io.h"
6 #include "wimlib/list.h"
7 #include "wimlib/sha1.h"
8 #include "wimlib/types.h"
9
10 struct wim_lookup_table_entry;
11 struct wim_image_metadata;
12
13 /* Specification of a resource in a WIM file.
14  *
15  * If a `struct wim_lookup_table_entry' lte has
16  * (lte->resource_location == RESOURCE_IN_WIM), then lte->wim_res_spec points to
17  * an instance of this structure.
18  *
19  * Normally, there is a one-to-one correspondence between WIM lookup table
20  * entries ("streams", each of which may be the contents of a file, for example)
21  * and WIM resources.  However, WIM resources with the
22  * WIM_RESHDR_FLAG_PACKED_STREAMS flag set may actually contain multiple streams
23  * 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.  */
27         WIMStruct *wim;
28
29         /* The offset, in bytes, from the start of WIM file at which this
30          * resource starts.  */
31         u64 offset_in_wim;
32
33         /* The size of this resource in the WIM file.  For compressed resources
34          * this is the compressed size.  */
35         u64 size_in_wim;
36
37         /* The number of bytes of uncompressed data this resource decompresses
38          * to.  */
39         u64 uncompressed_size;
40
41         /* The list of streams this resource contains.  */
42         struct list_head stream_list;
43
44         /* Flags for this resource (WIM_RESHDR_FLAG_*)  */
45         u32 flags : 8;
46
47         /* This flag will be set if the WIM is pipable.  In such cases, the
48          * resource will be in a slightly different format if it is compressed.
49          * This is a wimlib extension.  */
50         u32 is_pipable : 1;
51
52         /* Temporary flag.  */
53         u32 raw_copy_ok : 1;
54 };
55
56 /* On-disk version of a WIM resource header.  */
57 struct wim_reshdr_disk {
58         /* Size of the resource as it appears in the WIM file (possibly
59          * compressed).  */
60         u8 size_in_wim[7];
61
62         /* Zero or more of the WIM_RESHDR_FLAG_* flags.  These indicate, for
63          * example, whether the resource is compressed or not.  */
64         u8 flags;
65
66         /* Offset of the resource from the start of the WIM file, in bytes.  */
67         le64 offset_in_wim;
68
69         /* Uncompressed size of the resource, in bytes.  */
70         le64 uncompressed_size;
71 } _packed_attribute;
72
73 /* In-memory version of a WIM resource header.  */
74 struct wim_reshdr {
75         u64 size_in_wim : 56;
76         u64 flags : 8;
77         u64 offset_in_wim;
78         u64 uncompressed_size;
79 };
80
81 /* Flags for the `flags' field of WIM resource headers.  */
82
83 /* Unknown meaning; may be intended to indicate spaces in the WIM that are free
84  * to overwrite.  Currently ignored by wimlib.  */
85 #define WIM_RESHDR_FLAG_FREE            0x01
86
87 /* The resource is a metadata resource for a WIM image, or is the lookup table
88  * or XML data for the WIM.  */
89 #define WIM_RESHDR_FLAG_METADATA        0x02
90
91 /* The resource is compressed using the WIM's default compression type and uses
92  * the regular chunk table format.  */
93 #define WIM_RESHDR_FLAG_COMPRESSED      0x04
94
95 /* Unknown meaning; may be intended to indicate a partial stream.  Currently
96  * ignored by wimlib.  */
97 #define WIM_RESHDR_FLAG_SPANNED         0x08
98
99 /* The resource is packed in a special format that may contain multiple
100  * underlying streams, or this resource entry represents a stream packed into
101  * one such resource.  When resources have this flag set, the WIM version number
102  * should be WIM_VERSION_PACKED_STREAMS.  */
103 #define WIM_RESHDR_FLAG_PACKED_STREAMS  0x10
104
105 /* Magic number in the 'uncompressed_size' field of the resource header that
106  * identifies the main entry for a pack.  */
107 #define WIM_PACK_MAGIC_NUMBER           0x100000000ULL
108
109 /* Returns true if the specified WIM resource is compressed, using either the
110  * original chunk table layout or the alternate layout for resources that may
111  * contain multiple packed streams.  */
112 static inline bool
113 resource_is_compressed(const struct wim_resource_spec *rspec)
114 {
115         return (rspec->flags & (WIM_RESHDR_FLAG_COMPRESSED |
116                                 WIM_RESHDR_FLAG_PACKED_STREAMS));
117 }
118
119 static inline void
120 copy_reshdr(struct wim_reshdr *dest, const struct wim_reshdr *src)
121 {
122         memcpy(dest, src, sizeof(struct wim_reshdr));
123 }
124
125 static inline void
126 zero_reshdr(struct wim_reshdr *reshdr)
127 {
128         memset(reshdr, 0, sizeof(struct wim_reshdr));
129 }
130
131 extern void
132 wim_res_hdr_to_spec(const struct wim_reshdr *reshdr, WIMStruct *wim,
133                     struct wim_resource_spec *rspec);
134
135 extern void
136 wim_res_spec_to_hdr(const struct wim_resource_spec *rspec,
137                     struct wim_reshdr *reshdr);
138
139 extern void
140 get_wim_reshdr(const struct wim_reshdr_disk *disk_reshdr,
141                struct wim_reshdr *reshdr);
142
143 void
144 put_wim_reshdr(const struct wim_reshdr *reshdr,
145                struct wim_reshdr_disk *disk_reshdr);
146
147 /* Alternate chunk table format for resources with
148  * WIM_RESHDR_FLAG_PACKED_STREAMS set.  */
149 struct alt_chunk_table_header_disk {
150         /* Uncompressed size of the resource in bytes.  */
151         le64 res_usize;
152
153         /* Number of bytes each compressed chunk decompresses into, except
154          * possibly the last which decompresses into the remainder.  */
155         le32 chunk_size;
156
157         /* Compression format used for compressed chunks:
158          * 0 = None
159          * 1 = LZX
160          * 2 = XPRESS
161          * 3 = LZMS  */
162         le32 compression_format;
163
164         /* This header is directly followed by a table of compressed sizes of
165          * the chunks.  */
166 } _packed_attribute;
167
168 /* wimlib internal flags used when writing resources.  */
169 #define WIMLIB_WRITE_RESOURCE_FLAG_RECOMPRESS           0x00000001
170 #define WIMLIB_WRITE_RESOURCE_FLAG_PIPABLE              0x00000002
171 #define WIMLIB_WRITE_RESOURCE_FLAG_PACK_STREAMS         0x00000004
172
173 /* Functions to read streams  */
174
175 extern int
176 read_partial_wim_stream_into_buf(const struct wim_lookup_table_entry *lte,
177                                  size_t size, u64 offset, void *buf);
178
179 extern int
180 read_full_stream_into_buf(const struct wim_lookup_table_entry *lte, void *buf);
181
182 extern int
183 read_full_stream_into_alloc_buf(const struct wim_lookup_table_entry *lte,
184                                 void **buf_ret);
185
186 extern int
187 wim_reshdr_to_data(const struct wim_reshdr *reshdr,
188                    WIMStruct *wim, void **buf_ret);
189
190 extern int
191 skip_wim_stream(struct wim_lookup_table_entry *lte);
192
193 extern int
194 read_stream_prefix(const struct wim_lookup_table_entry *lte,
195                    u64 size, consume_data_callback_t cb,
196                    void *cb_ctx);
197
198 typedef int (*read_stream_list_begin_stream_t)(struct wim_lookup_table_entry *lte,
199                                                bool is_partial_res,
200                                                void *ctx);
201 typedef int (*read_stream_list_end_stream_t)(struct wim_lookup_table_entry *lte,
202                                              int status,
203                                              void *ctx);
204
205 #define VERIFY_STREAM_HASHES            0x1
206 #define COMPUTE_MISSING_STREAM_HASHES   0x2
207 #define STREAM_LIST_ALREADY_SORTED      0x4
208 #define BEGIN_STREAM_STATUS_SKIP_STREAM         -1
209
210 /* Callback functions and contexts for read_stream_list().  */
211 struct read_stream_list_callbacks {
212
213         /* Called when a stream is about to be read.  */
214         read_stream_list_begin_stream_t begin_stream;
215
216         /* Called when a chunk of data has been read.  */
217         consume_data_callback_t consume_chunk;
218
219         /* Called when a stream has been fully read.  */
220         read_stream_list_end_stream_t end_stream;
221
222         /* Parameter passed to @begin_stream.  */
223         void *begin_stream_ctx;
224
225         /* Parameter passed to @consume_chunk.  */
226         void *consume_chunk_ctx;
227
228         /* Parameter passed to @end_stream.  */
229         void *end_stream_ctx;
230 };
231
232 extern int
233 read_stream_list(struct list_head *stream_list,
234                  size_t list_head_offset,
235                  const struct read_stream_list_callbacks *cbs,
236                  int flags);
237
238 /* Functions to extract streams.  */
239
240 extern int
241 extract_stream(struct wim_lookup_table_entry *lte,
242                u64 size,
243                consume_data_callback_t extract_chunk,
244                void *extract_chunk_arg);
245
246 extern int
247 extract_stream_to_fd(struct wim_lookup_table_entry *lte,
248                      struct filedes *fd, u64 size);
249
250 extern int
251 extract_chunk_to_fd(const void *chunk, size_t size, void *_fd_p);
252
253 /* Miscellaneous stream functions.  */
254
255 extern int
256 sha1_stream(struct wim_lookup_table_entry *lte);
257
258 /* Functions to read/write metadata resources.  */
259
260 extern int
261 read_metadata_resource(WIMStruct *wim,
262                        struct wim_image_metadata *image_metadata);
263
264 extern int
265 write_metadata_resource(WIMStruct *wim, int image, int write_resource_flags);
266
267 /* Definitions specific to pipable WIM resources.  */
268
269 /* Arbitrary number to begin each stream in the pipable WIM, used for sanity
270  * checking.  */
271 #define PWM_STREAM_MAGIC 0x2b9b9ba2443db9d8ULL
272
273 /* Header that precedes each resource in a pipable WIM.  */
274 struct pwm_stream_hdr {
275         le64 magic;                     /* +0   */
276         le64 uncompressed_size;         /* +8   */
277         u8 hash[SHA1_HASH_SIZE];        /* +16  */
278         le32 flags;                     /* +36  */
279                                         /* +40  */
280 } _packed_attribute;
281
282 /* Extra flag for the @flags field in `struct pipable_wim_stream_hdr': Indicates
283  * that the SHA1 message digest of the stream has not been calculated.
284  * Currently only used for the XML data.  */
285 #define PWM_RESHDR_FLAG_UNHASHED         0x100
286
287 /* Header that precedes each chunk of a compressed resource in a pipable WIM.
288  */
289 struct pwm_chunk_hdr {
290         le32 compressed_size;
291 } _packed_attribute;
292
293 #endif /* _WIMLIB_RESOURCE_H */