]> wimlib.net Git - wimlib/blobdiff - src/resource.c
Various fixes and cleanups
[wimlib] / src / resource.c
index 01d481df0f97057a074e7168270e0616e9359c2e..2576197194cada057b7712504e580cd91d6732c4 100644 (file)
@@ -83,7 +83,7 @@ static int read_compressed_resource(FILE *fp, u64 resource_compressed_size,
 
        int (*decompress)(const void *, uint, void *, uint);
        /* Set the appropriate decompress function. */
-       if (resource_ctype == WIM_COMPRESSION_TYPE_LZX)
+       if (resource_ctype == WIMLIB_COMPRESSION_TYPE_LZX)
                decompress = lzx_decompress;
        else
                decompress = xpress_decompress;
@@ -419,6 +419,7 @@ u8 *put_resource_entry(u8 *p, const struct resource_entry *entry)
        return p;
 }
 
+#ifdef WITH_FUSE
 static FILE *wim_get_fp(WIMStruct *w)
 {
        pthread_mutex_lock(&w->fp_tab_mutex);
@@ -469,6 +470,7 @@ out:
        pthread_mutex_unlock(&w->fp_tab_mutex);
        return ret;
 }
+#endif
 
 /*
  * Reads some data from the resource corresponding to a WIM lookup table entry.
@@ -501,23 +503,27 @@ int read_wim_resource(const struct lookup_table_entry *lte, u8 buf[],
                 * or uncompressed. */
                wimlib_assert(lte->wim != NULL);
 
+               #ifdef WITH_FUSE
                if (flags & WIMLIB_RESOURCE_FLAG_MULTITHREADED) {
                        fp = wim_get_fp(lte->wim);
                        if (!fp)
                                return WIMLIB_ERR_OPEN;
-               } else {
+               } else
+               #endif
+               {
+                       wimlib_assert(!(flags & WIMLIB_RESOURCE_FLAG_MULTITHREADED));
                        wimlib_assert(lte->wim->fp != NULL);
                        fp = lte->wim->fp;
                }
 
                ctype = wim_resource_compression_type(lte);
 
-               wimlib_assert(ctype != WIM_COMPRESSION_TYPE_NONE ||
+               wimlib_assert(ctype != WIMLIB_COMPRESSION_TYPE_NONE ||
                              (lte->resource_entry.original_size ==
                               lte->resource_entry.size));
 
                if ((flags & WIMLIB_RESOURCE_FLAG_RAW)
-                   || ctype == WIM_COMPRESSION_TYPE_NONE)
+                   || ctype == WIMLIB_COMPRESSION_TYPE_NONE)
                        ret = read_uncompressed_resource(fp,
                                                         lte->resource_entry.offset + offset,
                                                         size, buf);
@@ -527,11 +533,13 @@ int read_wim_resource(const struct lookup_table_entry *lte, u8 buf[],
                                                       lte->resource_entry.original_size,
                                                       lte->resource_entry.offset,
                                                       ctype, size, offset, buf);
+       #ifdef WITH_FUSE
                if (flags & WIMLIB_RESOURCE_FLAG_MULTITHREADED) {
                        int ret2 = wim_release_fp(lte->wim, fp);
                        if (ret == 0)
                                ret = ret2;
                }
+       #endif
                break;
        case RESOURCE_IN_STAGING_FILE:
        case RESOURCE_IN_FILE_ON_DISK:
