include/wimlib/assert.h \
include/wimlib/avl_tree.h \
include/wimlib/bitops.h \
+ include/wimlib/blob_table.h \
include/wimlib/bt_matchfinder.h \
include/wimlib/callback.h \
include/wimlib/capture.h \
include/wimlib/integrity.h \
include/wimlib/lcpit_matchfinder.h \
include/wimlib/list.h \
- include/wimlib/lookup_table.h \
include/wimlib/lz_extend.h \
include/wimlib/lz_hash.h \
include/wimlib/lzms_common.h \
#endif
};
-/* A "blob target" is a stream, and the inode to which that stream belongs, to
- * which a blob needs to be extracted as part of an extraction operation. Since
- * blobs are single-instanced, a blob may have multiple targets. */
+/* A "blob extraction target" is a stream, and the inode to which that stream
+ * belongs, to which a blob needs to be extracted as part of an extraction
+ * operation. Since blobs are single-instanced, a blob may have multiple
+ * extraction targets. */
struct blob_extraction_target {
struct wim_inode *inode;
struct wim_inode_stream *stream;
};
/*
- * Descriptor for a blob, which is a known length sequence of binary data.
+ * Descriptor for a "blob", which is a known length sequence of binary data.
*
* Within a WIM file, blobs are single instanced and are identified by SHA-1
* message digest.
* tree for each image in the WIM.
*
* Note that this is a directory entry and not an inode. Since NTFS allows hard
- * links, it's possible for an NTFS inode to correspond to multiple WIM dentries.
- * The hard link group ID field of the on-disk WIM dentry tells us the number of
- * the NTFS inode that the dentry corresponds to (and this gets placed in
- * d_inode->i_ino).
+ * links, it's possible for an NTFS inode to correspond to multiple WIM
+ * dentries. The hard link group ID field of the on-disk WIM dentry tells us
+ * the number of the NTFS inode that the dentry corresponds to (and this gets
+ * placed in d_inode->i_ino).
*
* Unfortunately, WIM files do not have an analogue to an inode; instead certain
- * information, such as file attributes, the security descriptor, and file
- * streams is replicated in each hard-linked dentry, even though this
- * information really is associated with an inode. In-memory, we fix up this
- * flaw by allocating a `struct wim_inode' for each dentry that contains some of
- * this duplicated information, then combining the inodes for each hard link
- * group together.
- *
- * Confusingly, it's possible for stream information to be missing from a dentry
- * in a hard link set, in which case the stream information needs to be gotten
- * from one of the other dentries in the hard link set. In addition, it is
- * possible for dentries to have inconsistent security IDs, file attributes, or
- * file streams when they share the same hard link ID (don't even ask. I hope
- * that Microsoft may have fixed this problem, since I've only noticed it in the
- * 'install.wim' for Windows 7). For those dentries, we have to use the
- * conflicting fields to split up the hard link groups. (See
- * dentry_tree_fix_inodes() in inode_fixup.c.)
+ * information, such as file attributes, the security descriptor, and streams is
+ * replicated in each hard-linked dentry, even though this information really is
+ * associated with an inode. In-memory, we fix up this flaw by allocating a
+ * `struct wim_inode' for each dentry that contains some of this duplicated
+ * information, then combining the inodes for each hard link group together.
+ * (See dentry_tree_fix_inodes().)
*/
struct wim_dentry {
/* Pointer to the inode for this dentry. This will contain some
* be exactly this size. */
#define WIM_HEADER_DISK_SIZE 208
-/* Default WIM version number. Streams are always compressed independently. */
+/* Default WIM version number. Blobs are always compressed independently. */
#define WIM_VERSION_DEFAULT 0x10d00
/* Version number used for WIMs that allow multiple blobs combined into one
*
* Note 2: although this is the top-level data structure in wimlib, there do
* exist cases in which a WIMStruct is not standalone:
- * - streams have been referenced from another WIMStruct
+ * - blobs have been referenced from another WIMStruct
* - an image has been imported into this WIMStruct from another
* (as this references the metadata rather than copies it)
*
/*
* Return true if and only if the WIM contains image metadata (actual directory
- * trees, not just a collection of streams and their checksums).
+ * trees, not just a collection of blobs and their checksums).
*
* See the description of the 'image_metadata' field. Note that we return true
* when the image count is 0 because it could be a WIM with 0 images. It's only
struct blob_descriptor *
new_blob_descriptor(void)
{
- struct blob_descriptor *blob;
-
- blob = CALLOC(1, sizeof(struct blob_descriptor));
- if (blob == NULL)
- return NULL;
-
- /* blob->refcnt = 0 */
- /* blob->blob_location = BLOB_NONEXISTENT */
BUILD_BUG_ON(BLOB_NONEXISTENT != 0);
-
- return blob;
+ return CALLOC(1, sizeof(struct blob_descriptor));
}
struct blob_descriptor *
struct blob_table *blob_table)
{
u8 hash[SHA1_HASH_SIZE];
- struct blob_descriptor *blob, *existing_blob;
+ struct blob_descriptor *blob;
+ void *buffer_copy;
sha1_buffer(buffer, size, hash);
- existing_blob = lookup_blob(blob_table, hash);
- if (existing_blob) {
- wimlib_assert(existing_blob->size == size);
- blob = existing_blob;
- } else {
- void *buffer_copy;
- blob = new_blob_descriptor();
- if (blob == NULL)
- return NULL;
- buffer_copy = memdup(buffer, size);
- if (buffer_copy == NULL) {
- free_blob_descriptor(blob);
- return NULL;
- }
- blob_set_is_located_in_attached_buffer(blob, buffer_copy, size);
- copy_hash(blob->hash, hash);
- blob_table_insert(blob_table, blob);
+
+ blob = lookup_blob(blob_table, hash);
+ if (blob)
+ return blob;
+
+ blob = new_blob_descriptor();
+ if (!blob)
+ return NULL;
+
+ buffer_copy = memdup(buffer, size);
+ if (!buffer_copy) {
+ free_blob_descriptor(blob);
+ return NULL;
}
+ blob_set_is_located_in_attached_buffer(blob, buffer_copy, size);
+ copy_hash(blob->hash, hash);
+ blob_table_insert(blob_table, blob);
return blob;
}
tprintf(T("Part Number = %hu\n"), hdr->part_number);
tprintf(T("Total Parts = %hu\n"), hdr->total_parts);
tprintf(T("Image Count = %u\n"), hdr->image_count);
- tprintf(T("Blob Table Size = %"PRIu64"\n"),
+ tprintf(T("Blob Table Size = %"PRIu64"\n"),
(u64)hdr->blob_table_reshdr.size_in_wim);
- tprintf(T("Blob Table Flags = 0x%hhx\n"),
+ tprintf(T("Blob Table Flags = 0x%hhx\n"),
(u8)hdr->blob_table_reshdr.flags);
- tprintf(T("Blob Table Offset = %"PRIu64"\n"),
+ tprintf(T("Blob Table Offset = %"PRIu64"\n"),
hdr->blob_table_reshdr.offset_in_wim);
- tprintf(T("Blob Table Original_size = %"PRIu64"\n"),
+ tprintf(T("Blob Table Original_size = %"PRIu64"\n"),
hdr->blob_table_reshdr.uncompressed_size);
tprintf(T("XML Data Size = %"PRIu64"\n"),
(u64)hdr->xml_data_reshdr.size_in_wim);
*
* If @force is %false:
* If any of the needed blobs do not exist in @table, return
- * WIMLIB_ERR_RESOURCE_NOT_FOUND and leave the inode unmodified.
+ * WIMLIB_ERR_RESOURCE_NOT_FOUND.
* If @force is %true:
* If any of the needed blobs do not exist in @table, allocate new blob
* descriptors for them and insert them into @table. This does not, of
inode_resolve_streams(struct wim_inode *inode, struct blob_table *table,
bool force)
{
- struct blob_descriptor *blobs[inode->i_num_streams];
-
for (unsigned i = 0; i < inode->i_num_streams; i++) {
+ struct wim_inode_stream *strm = &inode->i_streams[i];
- if (inode->i_streams[i].stream_resolved)
+ if (strm->stream_resolved)
continue;
- const u8 *hash = stream_hash(&inode->i_streams[i]);
+ const u8 *hash = stream_hash(strm);
struct blob_descriptor *blob = NULL;
if (!is_zero_hash(hash)) {
blob_table_insert(table, blob);
}
}
- blobs[i] = blob;
- }
-
- for (unsigned i = 0; i < inode->i_num_streams; i++) {
- if (!inode->i_streams[i].stream_resolved) {
- inode->i_streams[i]._stream_blob = blobs[i];
- inode->i_streams[i].stream_resolved = 1;
- }
+ strm->_stream_blob = blob;
+ strm->stream_resolved = 1;
}
return 0;
}