]> wimlib.net Git - wimlib/blobdiff - src/lookup_table.c
Use read_stream_list() for extraction
[wimlib] / src / lookup_table.c
index 0429a110b7c52e1d8c96f05727e4b1fc7667e2bc..fe0872cc9ba75d2549e064875799a10bb720c81c 100644 (file)
@@ -82,7 +82,6 @@ new_lookup_table_entry(void)
        }
        lte->refcnt = 1;
        BUILD_BUG_ON(RESOURCE_NONEXISTENT != 0);
-       BUILD_BUG_ON(WIMLIB_COMPRESSION_TYPE_NONE != 0);
        return lte;
 }
 
@@ -311,6 +310,7 @@ cmp_streams_by_sequential_order(const void *p1, const void *p2)
        const struct wim_lookup_table_entry *lte1, *lte2;
        int v;
        WIMStruct *wim1, *wim2;
+       u64 offset1, offset2;
 
        lte1 = *(const struct wim_lookup_table_entry**)p1;
        lte2 = *(const struct wim_lookup_table_entry**)p2;
@@ -339,9 +339,12 @@ cmp_streams_by_sequential_order(const void *p1, const void *p2)
                        return v;
 
                /* Compare by offset.  */
-               if (lte1->rspec->offset_in_wim < lte2->rspec->offset_in_wim)
+               offset1 = lte1->rspec->offset_in_wim + lte1->offset_in_res;
+               offset2 = lte2->rspec->offset_in_wim + lte2->offset_in_res;
+
+               if (offset1 < offset2)
                        return -1;
-               if (lte1->rspec->offset_in_wim > lte2->rspec->offset_in_wim)
+               if (offset1 > offset2)
                        return 1;
                return 0;
        case RESOURCE_IN_FILE_ON_DISK:
