/*
* Copyright (C) 2012, 2013 Eric Biggers
*
- * This file is part of wimlib, a library for working with WIM files.
+ * This file is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at your option) any
+ * later version.
*
- * wimlib is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 3 of the License, or (at your option) any later
- * version.
+ * This file is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
*
- * wimlib is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * wimlib; if not, see http://www.gnu.org/licenses/.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this file; if not, see http://www.gnu.org/licenses/.
*/
#ifdef HAVE_CONFIG_H
# 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;
* 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;
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;
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
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);
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;