Most "blob" flags were actually only meaningful for WIM resources.
Resource flags are actually saved in the 'flags' member of 'struct
wim_resource_descriptor', and we don't need to duplicate them in 'struct
blob_descriptor'.
/* One of the `enum blob_location' values documented above. */
u32 blob_location : 4;
- /* Blob flags (WIM_RESHDR_FLAG_*) */
- u32 flags : 8;
+ /* 1 iff this blob contains "metadata" as opposed to data. */
+ u32 is_metadata : 1;
/* 1 iff the SHA-1 message digest of this blob is unknown. */
u32 unhashed : 1;
extern int
cmp_blobs_by_sequential_order(const void *p1, const void *p2);
-static inline bool
-blob_is_in_solid_wim_resource(const struct blob_descriptor *blob)
-{
- return blob->blob_location == BLOB_IN_WIM &&
- blob->size != blob->rdesc->uncompressed_size;
-}
-
-static inline bool
-blob_is_in_file(const struct blob_descriptor *blob)
-{
- return blob->blob_location == BLOB_IN_FILE_ON_DISK
-#ifdef __WIN32__
- || blob->blob_location == BLOB_IN_WINNT_FILE_ON_DISK
- || blob->blob_location == BLOB_WIN32_ENCRYPTED
-#endif
- ;
-}
-
static inline const struct blob_extraction_target *
blob_extraction_targets(struct blob_descriptor *blob)
{
/* +40 */
} _packed_attribute;
-/* Extra flag for the @flags field in `struct pwm_blob_hdr': Indicates that the
- * SHA-1 message digest of the stream has not been calculated. Currently only
- * used for the XML data. */
-#define PWM_RESHDR_FLAG_UNHASHED 0x100
-
/* Header that precedes each chunk of a compressed resource in a pipable WIM.
*/
struct pwm_chunk_hdr {
return (wim->hdr.magic == PWM_MAGIC);
}
+extern bool
+wim_has_solid_resources(const WIMStruct *wim);
+
extern int
set_wim_hdr_cflags(int ctype, struct wim_header *hdr);
const u8 *guid);
int
-write_wim_resource_from_buffer(const void *buf, size_t buf_size,
- int reshdr_flags, struct filedes *out_fd,
+write_wim_resource_from_buffer(const void *buf,
+ size_t buf_size,
+ bool is_metadata,
+ struct filedes *out_fd,
int out_ctype,
u32 out_chunk_size,
struct wim_reshdr *out_reshdr,
- u8 *hash,
+ u8 *hash_ret,
int write_resource_flags);
#endif /* _WIMLIB_WRITE_H */
goto out;
metadata_blob->refcnt = 1;
- metadata_blob->flags = WIM_RESHDR_FLAG_METADATA;
metadata_blob->unhashed = 1;
+ metadata_blob->is_metadata = 1;
/* Create empty security data (no security descriptors). */
sd = new_wim_security_data();
/* XXX: This linear search will be slow in the degenerate case where the
* number of solid resources in the run is huge. */
blob->size = reshdr->size_in_wim;
- blob->flags = reshdr->flags;
for (size_t i = 0; i < num_rdescs; i++) {
if (offset + blob->size <= rdescs[i]->uncompressed_size) {
blob->offset_in_res = offset;
cur_blob->offset_in_res = 0;
cur_blob->size = reshdr.uncompressed_size;
- cur_blob->flags = reshdr.flags;
blob_set_is_located_in_wim_resource(cur_blob, rdesc);
}
if (reshdr.flags & WIM_RESHDR_FLAG_METADATA) {
+ cur_blob->is_metadata = 1;
+
/* Blob table entry for a metadata resource. */
/* Metadata entries with no references must be ignored.
}
/* Note: the list of blob descriptors must be sorted so that all entries for the
- * same solid resource are consecutive. In addition, blob descriptors with
- * WIM_RESHDR_FLAG_METADATA set must be in the same order as the indices of the
- * underlying images. */
+ * same solid resource are consecutive. In addition, blob descriptors for
+ * metadata resources must be in the same order as the indices of the underlying
+ * images. */
int
write_blob_table_from_blob_list(struct list_head *blob_list,
struct filedes *out_fd,
* compressed blob table, MS software cannot. */
ret = write_wim_resource_from_buffer(table_buf,
table_size,
- WIM_RESHDR_FLAG_METADATA,
+ true,
out_fd,
WIMLIB_COMPRESSION_TYPE_NONE,
0,
wentry->uncompressed_size = blob->size;
if (blob->blob_location == BLOB_IN_WIM) {
+ unsigned res_flags = blob->rdesc->flags;
+
wentry->part_number = blob->rdesc->wim->hdr.part_number;
- if (blob->flags & WIM_RESHDR_FLAG_SOLID) {
+ if (res_flags & WIM_RESHDR_FLAG_SOLID) {
wentry->offset = blob->offset_in_res;
} else {
wentry->compressed_size = blob->rdesc->size_in_wim;
wentry->raw_resource_offset_in_wim = blob->rdesc->offset_in_wim;
wentry->raw_resource_compressed_size = blob->rdesc->size_in_wim;
wentry->raw_resource_uncompressed_size = blob->rdesc->uncompressed_size;
+
+ wentry->is_compressed = (res_flags & WIM_RESHDR_FLAG_COMPRESSED) != 0;
+ wentry->is_free = (res_flags & WIM_RESHDR_FLAG_FREE) != 0;
+ wentry->is_spanned = (res_flags & WIM_RESHDR_FLAG_SPANNED) != 0;
+ wentry->packed = (res_flags & WIM_RESHDR_FLAG_SOLID) != 0;
}
copy_hash(wentry->sha1_hash, blob->hash);
wentry->reference_count = blob->refcnt;
- wentry->is_compressed = (blob->flags & WIM_RESHDR_FLAG_COMPRESSED) != 0;
- wentry->is_metadata = (blob->flags & WIM_RESHDR_FLAG_METADATA) != 0;
- wentry->is_free = (blob->flags & WIM_RESHDR_FLAG_FREE) != 0;
- wentry->is_spanned = (blob->flags & WIM_RESHDR_FLAG_SPANNED) != 0;
- wentry->packed = (blob->flags & WIM_RESHDR_FLAG_SOLID) != 0;
+ wentry->is_metadata = blob->is_metadata;
}
struct iterate_blob_context {
reshdr.uncompressed_size = le64_to_cpu(buf.blob_hdr.uncompressed_size);
wim_res_hdr_to_desc(&reshdr, pwm, rdesc);
blob_set_is_located_in_wim_resource(blob, rdesc);
- blob->flags = rdesc->flags;
blob->size = rdesc->uncompressed_size;
blob->offset_in_res = 0;
+ blob->is_metadata = (rdesc->flags & WIM_RESHDR_FLAG_METADATA) != 0;
return 0;
read_error:
goto out;
if ((found_blob->blob_location != BLOB_NONEXISTENT)
- && !(found_blob->flags & WIM_RESHDR_FLAG_METADATA)
+ && !found_blob->is_metadata
&& (needed_blob = lookup_blob(blob_table, found_blob->hash))
&& (needed_blob->out_refcnt))
{
needed_blob->offset_in_res = found_blob->offset_in_res;
- needed_blob->flags = found_blob->flags;
needed_blob->size = found_blob->size;
blob_unset_is_located_in_wim_resource(found_blob);
if (ret)
goto out_wimlib_free;
- if (!(xml_blob.flags & WIM_RESHDR_FLAG_METADATA))
- {
+ if (!xml_blob.is_metadata) {
ERROR("Expected XML data, but found non-metadata resource.");
ret = WIMLIB_ERR_INVALID_PIPABLE_WIM;
goto out_wimlib_free;
goto out_wimlib_free;
}
- if (!(metadata_blob->flags & WIM_RESHDR_FLAG_METADATA)) {
+ if (!metadata_blob->is_metadata) {
ERROR("Expected metadata resource, but found "
"non-metadata resource.");
ret = WIMLIB_ERR_INVALID_PIPABLE_WIM;
ret = write_wim_resource_from_buffer(new_table,
new_table_size,
- 0,
+ false,
&wim->out_fd,
WIMLIB_COMPRESSION_TYPE_NONE,
0,
/* Write the metadata resource to the output WIM using the proper
* compression type, in the process updating the blob descriptor for the
* metadata resource. */
- ret = write_wim_resource_from_buffer(buf, len, WIM_RESHDR_FLAG_METADATA,
+ ret = write_wim_resource_from_buffer(buf,
+ len,
+ true,
&wim->out_fd,
wim->out_compression_type,
wim->out_chunk_size,
new_blob = new_blob_descriptor();
if (!new_blob)
goto err_put_replace_imd;
+
new_blob->refcnt = 1;
- new_blob->flags = WIM_RESHDR_FLAG_METADATA;
new_blob->unhashed = 1;
+ new_blob->is_metadata = 1;
/* Make the image being moved available at a new index. Increments the
* WIM's image count, but does not increment the reference count of the
wim_reshdr_to_data(const struct wim_reshdr *reshdr, WIMStruct *wim, void **buf_ret)
{
struct wim_resource_descriptor rdesc;
- struct blob_descriptor *blob;
- int ret;
+ struct blob_descriptor blob;
wim_res_hdr_to_desc(reshdr, wim, &rdesc);
+ blob_set_is_located_in_wim_resource(&blob, &rdesc);
- blob = new_blob_descriptor();
- if (!blob)
- return WIMLIB_ERR_NOMEM;
-
- blob_set_is_located_in_wim_resource(blob, &rdesc);
- blob->flags = rdesc.flags;
- blob->size = rdesc.uncompressed_size;
- blob->offset_in_res = 0;
+ blob.size = rdesc.uncompressed_size;
+ blob.offset_in_res = 0;
- ret = read_full_blob_into_alloc_buf(blob, buf_ret);
-
- blob_unset_is_located_in_wim_resource(blob);
- free_blob_descriptor(blob);
- return ret;
+ return read_full_blob_into_alloc_buf(&blob, buf_ret);
}
int
u8 hash[SHA1_HASH_SIZE])
{
struct wim_resource_descriptor rdesc;
+ struct blob_descriptor blob;
int ret;
- struct blob_descriptor *blob;
wim_res_hdr_to_desc(reshdr, wim, &rdesc);
+ blob_set_is_located_in_wim_resource(&blob, &rdesc);
- blob = new_blob_descriptor();
- if (blob == NULL)
- return WIMLIB_ERR_NOMEM;
+ blob.size = rdesc.uncompressed_size;
+ blob.offset_in_res = 0;
+ blob.unhashed = 1;
- blob_set_is_located_in_wim_resource(blob, &rdesc);
- blob->flags = rdesc.flags;
- blob->size = rdesc.uncompressed_size;
- blob->offset_in_res = 0;
- blob->unhashed = 1;
-
- ret = sha1_blob(blob);
-
- blob_unset_is_located_in_wim_resource(blob);
- copy_hash(hash, blob->hash);
- free_blob_descriptor(blob);
- return ret;
+ ret = sha1_blob(&blob);
+ if (ret)
+ return ret;
+ copy_hash(hash, blob.hash);
+ return 0;
}
struct blobifier_context {
*/
int
read_blob_list(struct list_head *blob_list,
- size_t list_head_offset,
- const struct read_blob_list_callbacks *cbs,
- int flags)
+ size_t list_head_offset,
+ const struct read_blob_list_callbacks *cbs,
+ int flags)
{
int ret;
struct list_head *cur, *next;
{
blob = (struct blob_descriptor*)((u8*)cur - list_head_offset);
- if (blob->flags & WIM_RESHDR_FLAG_SOLID &&
+ if (blob->blob_location == BLOB_IN_WIM &&
blob->size != blob->rdesc->uncompressed_size)
{
-
struct blob_descriptor *blob_next, *blob_last;
struct list_head *next2;
u64 blob_count;
struct swm_info *swm_info = _swm_info;
u64 blob_stored_size;
- if (blob_is_in_solid_wim_resource(blob)) {
- ERROR("Splitting of WIM containing solid resources is not supported.\n"
- " Export it in non-solid format first.");
- return WIMLIB_ERR_UNSUPPORTED;
- }
if (blob->blob_location == BLOB_IN_WIM)
blob_stored_size = blob->rdesc->size_in_wim;
else
if (swm_info->num_parts == 0 ||
((swm_info->parts[swm_info->num_parts - 1].size +
blob_stored_size >= swm_info->max_part_size)
- && !((blob->flags & WIM_RESHDR_FLAG_METADATA) ||
- swm_info->parts[swm_info->num_parts - 1].size == 0)))
+ && !(blob->is_metadata ||
+ swm_info->parts[swm_info->num_parts - 1].size == 0)))
{
if (swm_info->num_parts == swm_info->num_alloc_parts) {
struct swm_part_info *parts;
swm_info->parts[swm_info->num_parts - 1].size = 0;
}
swm_info->parts[swm_info->num_parts - 1].size += blob_stored_size;
- if (!(blob->flags & WIM_RESHDR_FLAG_METADATA)) {
+ if (!blob->is_metadata) {
list_add_tail(&blob->write_blobs_list,
&swm_info->parts[swm_info->num_parts - 1].blob_list);
}
if (!wim_has_metadata(wim))
return WIMLIB_ERR_METADATA_NOT_FOUND;
+ if (wim_has_solid_resources(wim)) {
+ ERROR("Splitting of WIM containing solid resources is not supported.\n"
+ " Export it in non-solid format first.");
+ return WIMLIB_ERR_UNSUPPORTED;
+ }
+
memset(&swm_info, 0, sizeof(swm_info));
swm_info.max_part_size = part_size;
}
}
+static int
+is_blob_in_solid_resource(struct blob_descriptor *blob, void *_ignore)
+{
+ return blob->blob_location == BLOB_IN_WIM &&
+ (blob->rdesc->flags & WIM_RESHDR_FLAG_SOLID);
+}
+
+bool
+wim_has_solid_resources(const WIMStruct *wim)
+{
+ return for_blob_in_table(wim->blob_table, is_blob_in_solid_resource, NULL);
+}
+
/*
* Calls a function on images in the WIM. If @image is WIMLIB_ALL_IMAGES,
* @visitor is called on the WIM once for each image, with each image selected
return false;
}
-static u8
-filter_resource_flags(u8 flags)
+static u32
+reshdr_flags_for_blob(const struct blob_descriptor *blob)
{
- return (flags & ~(WIM_RESHDR_FLAG_SOLID |
- WIM_RESHDR_FLAG_COMPRESSED |
- WIM_RESHDR_FLAG_SPANNED |
- WIM_RESHDR_FLAG_FREE));
+ u32 reshdr_flags = 0;
+ if (blob->is_metadata)
+ reshdr_flags |= WIM_RESHDR_FLAG_METADATA;
+ return reshdr_flags;
}
static void
rdesc = blob->rdesc;
if (rdesc->flags & WIM_RESHDR_FLAG_SOLID) {
-
- wimlib_assert(blob->flags & WIM_RESHDR_FLAG_SOLID);
-
blob->out_reshdr.offset_in_wim = blob->offset_in_res;
blob->out_reshdr.uncompressed_size = 0;
blob->out_reshdr.size_in_wim = blob->size;
blob->out_res_size_in_wim = rdesc->size_in_wim;
blob->out_res_uncompressed_size = rdesc->uncompressed_size;
} else {
- wimlib_assert(!(blob->flags & WIM_RESHDR_FLAG_SOLID));
-
blob->out_reshdr.offset_in_wim = rdesc->offset_in_wim;
blob->out_reshdr.uncompressed_size = rdesc->uncompressed_size;
blob->out_reshdr.size_in_wim = rdesc->size_in_wim;
}
- blob->out_reshdr.flags = blob->flags;
+ blob->out_reshdr.flags = rdesc->flags;
}
/* Write the header for a blob in a pipable WIM. */
static int
write_pwm_blob_header(const struct blob_descriptor *blob,
- struct filedes *out_fd, int additional_reshdr_flags)
+ struct filedes *out_fd, bool compressed)
{
struct pwm_blob_hdr blob_hdr;
u32 reshdr_flags;
int ret;
+ wimlib_assert(!blob->unhashed);
+
blob_hdr.magic = cpu_to_le64(PWM_BLOB_MAGIC);
blob_hdr.uncompressed_size = cpu_to_le64(blob->size);
- if (additional_reshdr_flags & PWM_RESHDR_FLAG_UNHASHED) {
- zero_out_hash(blob_hdr.hash);
- } else {
- wimlib_assert(!blob->unhashed);
- copy_hash(blob_hdr.hash, blob->hash);
- }
-
- reshdr_flags = filter_resource_flags(blob->flags);
- reshdr_flags |= additional_reshdr_flags;
+ copy_hash(blob_hdr.hash, blob->hash);
+ reshdr_flags = reshdr_flags_for_blob(blob);
+ if (compressed)
+ reshdr_flags |= WIM_RESHDR_FLAG_COMPRESSED;
blob_hdr.flags = cpu_to_le32(reshdr_flags);
ret = full_write(out_fd, &blob_hdr, sizeof(blob_hdr));
if (ret)
* uncompressed data by decompressing the compressed data we wrote to
* the output file.
*/
- if ((blob->flags & WIM_RESHDR_FLAG_SOLID) &&
- (blob->out_reshdr.size_in_wim != blob->out_reshdr.uncompressed_size))
+ if (blob->blob_location == BLOB_IN_WIM &&
+ blob->size != blob->rdesc->uncompressed_size &&
+ blob->size != blob->out_reshdr.size_in_wim)
return false;
return true;
/* Starting to write a new blob in non-solid mode. */
if (ctx->write_resource_flags & WRITE_RESOURCE_FLAG_PIPABLE) {
- int additional_reshdr_flags = 0;
- if (ctx->compressor != NULL)
- additional_reshdr_flags |= WIM_RESHDR_FLAG_COMPRESSED;
-
DEBUG("Writing pipable WIM blob header "
"(offset=%"PRIu64")", ctx->out_fd->offset);
-
ret = write_pwm_blob_header(blob, ctx->out_fd,
- additional_reshdr_flags);
+ ctx->compressor != NULL);
if (ret)
return ret;
}
if (ret)
return ret;
- blob->out_reshdr.flags = filter_resource_flags(blob->flags);
+ blob->out_reshdr.flags = reshdr_flags_for_blob(blob);
if (ctx->compressor != NULL)
blob->out_reshdr.flags |= WIM_RESHDR_FLAG_COMPRESSED;
blob->out_reshdr.offset_in_wim = 0;
blob->out_reshdr.size_in_wim = 0;
blob->out_reshdr.uncompressed_size = 0;
- blob->out_reshdr.flags = filter_resource_flags(blob->flags);
+ blob->out_reshdr.flags = reshdr_flags_for_blob(blob);
}
}
}
+static inline bool
+blob_is_in_file(const struct blob_descriptor *blob)
+{
+ return blob->blob_location == BLOB_IN_FILE_ON_DISK
+#ifdef __WIN32__
+ || blob->blob_location == BLOB_IN_WINNT_FILE_ON_DISK
+ || blob->blob_location == BLOB_WIN32_ENCRYPTED
+#endif
+ ;
+}
+
static void
init_done_with_file_info(struct list_head *blob_list)
{
offset_in_res = 0;
list_for_each_entry(blob, &ctx.blobs_in_solid_resource, write_blobs_list) {
blob->out_reshdr.size_in_wim = blob->size;
- blob->out_reshdr.flags = filter_resource_flags(blob->flags);
- blob->out_reshdr.flags |= WIM_RESHDR_FLAG_SOLID;
+ blob->out_reshdr.flags = reshdr_flags_for_blob(blob) |
+ WIM_RESHDR_FLAG_SOLID;
blob->out_reshdr.uncompressed_size = 0;
blob->out_reshdr.offset_in_wim = offset_in_res;
blob->out_res_offset_in_wim = reshdr.offset_in_wim;
return ret;
}
-static int
-is_blob_in_solid_resource(struct blob_descriptor *blob, void *_ignore)
-{
- return blob_is_in_solid_wim_resource(blob);
-}
-
-static bool
-wim_has_solid_resources(WIMStruct *wim)
-{
- return for_blob_in_table(wim->blob_table, is_blob_in_solid_resource, NULL);
-}
static int
wim_write_blob_list(WIMStruct *wim,
wim->progctx);
}
+/* Write the contents of the specified blob as a WIM resource. */
static int
write_wim_resource(struct blob_descriptor *blob,
struct filedes *out_fd,
NULL);
}
+/* Write the contents of the specified buffer as a WIM resource. */
int
-write_wim_resource_from_buffer(const void *buf, size_t buf_size,
- int reshdr_flags, struct filedes *out_fd,
+write_wim_resource_from_buffer(const void *buf,
+ size_t buf_size,
+ bool is_metadata,
+ struct filedes *out_fd,
int out_ctype,
u32 out_chunk_size,
struct wim_reshdr *out_reshdr,
- u8 *hash,
+ u8 *hash_ret,
int write_resource_flags)
{
int ret;
- struct blob_descriptor *blob;
+ struct blob_descriptor blob;
- /* Set up a temporary blob descriptor to provide to
- * write_wim_resource(). */
-
- blob = new_blob_descriptor();
- if (blob == NULL)
- return WIMLIB_ERR_NOMEM;
+ blob.blob_location = BLOB_IN_ATTACHED_BUFFER;
+ blob.attached_buffer = (void*)buf;
+ blob.size = buf_size;
+ sha1_buffer(buf, buf_size, blob.hash);
+ blob.unhashed = 0;
+ blob.is_metadata = is_metadata;
- blob->blob_location = BLOB_IN_ATTACHED_BUFFER;
- blob->attached_buffer = (void*)buf;
- blob->size = buf_size;
- blob->flags = reshdr_flags;
-
- if (write_resource_flags & WRITE_RESOURCE_FLAG_PIPABLE) {
- sha1_buffer(buf, buf_size, blob->hash);
- blob->unhashed = 0;
- } else {
- blob->unhashed = 1;
- }
-
- ret = write_wim_resource(blob, out_fd, out_ctype, out_chunk_size,
+ ret = write_wim_resource(&blob, out_fd, out_ctype, out_chunk_size,
write_resource_flags);
if (ret)
- goto out_free_blob;
+ return ret;
- copy_reshdr(out_reshdr, &blob->out_reshdr);
+ copy_reshdr(out_reshdr, &blob.out_reshdr);
- if (hash)
- copy_hash(hash, blob->hash);
- ret = 0;
-out_free_blob:
- blob->blob_location = BLOB_NONEXISTENT;
- free_blob_descriptor(blob);
- return ret;
+ if (hash_ret)
+ copy_hash(hash_ret, blob.hash);
+ return 0;
}
struct blob_size_table {
}
static int
-write_metadata_blobs(WIMStruct *wim, int image, int write_flags)
+write_metadata_resources(WIMStruct *wim, int image, int write_flags)
{
int ret;
int start_image;
/* Write metadata resources for the image(s) being included in the
* output WIM. */
- ret = write_metadata_blobs(wim, image, write_flags);
+ ret = write_metadata_resources(wim, image, write_flags);
if (ret)
return ret;
if (ret)
goto out_restore_hdr;
- /* Write metadata resources and blobs. */
+ /* Write file blobs and metadata resources. */
if (!(write_flags & WIMLIB_WRITE_FLAG_PIPABLE)) {
/* Default case: create a normal (non-pipable) WIM. */
ret = write_file_blobs(wim, image, write_flags,
if (ret)
goto out_restore_hdr;
- ret = write_metadata_blobs(wim, image, write_flags);
+ ret = write_metadata_resources(wim, image, write_flags);
if (ret)
goto out_restore_hdr;
} else {
if (ret)
goto out_truncate;
- ret = write_metadata_blobs(wim, WIMLIB_ALL_IMAGES, write_flags);
+ ret = write_metadata_resources(wim, WIMLIB_ALL_IMAGES, write_flags);
if (ret)
goto out_truncate;
* compressed XML data, MS software cannot. */
ret = write_wim_resource_from_buffer(xml_data,
xml_len,
- WIM_RESHDR_FLAG_METADATA,
+ true,
&wim->out_fd,
WIMLIB_COMPRESSION_TYPE_NONE,
0,