@@ -381,7 +384,7 @@ sort_stream_list_by_sequential_order(struct list_head *stream_list,
 
        array_size = num_streams * sizeof(array[0]);
        array = MALLOC(array_size);
-       if (!array)
+       if (array == NULL)
                return WIMLIB_ERR_NOMEM;
        cur = stream_list->next;
        for (i = 0; i < num_streams; i++) {
@@ -465,28 +468,22 @@ struct wim_lookup_table_entry_disk {
 #define WIM_LOOKUP_TABLE_ENTRY_DISK_SIZE 50
 
 static int
-validate_resource(const struct wim_resource_spec *rspec,
-                 u64 offset_save, u64 size_save)
+validate_resource(const struct wim_resource_spec *rspec)
 {
        struct wim_lookup_table_entry *lte;
-       list_for_each_entry(lte, &rspec->lte_list, wim_resource_list) {
-               if (rspec->flags & WIM_RESHDR_FLAG_COMPRESSED)
-                       lte->flags |= WIM_RESHDR_FLAG_COMPRESSED;
-               else
-                       lte->flags &= ~WIM_RESHDR_FLAG_COMPRESSED;
-
-               if (!(lte->flags & WIM_RESHDR_FLAG_CONCAT)) {
-                       lte->offset_in_res = offset_save;
-                       lte->size = size_save;
-               }
-
+       if (!list_is_singular(&rspec->lte_list)) {
+               list_for_each_entry(lte, &rspec->lte_list, wim_resource_list) {
+                       if (rspec->flags & WIM_RESHDR_FLAG_COMPRESSED)
+                               lte->flags |= WIM_RESHDR_FLAG_COMPRESSED;
+                       else
+                               lte->flags &= ~WIM_RESHDR_FLAG_COMPRESSED;
 
-               if (lte->offset_in_res + lte->size < lte->size ||
-                   lte->offset_in_res + lte->size > rspec->uncompressed_size)
-               {
-                       return WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY;
+                       if (lte->offset_in_res + lte->size < lte->size ||
+                           lte->offset_in_res + lte->size > rspec->uncompressed_size)
+                       {
+                               return WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY;
+                       }
                }
-               print_lookup_table_entry(lte, stderr);
        }
        return 0;
 }
@@ -512,8 +509,6 @@ read_wim_lookup_table(WIMStruct *wim)
        struct wim_lookup_table *table;
        struct wim_lookup_table_entry *cur_entry, *duplicate_entry;
        struct wim_resource_spec *cur_rspec;
-       u64 size_save;
-       u64 offset_save;
        void *buf;
 
        BUILD_BUG_ON(sizeof(struct wim_lookup_table_entry_disk) !=
@@ -548,16 +543,22 @@ read_wim_lookup_table(WIMStruct *wim)
                u16 part_number;
                struct wim_reshdr reshdr;
 
-               get_wim_reshdr(&disk_entry->reshdr, &reshdr);
+               ret = get_wim_reshdr(&disk_entry->reshdr, &reshdr);
+               if (ret) {
+                       ERROR("Resource header is invalid!");
+                       goto out_free_lookup_table;
+               }
 
-               DEBUG("reshdr: size=%"PRIu64", original_size=%"PRIu64", "
-                     "offset=%"PRIu64", flags=0x%02x",
+               DEBUG("reshdr: size_in_wim=%"PRIu64", "
+                     "uncompressed_size=%"PRIu64", "
+                     "offset_in_wim=%"PRIu64", "
+                     "flags=0x%02x",
                      reshdr.size_in_wim, reshdr.uncompressed_size,
                      reshdr.offset_in_wim, reshdr.flags);
 
                cur_entry = new_lookup_table_entry();
                if (cur_entry == NULL) {
-                       ERROR("Not enough memory to read lookup table.");
+                       ERROR("Not enough memory to read lookup table!");
                        ret = WIMLIB_ERR_NOMEM;
                        goto out_free_lookup_table;
                }
@@ -582,21 +583,22 @@ read_wim_lookup_table(WIMStruct *wim)
                         * simply a single normal entry by itself.  */
 
                        if (cur_rspec != NULL) {
-                               ret = validate_resource(cur_rspec, offset_save,
-                                                       size_save);
+                               ret = validate_resource(cur_rspec);
                                if (ret)
                                        goto out_free_cur_entry;
                        }
 
                        cur_rspec = MALLOC(sizeof(struct wim_resource_spec));
                        if (cur_rspec == NULL) {
-                               ERROR("Not enough memory to read lookup table.");
+                               ERROR("Not enough memory to read lookup table!");
                                ret = WIMLIB_ERR_NOMEM;
                                goto out_free_cur_entry;
                        }
-                       offset_save = reshdr.offset_in_wim;
-                       size_save = reshdr.size_in_wim;
                        wim_res_hdr_to_spec(&reshdr, wim, cur_rspec);
+                       if (reshdr.flags & WIM_RESHDR_FLAG_CONCAT) {
+                               cur_rspec->size_in_wim = 0;
+                               cur_rspec->uncompressed_size = 0;
+                       }
                } else if (is_zero_hash(cur_entry->hash)) {
                        /* Found the resource specification for the run.  */
                        cur_rspec->offset_in_wim = reshdr.offset_in_wim;
@@ -609,7 +611,9 @@ read_wim_lookup_table(WIMStruct *wim)
                              cur_rspec->flags);
                        free_lookup_table_entry(cur_entry);
                        continue;
-               } else {
+               }
+
+               if (reshdr.flags & WIM_RESHDR_FLAG_CONCAT) {
                        /* Continuing the run with another stream.  */
                        DEBUG("Continuing concat run with stream: "
                              "%"PRIu64" uncompressed bytes @ resource offset %"PRIu64")",
@@ -627,11 +631,10 @@ read_wim_lookup_table(WIMStruct *wim)
                        cur_entry->size = reshdr.size_in_wim;
                        cur_entry->flags = reshdr.flags;
                } else {
-                       /* These may be overwritten in validate_resource() if
-                        * the run turns out to be a concatenation.  */
                        cur_entry->offset_in_res = 0;
                        cur_entry->size = reshdr.uncompressed_size;
                        cur_entry->flags = reshdr.flags;
+                       cur_rspec = NULL;
                }
 
                if (is_zero_hash(cur_entry->hash)) {
@@ -709,7 +712,7 @@ read_wim_lookup_table(WIMStruct *wim)
        }
 
        if (cur_rspec != NULL) {
-               ret = validate_resource(cur_rspec, offset_save, size_save);
+               ret = validate_resource(cur_rspec);
                if (ret)
                        goto out_free_cur_entry;
        }
@@ -1402,7 +1405,7 @@ hash_unhashed_stream(struct wim_lookup_table_entry *lte,
         * the SHA1 has been calculated. */
        back_ptr = retrieve_lte_pointer(lte);
 
-       ret = sha1_resource(lte);
+       ret = sha1_stream(lte);
        if (ret)
                return ret;