]> wimlib.net Git - wimlib/blobdiff - src/metadata_resource.c
New helper macro: ALIGN()
[wimlib] / src / metadata_resource.c
index 7c97b3dfe179daa6b0d9b09a422a00afe444b722..014d16b999388267ff5eec1e17025d0b43b1c15e 100644 (file)
 #  include "config.h"
 #endif
 
+#include "wimlib/assert.h"
+#include "wimlib/blob_table.h"
 #include "wimlib/dentry.h"
 #include "wimlib/error.h"
-#include "wimlib/lookup_table.h"
 #include "wimlib/metadata.h"
 #include "wimlib/resource.h"
 #include "wimlib/security.h"
 #include "wimlib/write.h"
 
+/* Fix the security ID for every inode to be either -1 or in bounds.  */
+static void
+fix_security_ids(struct wim_image_metadata *imd, const u32 num_entries)
+{
+       struct wim_inode *inode;
+       unsigned long invalid_count = 0;
+
+       image_for_each_inode(inode, imd) {
+               if ((u32)inode->i_security_id >= num_entries) {
+                       if (inode->i_security_id >= 0)
+                               invalid_count++;
+                       inode->i_security_id = -1;
+               }
+       }
+       if (invalid_count)
+               WARNING("%lu inodes had invalid security IDs", invalid_count);
+}
+
 /*
  * Reads and parses a metadata resource for an image in the WIM file.
  *
- * @wim:
- *     Pointer to the WIMStruct for the WIM file.
- *
  * @imd:
  *     Pointer to the image metadata structure for the image whose metadata
- *     resource we are reading.  Its `metadata_lte' member specifies the lookup
+ *     resource we are reading.  Its `metadata_blob' member specifies the blob
  *     table entry for the metadata resource.  The rest of the image metadata
  *     entry will be filled in by this function.
  *
  *     WIMLIB_ERR_DECOMPRESSION
  */
 int
-read_metadata_resource(WIMStruct *wim, struct wim_image_metadata *imd)
+read_metadata_resource(struct wim_image_metadata *imd)
 {
-       const struct wim_lookup_table_entry *metadata_lte;
+       const struct blob_descriptor *metadata_blob;
        void *buf;
        int ret;
        struct wim_security_data *sd;
        struct wim_dentry *root;
-       struct wim_inode *inode;
 
-       metadata_lte = imd->metadata_lte;
+       metadata_blob = imd->metadata_blob;
 
-       DEBUG("Reading metadata resource (size=%"PRIu64").", metadata_lte->size);
+       DEBUG("Reading metadata resource (size=%"PRIu64").", metadata_blob->size);
 
        /* Read the metadata resource into memory.  (It may be compressed.)  */
-       ret = read_full_stream_into_alloc_buf(metadata_lte, &buf);
+       ret = read_blob_into_alloc_buf(metadata_blob, &buf);
        if (ret)
                return ret;
 
        /* Checksum the metadata resource.  */
-       if (!metadata_lte->dont_check_metadata_hash) {
+       if (!metadata_blob->dont_check_metadata_hash) {
                u8 hash[SHA1_HASH_SIZE];
 
-               sha1_buffer(buf, metadata_lte->size, hash);
-               if (!hashes_equal(metadata_lte->hash, hash)) {
+               sha1_buffer(buf, metadata_blob->size, hash);
+               if (!hashes_equal(metadata_blob->hash, hash)) {
                        ERROR("Metadata resource is corrupted "
                              "(invalid SHA-1 message digest)!");
                        ret = WIMLIB_ERR_INVALID_METADATA_RESOURCE;
@@ -93,11 +108,11 @@ read_metadata_resource(WIMStruct *wim, struct wim_image_metadata *imd)
         * by a directory entry of length '0', really of length 8, because
         * that's how long the 'length' field is.  */
 
-       ret = read_wim_security_data(buf, metadata_lte->size, &sd);
+       ret = read_wim_security_data(buf, metadata_blob->size, &sd);
        if (ret)
                goto out_free_buf;
 
-       ret = read_dentry_tree(buf, metadata_lte->size, sd->total_length, &root);
+       ret = read_dentry_tree(buf, metadata_blob->size, sd->total_length, &root);
        if (ret)
                goto out_free_security_data;
 
@@ -111,13 +126,12 @@ read_metadata_resource(WIMStruct *wim, struct wim_image_metadata *imd)
        if (ret)
                goto out_free_dentry_tree;
 
-       image_for_each_inode(inode, imd)
-               check_inode(inode, sd);
+       fix_security_ids(imd, sd->num_entries);
 
        /* Success; fill in the image_metadata structure.  */
        imd->root_dentry = root;
        imd->security_data = sd;
-       INIT_LIST_HEAD(&imd->unhashed_streams);
+       INIT_LIST_HEAD(&imd->unhashed_blobs);
        DEBUG("Done parsing metadata resource.");
        return 0;
 
@@ -136,7 +150,7 @@ recalculate_security_data_length(struct wim_security_data *sd)
        u32 total_length = sizeof(u64) * sd->num_entries + 2 * sizeof(u32);
        for (u32 i = 0; i < sd->num_entries; i++)
                total_length += sd->sizes[i];
-       sd->total_length = (total_length + 7) & ~7;
+       sd->total_length = ALIGN(total_length, 8);
 }
 
 static int
@@ -171,16 +185,12 @@ prepare_metadata_resource(WIMStruct *wim, int image,
                imd->root_dentry = root;
        }
 
-       /* Offset of first child of the root dentry.  It's equal to:
-        * - The total length of the security data, rounded to the next 8-byte
-        *   boundary,
-        * - plus the total length of the root dentry,
-        * - plus 8 bytes for an end-of-directory entry following the root
-        *   dentry (shouldn't really be needed, but just in case...)
-        */
+       /* The offset of the first child of the root dentry is equal to the
+        * total length of the security data, plus the total length of the root
+        * dentry, plus 8 bytes for an end-of-directory entry following the root
+        * dentry (shouldn't really be needed, but just in case...)  */
        recalculate_security_data_length(sd);
-       subdir_offset = (((u64)sd->total_length + 7) & ~7) +
-                       dentry_out_total_length(root) + 8;
+       subdir_offset = sd->total_length + dentry_out_total_length(root) + 8;
 
        /* Calculate the subdirectory offsets for the entire dentry tree.  */
        calculate_subdir_offsets(root, &subdir_offset);
@@ -228,18 +238,20 @@ write_metadata_resource(WIMStruct *wim, int image, int write_resource_flags)
        imd = wim->image_metadata[image - 1];
 
        /* Write the metadata resource to the output WIM using the proper
-        * compression type, in the process updating the lookup table entry for
-        * the metadata resource.  */
-       ret = write_wim_resource_from_buffer(buf, len, WIM_RESHDR_FLAG_METADATA,
+        * compression type, in the process updating the blob descriptor for the
+        * metadata resource.  */
+       ret = write_wim_resource_from_buffer(buf,
+                                            len,
+                                            true,
                                             &wim->out_fd,
                                             wim->out_compression_type,
                                             wim->out_chunk_size,
-                                            &imd->metadata_lte->out_reshdr,
-                                            imd->metadata_lte->hash,
+                                            &imd->metadata_blob->out_reshdr,
+                                            imd->metadata_blob->hash,
                                             write_resource_flags);
 
        /* Original checksum was overridden; set a flag so it isn't used.  */
-       imd->metadata_lte->dont_check_metadata_hash = 1;
+       imd->metadata_blob->dont_check_metadata_hash = 1;
 
        FREE(buf);
        return ret;