X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fblob_table.c;h=ab8d08467e717a9fd093488094453cecc394e586;hb=f98600c0d29ccd437be60a46070976728b38744c;hp=96290e8de777afef6137f0e4d45433d5823e6e67;hpb=cf13fe6161a69db6cbf17637b60c978fd746078a;p=wimlib diff --git a/src/blob_table.c b/src/blob_table.c index 96290e8d..ab8d0846 100644 --- a/src/blob_table.c +++ b/src/blob_table.c @@ -9,7 +9,7 @@ */ /* - * Copyright (C) 2012, 2013, 2014, 2015 Eric Biggers + * Copyright (C) 2012-2016 Eric Biggers * * 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 @@ -44,6 +44,7 @@ #include "wimlib/resource.h" #include "wimlib/unaligned.h" #include "wimlib/util.h" +#include "wimlib/win32.h" #include "wimlib/write.h" /* A hash table mapping SHA-1 message digests to blob descriptors */ @@ -53,21 +54,13 @@ struct blob_table { size_t mask; /* capacity - 1; capacity is a power of 2 */ }; -static size_t -next_power_of_2(size_t n) -{ - if (n <= 1) - return 1; - return (size_t)1 << (1 + flsw(n - 1)); -} - struct blob_table * new_blob_table(size_t capacity) { struct blob_table *table; struct hlist_head *array; - capacity = next_power_of_2(capacity); + capacity = roundup_pow_of_2(capacity); table = MALLOC(sizeof(struct blob_table)); if (table == NULL) @@ -129,10 +122,6 @@ clone_blob_descriptor(const struct blob_descriptor *old) break; case BLOB_IN_FILE_ON_DISK: -#ifdef __WIN32__ - case BLOB_IN_WINNT_FILE_ON_DISK: - case BLOB_WIN32_ENCRYPTED: -#endif #ifdef WITH_FUSE case BLOB_IN_STAGING_FILE: STATIC_ASSERT((void*)&old->file_on_disk == @@ -142,6 +131,11 @@ clone_blob_descriptor(const struct blob_descriptor *old) if (new->file_on_disk == NULL) goto out_free; break; +#ifdef __WIN32__ + case BLOB_IN_WINDOWS_FILE: + new->windows_file = clone_windows_file(old->windows_file); + break; +#endif case BLOB_IN_ATTACHED_BUFFER: new->attached_buffer = memdup(old->attached_buffer, old->size); if (new->attached_buffer == NULL) @@ -162,20 +156,23 @@ out_free: return NULL; } -static void +/* Release a blob descriptor from its location, if any, and set its new location + * to BLOB_NONEXISTENT. */ +void blob_release_location(struct blob_descriptor *blob) { switch (blob->blob_location) { - case BLOB_IN_WIM: + case BLOB_IN_WIM: { + struct wim_resource_descriptor *rdesc = blob->rdesc; + list_del(&blob->rdesc_node); - if (list_empty(&blob->rdesc->blob_list)) - FREE(blob->rdesc); + if (list_empty(&rdesc->blob_list)) { + wim_decrement_refcnt(rdesc->wim); + FREE(rdesc); + } break; + } case BLOB_IN_FILE_ON_DISK: -#ifdef __WIN32__ - case BLOB_IN_WINNT_FILE_ON_DISK: - case BLOB_WIN32_ENCRYPTED: -#endif #ifdef WITH_FUSE case BLOB_IN_STAGING_FILE: STATIC_ASSERT((void*)&blob->file_on_disk == @@ -186,13 +183,18 @@ blob_release_location(struct blob_descriptor *blob) (void*)&blob->attached_buffer); FREE(blob->file_on_disk); break; +#ifdef __WIN32__ + case BLOB_IN_WINDOWS_FILE: + free_windows_file(blob->windows_file); + break; +#endif #ifdef WITH_NTFS_3G case BLOB_IN_NTFS_VOLUME: - if (blob->ntfs_loc) - free_ntfs_location(blob->ntfs_loc); + free_ntfs_location(blob->ntfs_loc); break; #endif } + blob->blob_location = BLOB_NONEXISTENT; } void @@ -455,18 +457,14 @@ cmp_blobs_by_sequential_order(const void *p1, const void *p2) case BLOB_IN_FILE_ON_DISK: #ifdef WITH_FUSE case BLOB_IN_STAGING_FILE: -#endif -#ifdef __WIN32__ - case BLOB_IN_WINNT_FILE_ON_DISK: - case BLOB_WIN32_ENCRYPTED: - /* Windows: compare by starting LCN (logical cluster number) */ - v = cmp_u64(blob1->sort_key, blob2->sort_key); - if (v) - return v; #endif /* Compare files by path: just a heuristic that will place files * in the same directory next to each other. */ return tstrcmp(blob1->file_on_disk, blob2->file_on_disk); +#ifdef __WIN32__ + case BLOB_IN_WINDOWS_FILE: + return cmp_windows_files(blob1->windows_file, blob2->windows_file); +#endif #ifdef WITH_NTFS_3G case BLOB_IN_NTFS_VOLUME: return cmp_ntfs_locations(blob1->ntfs_loc, blob2->ntfs_loc); @@ -707,6 +705,8 @@ load_solid_info(WIMStruct *wim, if (ret) goto out_free_rdescs; + wim->refcnt += num_rdescs; + *rdescs_ret = rdescs; *num_rdescs_ret = num_rdescs; return 0; @@ -747,9 +747,12 @@ static void free_solid_rdescs(struct wim_resource_descriptor **rdescs, size_t num_rdescs) { if (rdescs) { - for (size_t i = 0; i < num_rdescs; i++) - if (list_empty(&rdescs[i]->blob_list)) + for (size_t i = 0; i < num_rdescs; i++) { + if (list_empty(&rdescs[i]->blob_list)) { + rdescs[i]->wim->refcnt--; FREE(rdescs[i]); + } + } FREE(rdescs); } } @@ -981,6 +984,7 @@ read_blob_table(WIMStruct *wim) goto oom; wim_reshdr_to_desc_and_blob(&reshdr, wim, rdesc, cur_blob); + wim->refcnt++; } /* cur_blob is now a blob bound to a resource. */ @@ -1003,9 +1007,6 @@ read_blob_table(WIMStruct *wim) } if (reshdr.flags & WIM_RESHDR_FLAG_METADATA) { - - cur_blob->is_metadata = 1; - /* Blob table entry for a metadata resource. */ /* Metadata entries with no references must be ignored. @@ -1052,7 +1053,10 @@ read_blob_table(WIMStruct *wim) * this overrides the actual locations of the metadata * resources themselves in the WIM file as well as any * information written in the XML data. */ - wim->image_metadata[image_index++]->metadata_blob = cur_blob; + wim->image_metadata[image_index] = new_unloaded_image_metadata(cur_blob); + if (!wim->image_metadata[image_index]) + goto oom; + image_index++; } else { /* Blob table entry for a non-metadata blob. */ @@ -1087,8 +1091,6 @@ read_blob_table(WIMStruct *wim) if (wim->hdr.part_number == 1 && image_index != wim->hdr.image_count) { WARNING("Could not find metadata resources for all images"); - for (u32 i = image_index; i < wim->hdr.image_count; i++) - put_image_metadata(wim->image_metadata[i], NULL); wim->hdr.image_count = image_index; }