]> wimlib.net Git - wimlib/blobdiff - src/verify.c
read_metadata_resource(): Check for named root here
[wimlib] / src / verify.c
index eef45d3ce3ee29eae902c9834302c8f0313964a2..501aea609787c3810b3e89470446c687b1841031 100644 (file)
@@ -41,23 +41,17 @@ verify_inode(struct wim_inode *inode, const WIMStruct *w)
        const struct wim_security_data *sd = wim_const_security_data(w);
        struct wim_dentry *first_dentry = inode_first_dentry(inode);
        struct wim_dentry *dentry;
-       int ret = WIMLIB_ERR_INVALID_DENTRY;
 
        /* Check the security ID.  -1 is valid and means "no security
         * descriptor".  Anything else has to be a valid index into the WIM
         * image's security descriptors table. */
-       if (inode->i_security_id < -1) {
-               ERROR("Dentry `%"TS"' has an invalid security ID (%d)",
-                     dentry_full_path(first_dentry), inode->i_security_id);
-               goto out;
-       }
-
-       if (inode->i_security_id >= sd->num_entries) {
-               ERROR("Dentry `%"TS"' has an invalid security ID (%d) "
-                     "(there are only %u entries in the security table)",
-                     dentry_full_path(first_dentry), inode->i_security_id,
-                     sd->num_entries);
-               goto out;
+       if (inode->i_security_id < -1 ||
+           (inode->i_security_id >= 0 &&
+            inode->i_security_id >= sd->num_entries))
+       {
+               WARNING("\"%"TS"\" has an invalid security ID (%d)",
+                       dentry_full_path(first_dentry), inode->i_security_id);
+               inode->i_security_id = -1;
        }
 
        /* Check that lookup table entries for all the inode's stream exist,
@@ -65,17 +59,17 @@ verify_inode(struct wim_inode *inode, const WIMStruct *w)
         * empty stream.
         *
         * This check is skipped on split WIMs. */
-       if (w->hdr.total_parts == 1) {
+       if (w->hdr.total_parts == 1 && !inode->i_resolved) {
                for (unsigned i = 0; i <= inode->i_num_ads; i++) {
                        struct wim_lookup_table_entry *lte;
                        const u8 *hash;
-                       hash = inode_stream_hash_unresolved(inode, i);
+                       hash = inode_stream_hash(inode, i);
                        lte = __lookup_resource(table, hash);
                        if (!lte && !is_zero_hash(hash)) {
                                ERROR("Could not find lookup table entry for stream "
                                      "%u of dentry `%"TS"'",
                                      i, dentry_full_path(first_dentry));
-                               goto out;
+                               return WIMLIB_ERR_INVALID_DENTRY;
                        }
                        if (lte)
                                lte->real_refcnt += inode->i_nlink;
@@ -86,14 +80,13 @@ verify_inode(struct wim_inode *inode, const WIMStruct *w)
        unsigned num_unnamed_streams = 0;
        for (unsigned i = 0; i <= inode->i_num_ads; i++) {
                const u8 *hash;
-               hash = inode_stream_hash_unresolved(inode, i);
+               hash = inode_stream_hash(inode, i);
                if (inode_stream_name_nbytes(inode, i) == 0 && !is_zero_hash(hash))
                        num_unnamed_streams++;
        }
        if (num_unnamed_streams > 1) {
-               ERROR("Dentry `%"TS"' has multiple (%u) un-named streams",
-                     dentry_full_path(first_dentry), num_unnamed_streams);
-               goto out;
+               WARNING("\"%"TS"\" has multiple (%u) un-named streams",
+                       dentry_full_path(first_dentry), num_unnamed_streams);
        }
 
        /* Files cannot have multiple DOS names, even if they have multiple
@@ -103,27 +96,26 @@ verify_inode(struct wim_inode *inode, const WIMStruct *w)
        inode_for_each_dentry(dentry, inode) {
                if (dentry_has_short_name(dentry)) {
                        if (dentry_with_dos_name) {
+                               /* This was previously an error, but if we
+                                * capture a WIM from UDF on Windows, hard links
+                                * are supported but DOS names are automatically
+                                * generated for all names for an inode.  */
+                       #if 0
                                ERROR("Hard-linked file has a DOS name at "
                                      "both `%"TS"' and `%"TS"'",
                                      dentry_full_path(dentry_with_dos_name),
                                      dentry_full_path(dentry));
-                               goto out;
+                               return WIMLIB_ERR_INVALID_DENTRY;
+                       #else
+                               dentry->dos_name_invalid = 1;
+                       #endif
                        }
                        dentry_with_dos_name = dentry;
                }
        }
 
-       /* Directories with multiple links have not been tested. XXX */
-       if (inode->i_nlink > 1 && inode->i_attributes & FILE_ATTRIBUTE_DIRECTORY) {
-               ERROR("Hard-linked directory `%"TS"' is unsupported",
-                     dentry_full_path(first_dentry));
-               goto out;
-       }
-
        inode->i_verified = 1;
-       ret = 0;
-out:
-       return ret;
+       return 0;
 }
 
 /* Run some miscellaneous verifications on a WIM dentry */
@@ -132,45 +124,14 @@ verify_dentry(struct wim_dentry *dentry, void *wim)
 {
        int ret;
        WIMStruct *w = wim;
-
        /* Verify the associated inode, but only one time no matter how many
         * dentries it has (unless we are doing a full verification of the WIM,
         * in which case we need to force the inode to be verified again.) */
        if (!dentry->d_inode->i_verified) {
                ret = verify_inode(dentry->d_inode, w);
-               if (ret != 0)
+               if (ret)
                        return ret;
        }
-
-       /* Make sure root dentry is unnamed, while every other dentry has at
-        * least a long name.
-        *
-        * I am assuming that dentries having only a DOS name is illegal; i.e.,
-        * Windows will always combine the Win32 name and DOS name for a file
-        * into a single WIM dentry, even if they are stored separately on NTFS.
-        * (This seems to be the case...) */
-       if (dentry_is_root(dentry)) {
-               if (dentry_has_long_name(dentry) || dentry_has_short_name(dentry)) {
-                       ERROR("The root dentry has a nonempty name!");
-                       return WIMLIB_ERR_INVALID_DENTRY;
-               }
-       } else {
-               if (!dentry_has_long_name(dentry)) {
-                       ERROR("Dentry `%"TS"' has no long name!",
-                             dentry_full_path(dentry));
-                       return WIMLIB_ERR_INVALID_DENTRY;
-               }
-       }
-
-#if 0
-       /* Check timestamps */
-       if (inode->i_last_access_time < inode->i_creation_time ||
-           inode->i_last_write_time < inode->i_creation_time) {
-               WARNING("Dentry `%"TS"' was created after it was last accessed or "
-                       "written to", dentry->full_path);
-       }
-#endif
-
        return 0;
 }
 
@@ -181,7 +142,7 @@ image_run_full_verifications(WIMStruct *w)
        struct wim_inode *inode;
 
        imd = wim_get_current_image_metadata(w);
-       image_for_each_inode(inode, imd)
+       image_for_each_inode(inode, imd) {
                inode->i_verified = 0;
        return for_dentry_in_tree(imd->root_dentry, verify_dentry, w);
 }