- u8 *buf;
- u8 *p;
- int ret;
- u64 subdir_offset;
- struct dentry *root;
- struct lookup_table_entry *lte;
- u64 metadata_original_size;
- const struct wim_security_data *sd;
- const unsigned random_tail_len = 20;
-
- DEBUG("Writing metadata resource for image %d", w->current_image);
-
- 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,
- * - 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...)
- */
- subdir_offset = ((sd->total_length + 7) & ~7) +
- dentry_correct_total_length(root) + 8;
-
- /* Calculate the subdirectory offsets for the entire dentry tree. */
- calculate_subdir_offsets(root, &subdir_offset);
-
- /* Total length of the metadata resource (uncompressed) */
- metadata_original_size = subdir_offset + random_tail_len;
-
- /* Allocate a buffer to contain the uncompressed metadata resource */
- buf = MALLOC(metadata_original_size);
- if (!buf) {
- ERROR("Failed to allocate %"PRIu64" bytes for "
- "metadata resource", metadata_original_size);
- return WIMLIB_ERR_NOMEM;
- }
-
- /* Write the security data into the resource buffer */
- p = write_security_data(sd, buf);
-
- /* Write the dentry tree into the resource buffer */
- p = write_dentry_tree(root, p);
-
- /*
- * Append 20 random bytes to the metadata resource so that we don't have
- * identical metadata resources if we happen to append exactly the same
- * image twice without any changes in timestamps. If this were to
- * happen, it would cause confusion about the number and order of images
- * in the WIM.
- */
- randomize_byte_array(p, random_tail_len);
-
- /* We MUST have exactly filled the buffer; otherwise we calculated its
- * size incorrectly or wrote the data incorrectly. */
- wimlib_assert(p - buf + random_tail_len == metadata_original_size);
-
- /* Get the lookup table entry for the metadata resource so we can update
- * 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. */
- ret = write_wim_resource_from_buffer(buf, metadata_original_size,
- w->out_fp,
- wimlib_get_compression_type(w),
- <e->output_resource_entry,
- lte->hash);
- if (ret != 0)
- goto out;
-
- /* It's very likely the SHA1 message digest of the metadata resource
- * changed, so re-insert the lookup table entry into the lookup table.
- * */
- lookup_table_unlink(w->lookup_table, lte);
- lookup_table_insert(w->lookup_table, lte);
-
- /* We do not allow a metadata resource to be referenced multiple times,
- * and the 20 random bytes appended to it should make it extremely
- * likely for each metadata resource to be unique, even if the exact
- * same image is captured. */
- wimlib_assert(lte->out_refcnt == 0);
- lte->out_refcnt = 1;
-
- /* Make sure that the resource entry is written 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
- * anymore */
- FREE(buf);
- return ret;
+ /* Note: disk_entry may not be 8 byte aligned--- in that case, the
+ * offset and original_size members will be unaligned. (This should be
+ * okay since `struct resource_entry_disk' is declared as packed.) */
+ u64 size = entry->size;
+
+ disk_entry->size[0] = size >> 0;
+ disk_entry->size[1] = size >> 8;
+ disk_entry->size[2] = size >> 16;
+ disk_entry->size[3] = size >> 24;
+ disk_entry->size[4] = size >> 32;
+ disk_entry->size[5] = size >> 40;
+ disk_entry->size[6] = size >> 48;
+ disk_entry->flags = entry->flags;
+ disk_entry->offset = cpu_to_le64(entry->offset);
+ disk_entry->original_size = cpu_to_le64(entry->original_size);