/* The blob's data does not exist. This is a temporary state only. */
BLOB_NONEXISTENT = 0,
- /* The blob's data is located in a WIM resource identified by the
+ /* The blob's data is available in the WIM resource identified by the
* `struct wim_resource_descriptor' pointed to by @rdesc.
* @offset_in_res identifies the offset at which this particular blob
* begins in the uncompressed data of the resource. */
#ifdef WITH_NTFS_3G
/* The blob's data is available as the contents of an NTFS attribute
- * accessible through libntfs-3g. The attribute is identified by
- * volume, path to an inode, attribute name, and attribute type.
- * @ntfs_loc points to a structure containing this information. */
+ * accessible through libntfs-3g. @ntfs_loc points to a structure which
+ * identifies the attribute. */
BLOB_IN_NTFS_VOLUME,
#endif
#ifdef __WIN32__
- /* Windows only: the blob's data is available as the contents of the
- * data stream named by @file_on_disk. @file_on_disk is an NT namespace
- * path that may be longer than the Win32-level MAX_PATH. Furthermore,
- * the stream may require "backup semantics" to access. */
- BLOB_IN_WINNT_FILE_ON_DISK,
-
- /* Windows only: the blob's data is available as the raw encrypted data
- * of the external file named by @file_on_disk. @file_on_disk is a
- * Win32 namespace path. */
- BLOB_WIN32_ENCRYPTED,
+ /* Windows only: the blob's data is available in the file (or named data
+ * stream) specified by @windows_file. The data might be only properly
+ * accessible through the Windows API. */
+ BLOB_IN_WINDOWS_FILE,
#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.
/* List node for a hash bucket of the blob table */
struct hlist_node hash_list;
- /* Uncompressed size of this blob */
+ /*
+ * Uncompressed size of this blob.
+ *
+ * In most cases we are now enforcing that this is nonzero; i.e. an
+ * empty stream will have "no blob" rather than "an empty blob". The
+ * exceptions are:
+ *
+ * - blob descriptors with 'blob_location == BLOB_NONEXISTENT',
+ * e.g. placeholder entries for new metadata resources or for
+ * blobs required for pipable WIM extraction. In these cases the
+ * size is not meaningful information anyway.
+ * - blob descriptors with 'blob_location == BLOB_IN_STAGING_FILE'
+ * can vary their size over time, including to 0.
+ */
u64 size;
- /* One of the `enum blob_location' values documented above. */
- u32 blob_location : 4;
-
- /* Blob flags (WIM_RESHDR_FLAG_*) */
- u32 flags : 8;
-
- /* 1 iff the SHA-1 message digest of this blob is unknown. */
- u32 unhashed : 1;
-
- /* Temporary fields used when writing blobs; set as documented for
- * prepare_blob_list_for_write(). */
- u32 unique_size : 1;
- u32 will_be_in_output_wim : 1;
-
- /* Set to 1 if this blob represents a metadata resource that has been
- * changed. In such cases, the hash cannot be used to verify the data
- * if the metadata resource is read again. (This could be avoided if we
- * used separate fields for input/output checksum, but most blobs
- * wouldn't need this.) */
- u32 dont_check_metadata_hash : 1;
-
- u32 may_send_done_with_file : 1;
-
- /* Only used by wimlib_export_image() */
- u32 was_exported : 1;
-
union {
/*
* For unhashed == 0: 'hash' is the SHA-1 message digest of the
#ifdef WITH_FUSE
/* Number of open file descriptors to this blob during a FUSE mount of
- * the containing image. */
+ * a WIM image. */
u16 num_opened_fds;
#endif
+ /* One of the `enum blob_location' values documented above. */
+ u16 blob_location : 4;
+
+ /* 1 iff this blob contains "metadata" as opposed to data. */
+ u16 is_metadata : 1;
+
+ /* 1 iff the SHA-1 message digest of this blob is unknown. */
+ u16 unhashed : 1;
+
+ /* 1 iff this blob has failed its checksum. */
+ u16 corrupted : 1;
+
+ /* Temporary fields used when writing blobs; set as documented for
+ * prepare_blob_list_for_write(). */
+ u16 unique_size : 1;
+ u16 will_be_in_output_wim : 1;
+
+ u16 may_send_done_with_file : 1;
+
+ /* Only used by wimlib_export_image() */
+ u16 was_exported : 1;
+
/* Specification of where this blob's data is located. Which member of
* this union is valid is determined by the @blob_location field. */
union {
struct {
struct wim_resource_descriptor *rdesc;
u64 offset_in_res;
+
+ /* Links together blobs that share the same underlying
+ * WIM resource. The head is rdesc->blob_list. */
+ struct list_head rdesc_node;
};
- /* BLOB_IN_FILE_ON_DISK
- * BLOB_IN_WINNT_FILE_ON_DISK
- * BLOB_WIN32_ENCRYPTED */
struct {
- tchar *file_on_disk;
- struct wim_inode *file_inode;
- };
- /* BLOB_IN_ATTACHED_BUFFER */
- void *attached_buffer;
+ union {
-#ifdef WITH_FUSE
- /* BLOB_IN_STAGING_FILE */
- struct {
- char *staging_file_name;
- int staging_dir_fd;
- };
-#endif
+ /* BLOB_IN_FILE_ON_DISK
+ * BLOB_IN_WINDOWS_FILE */
+ struct {
+ union {
+ tchar *file_on_disk;
+ struct windows_file *windows_file;
+ };
+ struct wim_inode *file_inode;
+ };
-#ifdef WITH_NTFS_3G
- /* BLOB_IN_NTFS_VOLUME */
- struct ntfs_location *ntfs_loc;
-#endif
- };
+ /* BLOB_IN_ATTACHED_BUFFER */
+ void *attached_buffer;
- /* Links together blobs that share the same underlying WIM resource.
- * The head is the 'blob_list' member of
- * 'struct wim_resource_descriptor'. */
- struct list_head rdesc_node;
+ #ifdef WITH_FUSE
+ /* BLOB_IN_STAGING_FILE */
+ struct {
+ char *staging_file_name;
+ int staging_dir_fd;
+ };
+ #endif
+
+ #ifdef WITH_NTFS_3G
+ /* BLOB_IN_NTFS_VOLUME */
+ struct ntfs_location *ntfs_loc;
+ #endif
+ };
+
+ /* List link for per-WIM-image list of unhashed blobs */
+ struct list_head unhashed_list;
+ };
+ };
/* Temporary fields */
union {
/* Links blobs being exported. */
struct list_head export_blob_list;
-
- /* Links original list of blobs in the read-write mounted image. */
- struct list_head orig_blob_list;
};
-
- /* Links blobs that are still unhashed after being been added to a WIM.
- */
- struct list_head unhashed_list;
};
extern struct blob_table *
new_blob_descriptor(void) _malloc_attribute;
extern struct blob_descriptor *
-clone_blob_descriptor(const struct blob_descriptor *blob)
- _malloc_attribute;
+clone_blob_descriptor(const struct blob_descriptor *blob) _malloc_attribute;
extern void
-blob_decrement_refcnt(struct blob_descriptor *blob,
- struct blob_table *table);
+blob_decrement_refcnt(struct blob_descriptor *blob, struct blob_table *table);
+
+extern void
+blob_subtract_refcnt(struct blob_descriptor *blob, struct blob_table *table,
+ u32 count);
+
#ifdef WITH_FUSE
extern void
blob_decrement_num_opened_fds(struct blob_descriptor *blob);
#endif
+extern void
+blob_release_location(struct blob_descriptor *blob);
+
extern void
free_blob_descriptor(struct blob_descriptor *blob);
struct wimlib_resource_entry *wentry);
extern int
-sort_blob_list(struct list_head *blob_list,
- size_t list_head_offset,
+sort_blob_list(struct list_head *blob_list, size_t list_head_offset,
int (*compar)(const void *, const void*));
extern int
extern int
cmp_blobs_by_sequential_order(const void *p1, const void *p2);
-static inline bool
-blob_is_in_solid_wim_resource(const struct blob_descriptor *blob)
-{
- return blob->blob_location == BLOB_IN_WIM &&
- blob->size != blob->rdesc->uncompressed_size;
-}
-
-static inline bool
-blob_is_in_file(const struct blob_descriptor *blob)
-{
- return blob->blob_location == BLOB_IN_FILE_ON_DISK
-#ifdef __WIN32__
- || blob->blob_location == BLOB_IN_WINNT_FILE_ON_DISK
- || blob->blob_location == BLOB_WIN32_ENCRYPTED
-#endif
- ;
-}
-
static inline const struct blob_extraction_target *
-blob_extraction_targets(struct blob_descriptor *blob)
+blob_extraction_targets(const struct blob_descriptor *blob)
{
if (blob->out_refcnt <= ARRAY_LEN(blob->inline_blob_extraction_targets))
return blob->inline_blob_extraction_targets;
return blob->blob_extraction_targets;
}
+/*
+ * Declare that the specified blob is located in the specified WIM resource at
+ * the specified offset. The caller is expected to set blob->size if required.
+ */
static inline void
blob_set_is_located_in_wim_resource(struct blob_descriptor *blob,
- struct wim_resource_descriptor *rdesc)
+ struct wim_resource_descriptor *rdesc,
+ u64 offset_in_res)
{
blob->blob_location = BLOB_IN_WIM;
blob->rdesc = rdesc;
list_add_tail(&blob->rdesc_node, &rdesc->blob_list);
+ blob->offset_in_res = offset_in_res;
}
static inline void
blob->blob_location = BLOB_NONEXISTENT;
}
+static inline void
+blob_set_is_located_in_attached_buffer(struct blob_descriptor *blob,
+ void *buffer, size_t size)
+{
+ blob->blob_location = BLOB_IN_ATTACHED_BUFFER;
+ blob->attached_buffer = buffer;
+ blob->size = size;
+}
+
+static inline bool
+blob_is_in_file(const struct blob_descriptor *blob)
+{
+ return blob->blob_location == BLOB_IN_FILE_ON_DISK
+#ifdef __WIN32__
+ || blob->blob_location == BLOB_IN_WINDOWS_FILE
+#endif
+ ;
+}
+
+#ifdef __WIN32__
+extern const wchar_t *
+get_windows_file_path(const struct windows_file *file);
+#endif
+
+static inline const tchar *
+blob_file_path(const struct blob_descriptor *blob)
+{
+#ifdef __WIN32__
+ if (blob->blob_location == BLOB_IN_WINDOWS_FILE)
+ return get_windows_file_path(blob->windows_file);
+#endif
+ return blob->file_on_disk;
+}
+
extern struct blob_descriptor *
new_blob_from_data_buffer(const void *buffer, size_t size,
struct blob_table *blob_table);
+extern struct blob_descriptor *
+after_blob_hashed(struct blob_descriptor *blob,
+ struct blob_descriptor **back_ptr,
+ struct blob_table *blob_table, struct wim_inode *inode);
+
extern int
-hash_unhashed_blob(struct blob_descriptor *blob,
- struct blob_table *blob_table,
+hash_unhashed_blob(struct blob_descriptor *blob, struct blob_table *blob_table,
struct blob_descriptor **blob_ret);
extern struct blob_descriptor **