Variable chunk size support (currently XPRESS only)
[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/sha1.h"
9
10 struct wim_lookup_table_entry;
11 struct wim_image_metadata;
12
13 /* Description of the location, size, and compression status of a WIM resource
14  * (stream).  This is the in-memory version of `struct resource_entry_disk'.  */
15 struct resource_entry {
16         /* Size, in bytes, of the resource as it appears in the WIM file.  If
17          * the resource is uncompressed, this will be the same as
18          * @original_size.  If the resource is compressed, this will be the
19          * compressed size of the resource, including all compressed chunks as
20          * well as the chunk table.
21          *
22          * Note: if the WIM is "pipable", this value does not include the stream
23          * header.  */
24         u64 size  : 56;
25
26         /* Bitwise OR of one or more of the WIM_RESHDR_FLAG_* flags.  */
27         u64 flags : 8;
28
29         /* Offset, in bytes, of the resource from the start of the WIM file.  */
30         u64 offset;
31
32         /* Uncompressed size, in bytes, of the resource (stream).  */
33         u64 original_size;
34 };
35
36 /* On-disk version of `struct resource_entry'.  See `struct resource_entry' for
37  * description of fields.  */
38 struct resource_entry_disk {
39         u8 size[7];
40         u8 flags;
41         le64 offset;
42         le64 original_size;
43 } _packed_attribute;
44
45 /* Flags for the `flags' field of the struct resource_entry structure. */
46
47 /* I haven't seen this flag used in any of the WIMs I have examined.  I assume
48  * it means that there are no references to the stream, so the space is free.
49  * However, even after deleting files from a WIM mounted with `imagex.exe
50  * /mountrw', I could not see this flag being used.  Either way, wimlib doesn't
51  * actually use this flag for anything. */
52 #define WIM_RESHDR_FLAG_FREE            0x01
53
54 /* Indicates that the stream is a metadata resource for a WIM image.  This flag
55  * is also set in the resource entry for the lookup table in the WIM header.  */
56 #define WIM_RESHDR_FLAG_METADATA        0x02
57
58 /* Indicates that the stream is compressed (using the WIM's set compression
59  * type).  */
60 #define WIM_RESHDR_FLAG_COMPRESSED      0x04
61
62 /* I haven't seen this flag used in any of the WIMs I have examined.  Perhaps it
63  * means that a stream could possibly be split among multiple split WIM parts.
64  * However, `imagex.exe /split' does not seem to create any WIMs like this.
65  * Either way, wimlib doesn't actually use this flag for anything.  */
66 #define WIM_RESHDR_FLAG_SPANNED         0x08
67
68 /* Functions that operate directly on `struct resource_entry's.  */
69
70 static inline int
71 resource_is_compressed(const struct resource_entry *entry)
72 {
73         return (entry->flags & WIM_RESHDR_FLAG_COMPRESSED);
74 }
75
76 static inline void copy_resource_entry(struct resource_entry *dst,
77                                        const struct resource_entry *src)
78 {
79         memcpy(dst, src, sizeof(struct resource_entry));
80 }
81
82 static inline void zero_resource_entry(struct resource_entry *entry)
83 {
84         memset(entry, 0, sizeof(struct resource_entry));
85 }
86
87 extern void
88 get_resource_entry(const struct resource_entry_disk *disk_entry,
89                    struct resource_entry *entry);
90
91 extern void
92 put_resource_entry(const struct resource_entry *entry,
93                    struct resource_entry_disk *disk_entry);
94
95 /* wimlib internal flags used when reading or writing resources.  */
96 #define WIMLIB_WRITE_RESOURCE_FLAG_RECOMPRESS           0x00000001
97 #define WIMLIB_WRITE_RESOURCE_FLAG_PIPABLE              0x00000002
98 #define WIMLIB_WRITE_RESOURCE_MASK                      0x0000ffff
99
100 #define WIMLIB_READ_RESOURCE_FLAG_RAW_FULL              0x80000000
101 #define WIMLIB_READ_RESOURCE_FLAG_RAW_CHUNKS            0x40000000
102 #define WIMLIB_READ_RESOURCE_FLAG_SEEK_ONLY             0x20000000
103 #define WIMLIB_READ_RESOURCE_FLAG_RAW           (WIMLIB_READ_RESOURCE_FLAG_RAW_FULL |  \
104                                                  WIMLIB_READ_RESOURCE_FLAG_RAW_CHUNKS)
105 #define WIMLIB_READ_RESOURCE_MASK                       0xffff0000
106
107
108 /* Functions to read a resource.  */
109
110 extern int
111 read_partial_wim_resource(const struct wim_lookup_table_entry *lte,
112                           u64 size, consume_data_callback_t cb,
113                           u32 in_chunk_size, void *ctx_or_buf,
114                           int flags, u64 offset);
115
116 extern int
117 read_partial_wim_resource_into_buf(const struct wim_lookup_table_entry *lte,
118                                    size_t size, u64 offset, void *buf);
119 extern int
120 read_full_resource_into_buf(const struct wim_lookup_table_entry *lte, void *buf);
121
122 extern int
123 read_full_resource_into_alloc_buf(const struct wim_lookup_table_entry *lte,
124                                   void **buf_ret);
125
126 extern int
127 res_entry_to_data(const struct resource_entry *res_entry,
128                   WIMStruct *wim, void **buf_ret);
129
130 extern int
131 read_resource_prefix(const struct wim_lookup_table_entry *lte,
132                      u64 size, consume_data_callback_t cb,
133                      u32 in_chunk_size, void *ctx_or_buf, int flags);
134
135 /* Functions to write a resource.  */
136
137 extern int
138 write_wim_resource(struct wim_lookup_table_entry *lte, struct filedes *out_fd,
139                    int out_ctype,
140                    u32 out_chunk_size,
141                    struct resource_entry *out_res_entry,
142                    int write_resource_flags,
143                    struct wimlib_lzx_context **comp_ctx);
144
145 extern int
146 write_wim_resource_from_buffer(const void *buf, size_t buf_size,
147                                int reshdr_flags, struct filedes *out_fd,
148                                int out_ctype,
149                                u32 out_chunk_size,
150                                struct resource_entry *out_res_entry,
151                                u8 *hash_ret, int write_resource_flags,
152                                struct wimlib_lzx_context **comp_ctx);
153
154 /* Functions to extract a resource.  */
155
156 extern int
157 extract_wim_resource(const struct wim_lookup_table_entry *lte,
158                      u64 size,
159                      consume_data_callback_t extract_chunk,
160                      void *extract_chunk_arg);
161
162 extern int
163 extract_wim_resource_to_fd(const struct wim_lookup_table_entry *lte,
164                            struct filedes *fd, u64 size);
165
166 /* Miscellaneous resource functions.  */
167
168 extern int
169 sha1_resource(struct wim_lookup_table_entry *lte);
170
171 /* Functions to read/write metadata resources.  */
172
173 extern int
174 read_metadata_resource(WIMStruct *wim,
175                        struct wim_image_metadata *image_metadata);
176
177 extern int
178 write_metadata_resource(WIMStruct *wim, int image, int write_resource_flags);
179
180 /* Definitions specific to pipable WIM resources.  */
181
182 /* Arbitrary number to begin each stream in the pipable WIM, used for sanity
183  * checking.  */
184 #define PWM_STREAM_MAGIC 0x2b9b9ba2443db9d8ULL
185
186 /* Header that precedes each resource in a pipable WIM.  */
187 struct pwm_stream_hdr {
188         le64 magic;                     /* +0   */
189         le64 uncompressed_size;         /* +8   */
190         u8 hash[SHA1_HASH_SIZE];        /* +16  */
191         le32 flags;                     /* +36  */
192                                         /* +40  */
193 } _packed_attribute;
194
195 /* Extra flag for the @flags field in `struct pipable_wim_stream_hdr': Indicates
196  * that the SHA1 message digest of the stream has not been calculated.
197  * Currently only used for the XML data.  */
198 #define PWM_RESHDR_FLAG_UNHASHED         0x100
199
200 /* Header that precedes each chunk of a compressed resource in a pipable WIM.
201  */
202 struct pwm_chunk_hdr {
203         le32 compressed_size;
204 } _packed_attribute;
205
206
207 #endif /* _WIMLIB_RESOURCE_H */