1d68649d182d02afcff9a96db18de5d403a73dd5
[wimlib] / include / wimlib / resource.h
1 #ifndef _WIMLIB_RESOURCE_H
2 #define _WIMLIB_RESOURCE_H
3
4 #include "wimlib/types.h"
5 #include "wimlib/endianness.h"
6 #include "wimlib/callback.h"
7 #include "wimlib/file_io.h"
8 #include "wimlib/list.h"
9 #include "wimlib/sha1.h"
10
11 struct wim_lookup_table_entry;
12 struct wim_image_metadata;
13
14 /* Specification of a resource in a WIM file.
15  *
16  * If a `struct wim_lookup_table_entry' lte has
17  * (lte->resource_location == RESOURCE_IN_WIM), then lte->wim_res_spec points to
18  * an instance of this structure.
19  *
20  * Normally, there is a one-to-one correspondence between WIM lookup table
21  * entries ("streams") and WIM resources.  However, the flag
22  * WIM_RESHDR_FLAG_CONCAT can be used to specify that two streams be combined
23  * into the same resource and compressed together.  Caveats about this flag are
24  * noted in the comment above the definition of WIM_VERSION_STREAM_CONCAT.  */
25 struct wim_resource_spec {
26         /* The WIM file containing this resource.  */
27         WIMStruct *wim;
28
29         /* Offset, in bytes, from the start of WIM file at which this resource
30          * 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         /* Number of bytes of uncompressed data this resource uncompresses to.
38          */
39         u64 uncompressed_size;
40
41         /* List of streams this resource contains.  */
42         struct list_head lte_list;
43
44         /* Resource flags.  */
45         u32 flags : 8;
46
47         /* This flag will be set if the WIM is pipable and therefore the
48          * resource will be in a slightly different format if it is compressed
49          * (wimlib extension).  */
50         u32 is_pipable : 1;
51
52         /* Compression type of this resource as one of WIMLIB_COMPRESSION_TYPE_*
53          * constants.  */
54         u32 ctype : 3;
55
56         /* Compression chunk size.  */
57         u32 cchunk_size;
58 };
59
60
61 /* On-disk version of a WIM resource header:  This structure specifies the
62  * location, size, and flags (e.g. compressed or not compressed) for a resource
63  * in the WIM file.  */
64 struct wim_reshdr_disk {
65         /* Size of the resource as it appears in the WIM file (possibly
66          * compressed).  */
67         u8 size_in_wim[7];
68
69         /* WIM_RESHDR_FLAG_* flags.  */
70         u8 flags;
71
72         /* Offset of the resource from the start of the WIM file.  */
73         le64 offset_in_wim;
74
75         /* Uncompressed size of the resource.  */
76         le64 uncompressed_size;
77 } _packed_attribute;
78
79 /* In-memory version of wim_reshdr_disk.  */
80 struct wim_reshdr {
81         u64 size_in_wim : 56;
82         u64 flags : 8;
83         u64 offset_in_wim;
84         u64 uncompressed_size;
85 };
86
87 /* Flags for the `flags' field of the struct resource_entry structure. */
88
89 /* I haven't seen this flag used in any of the WIMs I have examined.  I assume
90  * it means that there are no references to the stream, so the space is free.
91  * However, even after deleting files from a WIM mounted with `imagex.exe
92  * /mountrw', I could not see this flag being used.  Either way, wimlib doesn't
93  * actually use this flag for anything. */
94 #define WIM_RESHDR_FLAG_FREE            0x01
95
96 /* Indicates that the stream is a metadata resource for a WIM image.  This flag
97  * is also set in the resource entry for the lookup table in the WIM header.  */
98 #define WIM_RESHDR_FLAG_METADATA        0x02
99
100 /* Indicates that the stream is compressed (using the WIM's set compression
101  * type).  */
102 #define WIM_RESHDR_FLAG_COMPRESSED      0x04
103
104 /* I haven't seen this flag used in any of the WIMs I have examined.  Perhaps it
105  * means that a stream could possibly be split among multiple split WIM parts.
106  * However, `imagex.exe /split' does not seem to create any WIMs like this.
107  * Either way, wimlib doesn't actually use this flag for anything.  */
108 #define WIM_RESHDR_FLAG_SPANNED         0x08
109
110 /* TODO  */
111 #define WIM_RESHDR_FLAG_CONCAT          0x10
112
113 static inline void
114 copy_reshdr(struct wim_reshdr *dest, const struct wim_reshdr *src)
115 {
116         memcpy(dest, src, sizeof(struct wim_reshdr));
117 }
118
119 static inline void
120 zero_reshdr(struct wim_reshdr *reshdr)
121 {
122         memset(reshdr, 0, sizeof(struct wim_reshdr));
123 }
124
125
126 extern void
127 wim_res_hdr_to_spec(const struct wim_reshdr *reshdr, WIMStruct *wim,
128                     struct wim_resource_spec *rspec);
129
130 extern void
131 wim_res_spec_to_hdr(const struct wim_resource_spec *rspec,
132                     struct wim_reshdr *reshdr);
133
134 extern int
135 get_wim_reshdr(const struct wim_reshdr_disk *disk_reshdr,
136                struct wim_reshdr *reshdr);
137
138 void
139 put_wim_reshdr(const struct wim_reshdr *reshdr,
140                struct wim_reshdr_disk *disk_reshdr);
141
142 /* wimlib internal flags used when reading or writing resources.  */
143 #define WIMLIB_WRITE_RESOURCE_FLAG_RECOMPRESS           0x00000001
144 #define WIMLIB_WRITE_RESOURCE_FLAG_PIPABLE              0x00000002
145 #define WIMLIB_WRITE_RESOURCE_MASK                      0x0000ffff
146
147 #define WIMLIB_READ_RESOURCE_FLAG_RAW_FULL              0x80000000
148 #define WIMLIB_READ_RESOURCE_FLAG_RAW_CHUNKS            0x40000000
149 #define WIMLIB_READ_RESOURCE_FLAG_RAW           (WIMLIB_READ_RESOURCE_FLAG_RAW_FULL |  \
150                                                  WIMLIB_READ_RESOURCE_FLAG_RAW_CHUNKS)
151 #define WIMLIB_READ_RESOURCE_MASK                       0xffff0000
152
153
154 /* Functions to read streams  */
155
156 extern int
157 read_partial_wim_stream_into_buf(const struct wim_lookup_table_entry *lte,
158                                  size_t size, u64 offset, void *buf);
159
160 extern int
161 skip_wim_stream(struct wim_lookup_table_entry *lte);
162
163 extern int
164 read_full_stream_into_buf(const struct wim_lookup_table_entry *lte, void *buf);
165
166 extern int
167 read_full_stream_into_alloc_buf(const struct wim_lookup_table_entry *lte,
168                                 void **buf_ret);
169
170 extern int
171 wim_reshdr_to_data(const struct wim_reshdr *reshdr,
172                    WIMStruct *wim, void **buf_ret);
173
174 extern int
175 read_stream_prefix(const struct wim_lookup_table_entry *lte,
176                    u64 size, consume_data_callback_t cb,
177                    void *cb_ctx, int flags);
178
179 typedef int (*read_stream_list_begin_stream_t)(struct wim_lookup_table_entry *lte,
180                                                bool is_partial_res,
181                                                void *ctx);
182 typedef int (*read_stream_list_end_stream_t)(struct wim_lookup_table_entry *lte,
183                                              int status,
184                                              void *ctx);
185
186 /* Callbacks for read_stream_list().  */
187 struct read_stream_list_callbacks {
188
189         /* Called when a stream is about to be read.  */
190         read_stream_list_begin_stream_t begin_stream;
191
192         /* Called when a chunk of data has been read.  */
193         consume_data_callback_t consume_chunk;
194
195         /* Called when a stream has been fully read.  */
196         read_stream_list_end_stream_t end_stream;
197
198         /* Parameter passed to @begin_stream.  */
199         void *begin_stream_ctx;
200
201         /* Parameter passed to @consume_chunk.  */
202         void *consume_chunk_ctx;
203
204         /* Parameter passed to @end_stream.  */
205         void *end_stream_ctx;
206 };
207
208 extern int
209 read_stream_list(struct list_head *stream_list,
210                  size_t list_head_offset,
211                  u32 cb_chunk_size,
212                  const struct read_stream_list_callbacks *cbs);
213
214 /* Functions for stream extraction.  */
215
216 extern int
217 extract_stream(struct wim_lookup_table_entry *lte,
218                u64 size,
219                consume_data_callback_t extract_chunk,
220                void *extract_chunk_arg);
221
222 extern int
223 extract_stream_to_fd(struct wim_lookup_table_entry *lte,
224                      struct filedes *fd, u64 size);
225
226 extern int
227 extract_chunk_to_fd(const void *chunk, size_t size, void *_fd_p);
228
229 /* Miscellaneous stream functions.  */
230
231 extern int
232 sha1_stream(struct wim_lookup_table_entry *lte);
233
234 /* Functions to read/write metadata resources.  */
235
236 extern int
237 read_metadata_resource(WIMStruct *wim,
238                        struct wim_image_metadata *image_metadata);
239
240 extern int
241 write_metadata_resource(WIMStruct *wim, int image, int write_resource_flags);
242
243 /* Definitions specific to pipable WIM resources.  */
244
245 /* Arbitrary number to begin each stream in the pipable WIM, used for sanity
246  * checking.  */
247 #define PWM_STREAM_MAGIC 0x2b9b9ba2443db9d8ULL
248
249 /* Header that precedes each resource in a pipable WIM.  */
250 struct pwm_stream_hdr {
251         le64 magic;                     /* +0   */
252         le64 uncompressed_size;         /* +8   */
253         u8 hash[SHA1_HASH_SIZE];        /* +16  */
254         le32 flags;                     /* +36  */
255                                         /* +40  */
256 } _packed_attribute;
257
258 /* Extra flag for the @flags field in `struct pipable_wim_stream_hdr': Indicates
259  * that the SHA1 message digest of the stream has not been calculated.
260  * Currently only used for the XML data.  */
261 #define PWM_RESHDR_FLAG_UNHASHED         0x100
262
263 /* Header that precedes each chunk of a compressed resource in a pipable WIM.
264  */
265 struct pwm_chunk_hdr {
266         le32 compressed_size;
267 } _packed_attribute;
268
269
270 #endif /* _WIMLIB_RESOURCE_H */