]> wimlib.net Git - wimlib/blobdiff - src/lookup_table.c
Comments etc.
[wimlib] / src / lookup_table.c
index 1fb2d4bdac747c1e4732da3f1526ec38a6dfd795..e8f44eac70355b6a0efdc895b15dd71111813469 100644 (file)
@@ -52,7 +52,7 @@ err:
        return NULL;
 }
 
-struct lookup_table_entry *new_lookup_table_entry(WIMStruct *wim)
+struct lookup_table_entry *new_lookup_table_entry()
 {
        struct lookup_table_entry *lte;
        
@@ -66,7 +66,6 @@ struct lookup_table_entry *new_lookup_table_entry(WIMStruct *wim)
 
        lte->part_number  = 1;
        lte->refcnt       = 1;
-       lte->wim          = wim;
        INIT_LIST_HEAD(&lte->lte_group_list);
        return lte;
 }
@@ -74,11 +73,31 @@ struct lookup_table_entry *new_lookup_table_entry(WIMStruct *wim)
 void free_lookup_table_entry(struct lookup_table_entry *lte)
 {
        if (lte) {
+#ifdef WITH_FUSE
                if (lte->staging_list.next)
                        list_del(&lte->staging_list);
-               if (lte->resource_location != RESOURCE_IN_WIM &&
-                   lte->resource_location != RESOURCE_NONEXISTENT)
+#endif
+               switch (lte->resource_location) {
+               case RESOURCE_IN_STAGING_FILE:
+               case RESOURCE_IN_ATTACHED_BUFFER:
+               case RESOURCE_IN_FILE_ON_DISK:
+                       wimlib_assert(&lte->file_on_disk ==
+                                     &lte->staging_file_name ==
+                                     &lte->attached_buffer);
                        FREE(lte->file_on_disk);
+                       break;
+#ifdef WITH_NTFS_3G
+               case RESOURCE_IN_NTFS_VOLUME:
+                       if (lte->ntfs_loc) {
+                               FREE(lte->ntfs_loc->path_utf8);
+                               FREE(lte->ntfs_loc->stream_name_utf16);
+                               FREE(lte->ntfs_loc);
+                       }
+                       break;
+#endif
+               default:
+                       break;
+               }
                FREE(lte);
        }
 }
@@ -134,7 +153,10 @@ lte_decrement_refcnt(struct lookup_table_entry *lte, struct lookup_table *table)
                wimlib_assert(lte->refcnt);
                if (--lte->refcnt == 0) {
                        lookup_table_unlink(table, lte);
-                       if (lte->num_opened_fds == 0) {
+               #ifdef WITH_FUSE
+                       if (lte->num_opened_fds == 0)
+               #endif
+                       {
                                free_lookup_table_entry(lte);
                                lte = NULL;
                        }
@@ -209,7 +231,7 @@ int read_lookup_table(WIMStruct *w)
                        ret = WIMLIB_ERR_READ;
                        goto out;
                }
-               cur_entry = new_lookup_table_entry(w);
+               cur_entry = new_lookup_table_entry();
                if (!cur_entry) {
                        ret = WIMLIB_ERR_NOMEM;
                        goto out;
@@ -222,6 +244,14 @@ int read_lookup_table(WIMStruct *w)
                p = get_u32(p, &cur_entry->refcnt);
                p = get_bytes(p, SHA1_HASH_SIZE, cur_entry->hash);
 
+               if (is_zero_hash(cur_entry->hash)) {
+                       ERROR("The WIM lookup table contains an entry with a "
+                             "SHA1 message digest of all 0's");
+                       ret = WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY;
+                       FREE(cur_entry);
+                       goto out;
+               }
+
                duplicate_entry = __lookup_resource(table, cur_entry->hash);
                if (duplicate_entry) {
                        ERROR("The WIM lookup table contains two entries with the "
@@ -231,6 +261,7 @@ int read_lookup_table(WIMStruct *w)
                        ERROR("The second entry is:");
                        print_lookup_table_entry(cur_entry);
                        ret = WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY;
+                       FREE(cur_entry);
                        goto out;
                }
                lookup_table_insert(table, cur_entry);
@@ -267,10 +298,6 @@ int write_lookup_table_entry(struct lookup_table_entry *lte, void *__out)
 
        out = __out;
 
-       /* do not write lookup table entries for empty files */
-       if (lte->output_resource_entry.original_size == 0)
-               return 0;
-
        /* Don't write entries that have not had file resources or metadata
         * resources written for them. */
        if (lte->out_refcnt == 0)
@@ -340,6 +367,8 @@ void print_lookup_table_entry(const struct lookup_table_entry *lte)
        case RESOURCE_IN_STAGING_FILE:
                printf("Staging File      = `%s'\n", lte->staging_file_name);
                break;
+       default:
+               break;
        }
        putchar('\n');
 }
@@ -393,7 +422,7 @@ int lookup_resource(WIMStruct *w, const char *path,
        struct dentry *dentry;
        struct lookup_table_entry *lte;
        unsigned stream_idx;
-       const char *stream_name;
+       const char *stream_name = NULL;
        char *p = NULL;
 
        if (lookup_flags & LOOKUP_FLAG_ADS_OK) {
@@ -486,12 +515,29 @@ int dentry_resolve_ltes(struct dentry *dentry, void *__table)
        return 0;
 }
 
+/* Return the lookup table entry for the unnamed data stream of a dentry, or
+ * NULL if there is none.
+ *
+ * You'd think this would be easier than it actually is, since the unnamed data
+ * stream should be the one referenced from the dentry itself.  Alas, if there
+ * are named data streams, Microsoft's "imagex.exe" program will put the unnamed
+ * data stream in one of the alternate data streams instead of inside the
+ * dentry.  So we need to check the alternate data streams too.
+ *
+ * Also, note that a dentry may appear to have than one unnamed stream, but if
+ * the SHA1 message digest is all 0's then the corresponding stream does not
+ * really "count" (this is the case for the dentry's own file stream when the
+ * file stream that should be there is actually in one of the alternate stream
+ * entries.).  This is despite the fact that we may need to extract such a
+ * missing entry as an empty file or empty named data stream.
+ */
 struct lookup_table_entry *
-dentry_first_lte(const struct dentry *dentry, const struct lookup_table *table)
+dentry_unnamed_lte(const struct dentry *dentry,
+                  const struct lookup_table *table)
 {
        if (dentry->resolved)
-               return dentry_first_lte_resolved(dentry);
+               return dentry_unnamed_lte_resolved(dentry);
        else
-               return dentry_first_lte_unresolved(dentry, table);
+               return dentry_unnamed_lte_unresolved(dentry, table);
 }