]> wimlib.net Git - wimlib/blob - include/wimlib/resource.h
16e28dfcfaed616111392317ee654d5d48cb2ab2
[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
53 /* On-disk version of a WIM resource header.  */
54 struct wim_reshdr_disk {
55         /* Size of the resource as it appears in the WIM file (possibly
56          * compressed).  */
57         u8 size_in_wim[7];
58
59         /* Zero or more of the WIM_RESHDR_FLAG_* flags.  These indicate, for
60          * example, whether the resource is compressed or not.  */
61         u8 flags;
62
63         /* Offset of the resource from the start of the WIM file, in bytes.  */
64         le64 offset_in_wim;
65
66         /* Uncompressed size of the resource, in bytes.  */
67         le64 uncompressed_size;
68 } _packed_attribute;
69
70 /* In-memory version of a WIM resource header.  */
71 struct wim_reshdr {
72         u64 size_in_wim : 56;
73         u64 flags : 8;
74         u64 offset_in_wim;
75         u64 uncompressed_size;
76 };
77
78 /* Flags for the `flags' field of WIM resource headers.  */
79
80 /* Unknown meaning; may be intended to indicate spaces in the WIM that are free
81  * to overwrite.  Currently ignored by wimlib.  */
82 #define WIM_RESHDR_FLAG_FREE            0x01
83
84 /* The resource is a metadata resource for a WIM image, or is the lookup table
85  * or XML data for the WIM.  */
86 #define WIM_RESHDR_FLAG_METADATA        0x02
87
88 /* The resource is compressed using the WIM's default compression type and uses
89  * the regular chunk table format.  */
90 #define WIM_RESHDR_FLAG_COMPRESSED      0x04
91
92 /* Unknown meaning; may be intended to indicate a partial stream.  Currently
93  * ignored by wimlib.  */
94 #define WIM_RESHDR_FLAG_SPANNED         0x08
95
96 /* The resource is packed in a special format that may contain multiple
97  * underlying streams, or this resource entry represents a stream packed into
98  * one such resource.  When resources have this flag set, the WIM version number
99  * should be WIM_VERSION_PACKED_STREAMS.  */
100 #define WIM_RESHDR_FLAG_PACKED_STREAMS  0x10
101
102 /* Returns true if the specified WIM resource is compressed, using either the
103  * original chunk table layout or the alternate layout for resources that may
104  * contain multiple packed streams.  */
105 static inline bool
106 resource_is_compressed(const struct wim_resource_spec *rspec)
107 {
108         return (rspec->flags & (WIM_RESHDR_FLAG_COMPRESSED |
109                                 WIM_RESHDR_FLAG_PACKED_STREAMS));
110 }
111
112 static inline void
113 copy_reshdr(struct wim_reshdr *dest, const struct wim_reshdr *src)
114 {
115         memcpy(dest, src, sizeof(struct wim_reshdr));
116 }
117
118 static inline void
119 zero_reshdr(struct wim_reshdr *reshdr)
120 {
121         memset(reshdr, 0, sizeof(struct wim_reshdr));
122 }
123
124 extern void
125 wim_res_hdr_to_spec(const struct wim_reshdr *reshdr, WIMStruct *wim,
126                     struct wim_resource_spec *rspec);
127
128 extern void
129 wim_res_spec_to_hdr(const struct wim_resource_spec *rspec,
130                     struct wim_reshdr *reshdr);
131
132 extern int
133 get_wim_reshdr(const struct wim_reshdr_disk *disk_reshdr,
134                struct wim_reshdr *reshdr);
135
136 void
137 put_wim_reshdr(const struct wim_reshdr *reshdr,
138                struct wim_reshdr_disk *disk_reshdr);
139
140 /* wimlib internal flags used when reading or writing resources.  */
141 #define WIMLIB_WRITE_RESOURCE_FLAG_RECOMPRESS           0x00000001
142 #define WIMLIB_WRITE_RESOURCE_FLAG_PIPABLE              0x00000002
143 #define WIMLIB_WRITE_RESOURCE_MASK                      0x0000ffff
144
145 #define WIMLIB_READ_RESOURCE_FLAG_RAW_FULL              0x80000000
146 #define WIMLIB_READ_RESOURCE_FLAG_RAW_CHUNKS            0x40000000
147 #define WIMLIB_READ_RESOURCE_FLAG_RAW           (WIMLIB_READ_RESOURCE_FLAG_RAW_FULL |  \
148                                                  WIMLIB_READ_RESOURCE_FLAG_RAW_CHUNKS)
149 #define WIMLIB_READ_RESOURCE_MASK                       0xffff0000
150
151
152 /* Functions to read streams  */
153
154 extern int
155 read_partial_wim_stream_into_buf(const struct wim_lookup_table_entry *lte,
156                                  size_t size, u64 offset, void *buf);
157
158 extern int
159 read_full_stream_into_buf(const struct wim_lookup_table_entry *lte, void *buf);
160
161 extern int
162 read_full_stream_into_alloc_buf(const struct wim_lookup_table_entry *lte,
163                                 void **buf_ret);
164
165 extern int
166 wim_reshdr_to_data(const struct wim_reshdr *reshdr,
167                    WIMStruct *wim, void **buf_ret);
168
169 extern int
170 skip_wim_stream(struct wim_lookup_table_entry *lte);
171
172 extern int
173 read_stream_prefix(const struct wim_lookup_table_entry *lte,
174                    u64 size, consume_data_callback_t cb,
175                    void *cb_ctx, int flags);
176
177 typedef int (*read_stream_list_begin_stream_t)(struct wim_lookup_table_entry *lte,
178                                                bool is_partial_res,
179                                                void *ctx);
180 typedef int (*read_stream_list_end_stream_t)(struct wim_lookup_table_entry *lte,
181                                              int status,
182                                              void *ctx);
183
184 /* Callback functions and contexts for read_stream_list().  */
185 struct read_stream_list_callbacks {
186
187         /* Called when a stream is about to be read.  */
188         read_stream_list_begin_stream_t begin_stream;
189
190         /* Called when a chunk of data has been read.  */
191         consume_data_callback_t consume_chunk;
192
193         /* Called when a stream has been fully read.  */
194         read_stream_list_end_stream_t end_stream;
195
196         /* Parameter passed to @begin_stream.  */
197         void *begin_stream_ctx;
198
199         /* Parameter passed to @consume_chunk.  */
200         void *consume_chunk_ctx;
201
202         /* Parameter passed to @end_stream.  */
203         void *end_stream_ctx;
204 };
205
206 extern int
207 read_stream_list(struct list_head *stream_list,
208                  size_t list_head_offset,
209                  u32 cb_chunk_size,
210                  const struct read_stream_list_callbacks *cbs);
211
212 /* Functions to extract streams.  */
213
214 extern int
215 extract_stream(struct wim_lookup_table_entry *lte,
216                u64 size,
217                consume_data_callback_t extract_chunk,
218                void *extract_chunk_arg);
219
220 extern int
221 extract_stream_to_fd(struct wim_lookup_table_entry *lte,
222                      struct filedes *fd, u64 size);
223
224 extern int
225 extract_chunk_to_fd(const void *chunk, size_t size, void *_fd_p);
226
227 /* Miscellaneous stream functions.  */
228
229 extern int
230 sha1_stream(struct wim_lookup_table_entry *lte);
231
232 /* Functions to read/write metadata resources.  */
233
234 extern int
235 read_metadata_resource(WIMStruct *wim,
236                        struct wim_image_metadata *image_metadata);
237
238 extern int
239 write_metadata_resource(WIMStruct *wim, int image, int write_resource_flags);
240
241 /* Definitions specific to pipable WIM resources.  */
242
243 /* Arbitrary number to begin each stream in the pipable WIM, used for sanity
244  * checking.  */
245 #define PWM_STREAM_MAGIC 0x2b9b9ba2443db9d8ULL
246
247 /* Header that precedes each resource in a pipable WIM.  */
248 struct pwm_stream_hdr {
249         le64 magic;                     /* +0   */
250         le64 uncompressed_size;         /* +8   */
251         u8 hash[SHA1_HASH_SIZE];        /* +16  */
252         le32 flags;                     /* +36  */
253                                         /* +40  */
254 } _packed_attribute;
255
256 /* Extra flag for the @flags field in `struct pipable_wim_stream_hdr': Indicates
257  * that the SHA1 message digest of the stream has not been calculated.
258  * Currently only used for the XML data.  */
259 #define PWM_RESHDR_FLAG_UNHASHED         0x100
260
261 /* Header that precedes each chunk of a compressed resource in a pipable WIM.
262  */
263 struct pwm_chunk_hdr {
264         le32 compressed_size;
265 } _packed_attribute;
266
267 #endif /* _WIMLIB_RESOURCE_H */