-#include "wimlib_internal.h"
-#include "dentry.h"
-#include "lookup_table.h"
-
-static int verify_inode(struct wim_inode *inode, const WIMStruct *w)
-{
- const struct wim_lookup_table *table = w->lookup_table;
- const struct wim_security_data *sd = wim_const_security_data(w);
- const struct wim_dentry *first_dentry = inode_first_dentry(inode);
- const 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 `%s' has an invalid security ID (%d)",
- first_dentry->full_path_utf8, inode->i_security_id);
- goto out;
- }
-
- if (inode->i_security_id >= sd->num_entries) {
- ERROR("Dentry `%s' has an invalid security ID (%d) "
- "(there are only %u entries in the security table)",
- first_dentry->full_path_utf8, inode->i_security_id,
- sd->num_entries);
- goto out;
- }
-
- /* Check that lookup table entries for all the inode's stream exist,
- * except if the SHA1 message digest is all 0's, which indicates an
- * empty stream.
- *
- * This check is skipped on split WIMs. */
- if (w->hdr.total_parts == 1) {
- 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);
- lte = __lookup_resource(table, hash);
- if (!lte && !is_zero_hash(hash)) {
- ERROR("Could not find lookup table entry for stream "
- "%u of dentry `%s'", i, first_dentry->full_path_utf8);
- goto out;
- }
- if (lte)
- lte->real_refcnt += inode->i_nlink;
-
- /* The following is now done when required by
- * wim_run_full_verifications(). */
-
- #if 0
- if (lte && !w->full_verification_in_progress &&
- lte->real_refcnt > lte->refcnt)
- {
- #ifdef ENABLE_ERROR_MESSAGES
- WARNING("The following lookup table entry "
- "has a reference count of %u, but",
- lte->refcnt);
- WARNING("We found %u references to it",
- lte->real_refcnt);
- WARNING("(One dentry referencing it is at `%s')",
- first_dentry->full_path_utf8);
-
- print_lookup_table_entry(lte);
- #endif
- /* Guess what! install.wim for Windows 8
- * contains many streams referenced by more
- * dentries than the refcnt stated in the lookup
- * table entry. So we will need to handle this
- * case and not just make it be an error... I'm
- * just setting the reference count to the
- * number of references we found.
- * (Unfortunately, even after doing this, the
- * reference count could be too low if it's also
- * referenced in other WIM images) */
-
- #if 1
- lte->refcnt = lte->real_refcnt;
- WARNING("Fixing reference count");
- #else
- goto out;
- #endif
- }
- #endif
- }
- }
-
- /* Make sure there is only one unnamed data stream. */
- 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);
- if (inode_stream_name_len(inode, i) == 0 && !is_zero_hash(hash))
- num_unnamed_streams++;
- }
- if (num_unnamed_streams > 1) {
- ERROR("Dentry `%s' has multiple (%u) un-named streams",
- first_dentry->full_path_utf8, num_unnamed_streams);
- goto out;
- }
-
- /* Currently ignoring this test because wimlib does not apply DOS names
- * to a file with hard links (see apply_dentry_ntfs()). */
-#if 0
- /* Files cannot have multiple DOS names, even if they have multiple
- * names in multiple directories (i.e. hard links) ??? XXX */
- const struct wim_dentry *dentry_with_dos_name = NULL;
- inode_for_each_dentry(dentry, inode) {
- if (dentry->short_name_len) {
- if (dentry_with_dos_name) {
- ERROR("Hard-linked file has a DOS name at "
- "both `%s' and `%s'",
- dentry_with_dos_name->full_path_utf8,
- dentry->full_path_utf8);
- goto out;
- }
- dentry_with_dos_name = dentry;
- }
- }