@@ -566,17 +574,15 @@ int read_wim_resource(const struct lookup_table_entry *lte, u8 buf[],
        case RESOURCE_IN_NTFS_VOLUME:
                wimlib_assert(lte->ntfs_loc != NULL);
                wimlib_assert(lte->attr != NULL);
-               {
-                       if (lte->ntfs_loc->is_reparse_point)
-                               offset += 8;
-                       if (ntfs_attr_pread(lte->attr, offset, size, buf) != size) {
-                               ERROR_WITH_ERRNO("Error reading NTFS attribute "
-                                                "at `%s'",
-                                                lte->ntfs_loc->path_utf8);
-                               ret = WIMLIB_ERR_NTFS_3G;
-                       }
-                       break;
+               if (lte->ntfs_loc->is_reparse_point)
+                       offset += 8;
+               if (ntfs_attr_pread(lte->attr, offset, size, buf) != size) {
+                       ERROR_WITH_ERRNO("Error reading NTFS attribute "
+                                        "at `%s'",
+                                        lte->ntfs_loc->path_utf8);
+                       ret = WIMLIB_ERR_NTFS_3G;
                }
+               break;
 #endif
        default:
                wimlib_assert(0);
@@ -688,9 +694,6 @@ int extract_full_wim_resource_to_fd(const struct lookup_table_entry *lte, int fd
  *
  * The output_resource_entry, out_refcnt, and part_number fields of @lte are
  * updated.
- *
- * Metadata resources are not copied (they are handled elsewhere for joining and
- * splitting).
  */
 int copy_resource(struct lookup_table_entry *lte, void *wim)
 {
@@ -738,15 +741,14 @@ int read_metadata_resource(WIMStruct *w, struct image_metadata *imd)
        struct inode_table inode_tab;
        const struct lookup_table_entry *metadata_lte;
        u64 metadata_len;
-       u64 metadata_offset;
        struct hlist_head inode_list;
 
        metadata_lte = imd->metadata_lte;
        metadata_len = wim_resource_size(metadata_lte);
-       metadata_offset = metadata_lte->resource_entry.offset;
 
        DEBUG("Reading metadata resource: length = %"PRIu64", "
-             "offset = %"PRIu64"", metadata_len, metadata_offset);
+             "offset = %"PRIu64"", metadata_len,
+             metadata_lte->resource_entry.offset);
 
        /* There is no way the metadata resource could possibly be less than (8
         * + WIM_DENTRY_DISK_SIZE) bytes, where the 8 is for security data (with
@@ -804,6 +806,8 @@ int read_metadata_resource(WIMStruct *w, struct image_metadata *imd)
                goto out_free_security_data;
        }
 
+       DEBUG("Reading root dentry");
+
        /* Allocate memory for the root dentry and read it into memory */
        dentry = MALLOC(sizeof(struct dentry));
        if (!dentry) {
@@ -818,8 +822,16 @@ int read_metadata_resource(WIMStruct *w, struct image_metadata *imd)
        /* This is the root dentry, so set its parent to itself. */
        dentry->parent = dentry;
 
-       if (ret != 0)
-               goto out_free_dentry_tree;
+       if (ret == 0 && dentry->length == 0) {
+               ERROR("Metadata resource cannot begin with end-of-directory entry!");
+               ret = WIMLIB_ERR_INVALID_DENTRY;
+       }
+
+       if (ret != 0) {
+               FREE(dentry);
+               goto out_free_security_data;
+       }
+
        inode_add_dentry(dentry, dentry->d_inode);
 
        /* Now read the entire directory entry tree into memory. */
@@ -848,11 +860,13 @@ int read_metadata_resource(WIMStruct *w, struct image_metadata *imd)
        if (ret != 0)
                goto out_free_dentry_tree;
 
-       DEBUG("Running miscellaneous verifications on the dentry tree");
-       for_lookup_table_entry(w->lookup_table, lte_zero_real_refcnt, NULL);
-       ret = for_dentry_in_tree(dentry, verify_dentry, w);
-       if (ret != 0)
-               goto out_free_dentry_tree;
+       if (!w->all_images_verified) {
+               DEBUG("Running miscellaneous verifications on the dentry tree");
+               for_lookup_table_entry(w->lookup_table, lte_zero_real_refcnt, NULL);
+               ret = for_dentry_in_tree(dentry, verify_dentry, w);
+               if (ret != 0)
+                       goto out_free_dentry_tree;
+       }
 
        DEBUG("Done reading image metadata");
 
@@ -869,6 +883,14 @@ out_free_buf:
        return ret;
 }
 
+static void 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;
+}
+
 /* Write the metadata resource for the current WIM image. */
 int write_metadata_resource(WIMStruct *w)
 {
@@ -879,18 +901,14 @@ int write_metadata_resource(WIMStruct *w)
        struct dentry *root;
        struct lookup_table_entry *lte;
        u64 metadata_original_size;
-       const struct wim_security_data *sd;
+       struct wim_security_data *sd;
 
-       DEBUG("Writing metadata resource for image %d", w->current_image);
+       DEBUG("Writing metadata resource for image %d (offset = %"PRIu64")",
+             w->current_image, ftello(w->out_fp));
 
        root = wim_root_dentry(w);
        sd = wim_security_data(w);
 
-       /* We do not allow the security data pointer to be NULL, although it may
-        * point to an empty security data with no entries. */
-       wimlib_assert(root != NULL);
-       wimlib_assert(sd != NULL);
-
        /* 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,
@@ -898,7 +916,8 @@ int write_metadata_resource(WIMStruct *w)
         * - plus 8 bytes for an end-of-directory entry following the root
         *   dentry (shouldn't really be needed, but just in case...)
         */
-       subdir_offset = ((sd->total_length + 7) & ~7) +
+       recalculate_security_data_length(sd);
+       subdir_offset = (((u64)sd->total_length + 7) & ~7) +
                        dentry_correct_total_length(root) + 8;
 
        /* Calculate the subdirectory offsets for the entire dentry tree. */
@@ -929,8 +948,6 @@ int write_metadata_resource(WIMStruct *w)
         * it. */
        lte = wim_metadata_lookup_table_entry(w);
 
-       wimlib_assert(lte != NULL);
-
        /* Write the metadata resource to the output WIM using the proper
         * compression type.  The lookup table entry for the metadata resource
         * is updated. */
@@ -954,12 +971,10 @@ int write_metadata_resource(WIMStruct *w)
         * */
        lookup_table_unlink(w->lookup_table, lte);
        lookup_table_insert(w->lookup_table, lte);
-
-       wimlib_assert(lte->out_refcnt == 0);
        lte->out_refcnt = 1;
 
-       /* Make sure that the resource entry is written marked with the metadata
-        * flag. */
+       /* Make sure that the lookup table entry for this metadata resource is
+        * marked with the metadata flag. */
        lte->output_resource_entry.flags |= WIM_RESHDR_FLAG_METADATA;
 out:
        /* All the data has been written to the new WIM; no need for the buffer