u64 offset_in_wim;
/* The size of this resource in the WIM file. For compressed resources
- * this is the compressed size. */
+ * this is the compressed size, including overhead such as the chunk
+ * table. */
u64 size_in_wim;
/* The number of bytes of uncompressed data this resource decompresses
/* The list of streams this resource contains. */
struct list_head stream_list;
- /* Flags for this resource (WIM_RESHDR_FLAG_*) */
+ /* Flags for this resource (WIM_RESHDR_FLAG_*). */
u32 flags : 8;
- /* This flag will be set if the WIM is pipable. In such cases, the
- * resource will be in a slightly different format if it is compressed.
- * This is a wimlib extension. */
+ /* [wimlib extension] This flag will be set if the WIM is pipable. In
+ * such cases, the resource will be in a slightly different format if it
+ * is compressed. */
u32 is_pipable : 1;
+
+ /* Temporary flag. */
+ u32 raw_copy_ok : 1;
+
+ /* Compression type of this resource. */
+ u32 compression_type : 22;
+
+ /* Compression chunk size of this resource. Irrelevant if the resource
+ * is uncompressed. */
+ u32 chunk_size;
};
/* On-disk version of a WIM resource header. */
le64 uncompressed_size;
} _packed_attribute;
-/* In-memory version of a WIM resource header. */
+/* In-memory version of a WIM resource header (`struct wim_reshdr_disk'). */
struct wim_reshdr {
u64 size_in_wim : 56;
u64 flags : 8;
u64 uncompressed_size;
};
-/* Flags for the `flags' field of WIM resource headers. */
+/* Flags for the `flags' field of WIM resource headers (`struct wim_reshdr').
+ */
/* Unknown meaning; may be intended to indicate spaces in the WIM that are free
* to overwrite. Currently ignored by wimlib. */
* should be WIM_VERSION_PACKED_STREAMS. */
#define WIM_RESHDR_FLAG_PACKED_STREAMS 0x10
+/* Magic number in the 'uncompressed_size' field of the resource header that
+ * identifies the main entry for a pack. */
+#define WIM_PACK_MAGIC_NUMBER 0x100000000ULL
+
/* Returns true if the specified WIM resource is compressed, using either the
* original chunk table layout or the alternate layout for resources that may
* contain multiple packed streams. */
wim_res_spec_to_hdr(const struct wim_resource_spec *rspec,
struct wim_reshdr *reshdr);
-extern int
+extern void
get_wim_reshdr(const struct wim_reshdr_disk *disk_reshdr,
struct wim_reshdr *reshdr);
put_wim_reshdr(const struct wim_reshdr *reshdr,
struct wim_reshdr_disk *disk_reshdr);
-/* wimlib internal flags used when reading or writing resources. */
-#define WIMLIB_WRITE_RESOURCE_FLAG_RECOMPRESS 0x00000001
-#define WIMLIB_WRITE_RESOURCE_FLAG_PIPABLE 0x00000002
-#define WIMLIB_WRITE_RESOURCE_MASK 0x0000ffff
-
-#define WIMLIB_READ_RESOURCE_FLAG_RAW_FULL 0x80000000
-#define WIMLIB_READ_RESOURCE_FLAG_RAW_CHUNKS 0x40000000
-#define WIMLIB_READ_RESOURCE_FLAG_RAW (WIMLIB_READ_RESOURCE_FLAG_RAW_FULL | \
- WIMLIB_READ_RESOURCE_FLAG_RAW_CHUNKS)
-#define WIMLIB_READ_RESOURCE_MASK 0xffff0000
+/* Alternate chunk table format for resources with
+ * WIM_RESHDR_FLAG_PACKED_STREAMS set. */
+struct alt_chunk_table_header_disk {
+ /* Uncompressed size of the resource in bytes. */
+ le64 res_usize;
+
+ /* Number of bytes each compressed chunk decompresses into, except
+ * possibly the last which decompresses into the remainder. This
+ * overrides the chunk size specified by the WIM header. */
+ le32 chunk_size;
+
+ /* Compression format used for compressed chunks:
+ * 0 = None
+ * 1 = XPRESS
+ * 2 = LZX
+ * 3 = LZMS
+ *
+ * This overrides the compression type specified by the WIM header. */
+ le32 compression_format;
+
+ /* This header is directly followed by a table of compressed sizes of
+ * the chunks (4 bytes per entry). */
+} _packed_attribute;
+static inline unsigned int
+get_chunk_entry_size(u64 res_size, bool is_alt)
+{
+ if (res_size <= UINT32_MAX || is_alt)
+ return 4;
+ else
+ return 8;
+}
/* Functions to read streams */
WIMStruct *wim, void **buf_ret);
extern int
-skip_wim_stream(struct wim_lookup_table_entry *lte);
+wim_reshdr_to_hash(const struct wim_reshdr *reshdr, WIMStruct *wim,
+ u8 hash[SHA1_HASH_SIZE]);
extern int
-read_stream_prefix(const struct wim_lookup_table_entry *lte,
- u64 size, consume_data_callback_t cb,
- void *cb_ctx, int flags);
+skip_wim_stream(struct wim_lookup_table_entry *lte);
+/*
+ * Type of callback function for beginning to read a stream.
+ *
+ * @lte:
+ * Stream that is about to be read.
+ *
+ * @ctx:
+ * User-provided context.
+ *
+ * Must return 0 on success, a positive error code on failure, or the special
+ * value BEGIN_STREAM_STATUS_SKIP_STREAM to indicate that the stream should not
+ * be read, and read_stream_list() should continue on to the next stream
+ * (without calling @consume_chunk or @end_stream).
+ */
typedef int (*read_stream_list_begin_stream_t)(struct wim_lookup_table_entry *lte,
- bool is_partial_res,
void *ctx);
+
+#define BEGIN_STREAM_STATUS_SKIP_STREAM -1
+
+/*
+ * Type of callback function for finishing reading a stream.
+ *
+ * @lte:
+ * Stream that has been fully read, or stream that started being read but
+ * could not be fully read due to a read error.
+ *
+ * @status:
+ * 0 if reading the stream was successful; otherwise a nonzero error code
+ * that specifies the return status.
+ *
+ * @ctx:
+ * User-provided context.
+ */
typedef int (*read_stream_list_end_stream_t)(struct wim_lookup_table_entry *lte,
int status,
void *ctx);
+
/* Callback functions and contexts for read_stream_list(). */
struct read_stream_list_callbacks {
/* Called when a chunk of data has been read. */
consume_data_callback_t consume_chunk;
- /* Called when a stream has been fully read. */
+ /* Called when a stream has been fully read. A successful call to
+ * @begin_stream will always be matched by a call to @end_stream. */
read_stream_list_end_stream_t end_stream;
/* Parameter passed to @begin_stream. */
void *end_stream_ctx;
};
+/* Flags for read_stream_list() */
+#define VERIFY_STREAM_HASHES 0x1
+#define COMPUTE_MISSING_STREAM_HASHES 0x2
+#define STREAM_LIST_ALREADY_SORTED 0x4
+
extern int
read_stream_list(struct list_head *stream_list,
size_t list_head_offset,
- u32 cb_chunk_size,
- const struct read_stream_list_callbacks *cbs);
+ const struct read_stream_list_callbacks *cbs,
+ int flags);
/* Functions to extract streams. */
extract_stream_to_fd(struct wim_lookup_table_entry *lte,
struct filedes *fd, u64 size);
+extern int
+extract_full_stream_to_fd(struct wim_lookup_table_entry *lte,
+ struct filedes *fd);
+
extern int
extract_chunk_to_fd(const void *chunk, size_t size, void *_fd_p);