Trim down 'flags' member of 'struct blob_descriptor'
authorEric Biggers <ebiggers3@gmail.com>
Thu, 2 Apr 2015 01:43:36 +0000 (20:43 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Fri, 3 Apr 2015 23:35:44 +0000 (18:35 -0500)
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'.

15 files changed:
include/wimlib/blob_table.h
include/wimlib/resource.h
include/wimlib/wim.h
include/wimlib/write.h
src/add_image.c
src/blob_table.c
src/extract.c
src/integrity.c
src/metadata_resource.c
src/mount_image.c
src/resource.c
src/split.c
src/wim.c
src/write.c
src/xml.c

index eca035a..b71abca 100644 (file)
@@ -80,8 +80,8 @@ 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;
@@ -332,24 +332,6 @@ sort_blob_list_by_sequential_order(struct list_head *blob_list,
 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)
 {
index 98305f0..ddd9ad9 100644 (file)
@@ -310,11 +310,6 @@ struct pwm_blob_hdr {
                                        /* +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 {
index 0f77aab..b0d351e 100644 (file)
@@ -182,6 +182,9 @@ static inline bool wim_is_pipable(const WIMStruct *wim)
        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);
 
index af1a635..82e5576 100644 (file)
@@ -64,12 +64,14 @@ write_wim_part(WIMStruct *wim,
               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 */
index d377829..e2106c9 100644 (file)
@@ -49,8 +49,8 @@ add_empty_image_metadata(WIMStruct *wim)
                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();
index 6cc0a98..c94635f 100644 (file)
@@ -738,7 +738,6 @@ assign_blob_to_solid_resource(const struct wim_reshdr *reshdr,
        /* 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;
@@ -1014,7 +1013,6 @@ read_blob_table(WIMStruct *wim)
 
                        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);
                }
@@ -1034,6 +1032,8 @@ read_blob_table(WIMStruct *wim)
 
                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.
@@ -1155,9 +1155,9 @@ write_blob_descriptor(struct blob_descriptor_disk *disk_entry,
 }
 
 /* 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,
@@ -1239,7 +1239,7 @@ write_blob_table_from_blob_list(struct list_head *blob_list,
         * 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,
@@ -1355,8 +1355,10 @@ blob_to_wimlib_resource_entry(const struct blob_descriptor *blob,
 
        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;
@@ -1365,14 +1367,15 @@ blob_to_wimlib_resource_entry(const struct blob_descriptor *blob,
                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 {
index 68fab3f..56ec644 100644 (file)
@@ -182,9 +182,9 @@ read_pwm_blob_header(WIMStruct *pwm, struct blob_descriptor *blob,
        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:
@@ -230,12 +230,11 @@ read_blobs_from_pipe(struct apply_ctx *ctx,
                        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);
@@ -1926,8 +1925,7 @@ wimlib_extract_image_from_pipe_with_progress(int pipe_fd,
                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;
@@ -1996,7 +1994,7 @@ wimlib_extract_image_from_pipe_with_progress(int pipe_fd,
                        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;
index c4a6f2e..0d1e137 100644 (file)
@@ -333,7 +333,7 @@ write_integrity_table(WIMStruct *wim,
 
        ret = write_wim_resource_from_buffer(new_table,
                                             new_table_size,
-                                            0,
+                                            false,
                                             &wim->out_fd,
                                             WIMLIB_COMPRESSION_TYPE_NONE,
                                             0,
index c187d69..1394ef9 100644 (file)
@@ -244,7 +244,9 @@ write_metadata_resource(WIMStruct *wim, int image, int write_resource_flags)
        /* 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,
index 7fe8bb5..9d7ddd3 100644 (file)
@@ -1018,9 +1018,10 @@ renew_current_image(struct wimfs_context *ctx)
        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
index f3e1349..11e09d6 100644 (file)
@@ -909,25 +909,15 @@ int
 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
@@ -935,27 +925,21 @@ wim_reshdr_to_hash(const struct wim_reshdr *reshdr, WIMStruct *wim,
                   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 {
@@ -1282,9 +1266,9 @@ read_blobs_in_solid_resource(struct blob_descriptor *first_blob,
  */
 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;
@@ -1323,10 +1307,9 @@ read_blob_list(struct list_head *blob_list,
        {
                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;
index 43d26db..88f9b2b 100644 (file)
@@ -150,11 +150,6 @@ add_blob_to_swm(struct blob_descriptor *blob, void *_swm_info)
        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
@@ -168,8 +163,8 @@ add_blob_to_swm(struct blob_descriptor *blob, void *_swm_info)
        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;
@@ -192,7 +187,7 @@ add_blob_to_swm(struct blob_descriptor *blob, void *_swm_info)
                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);
        }
@@ -218,6 +213,12 @@ wimlib_split(WIMStruct *wim, const tchar *swm_name,
        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;
 
index 5feb7a4..97aad09 100644 (file)
--- a/src/wim.c
+++ b/src/wim.c
@@ -143,6 +143,19 @@ wim_default_chunk_size(int ctype)
        }
 }
 
+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
index 03f3055..75a6fcf 100644 (file)
@@ -212,13 +212,13 @@ can_raw_copy(const struct blob_descriptor *blob,
        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
@@ -230,9 +230,6 @@ blob_set_out_reshdr_for_reuse(struct blob_descriptor *blob)
        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;
@@ -241,36 +238,31 @@ blob_set_out_reshdr_for_reuse(struct blob_descriptor *blob)
                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)
@@ -877,8 +869,9 @@ should_rewrite_blob_uncompressed(const struct write_blobs_ctx *ctx,
         * 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;
@@ -926,15 +919,10 @@ write_chunk(struct write_blobs_ctx *ctx, const void *cchunk,
                /* 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;
                }
@@ -1007,7 +995,7 @@ write_chunk(struct write_blobs_ctx *ctx, const void *cchunk,
                        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;
 
@@ -1365,11 +1353,22 @@ remove_empty_blobs(struct list_head *blob_list)
                        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)
 {
@@ -1681,8 +1680,8 @@ write_blob_list(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;
@@ -1707,17 +1706,6 @@ out_destroy_context:
        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,
@@ -1762,6 +1750,7 @@ 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,
@@ -1784,51 +1773,38 @@ write_wim_resource(struct blob_descriptor *blob,
                               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 {
@@ -2215,7 +2191,7 @@ write_file_blobs(WIMStruct *wim, int image, int write_flags,
 }
 
 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;
@@ -2719,7 +2695,7 @@ write_pipable_wim(WIMStruct *wim, int image, int write_flags,
 
        /* 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;
 
@@ -2980,7 +2956,7 @@ write_wim_part(WIMStruct *wim,
        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,
@@ -2990,7 +2966,7 @@ write_wim_part(WIMStruct *wim,
                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 {
@@ -3266,7 +3242,7 @@ overwrite_wim_inplace(WIMStruct *wim, int write_flags, unsigned num_threads)
        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;
 
index 58750a1..24fb328 100644 (file)
--- a/src/xml.c
+++ b/src/xml.c
@@ -1581,7 +1581,7 @@ write_wim_xml_data(WIMStruct *wim, int image, u64 total_bytes,
         * 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,