+/** Information about a unique stream in the WIM file. (A stream is the same
+ * thing as a "resource", except in the case of packed resources.) */
+struct wimlib_resource_entry {
+ /** Uncompressed size of the stream in bytes. */
+ uint64_t uncompressed_size;
+
+ /** Compressed size of the stream in bytes. This will be the same as @p
+ * uncompressed_size if the stream is uncompressed. Or, if @p packed is
+ * 1, this will be 0. */
+ uint64_t compressed_size;
+
+ /** Offset, in bytes, of this stream from the start of the WIM file. Or
+ * if @p packed is 1, then this is actually the offset at which this
+ * stream begins in the uncompressed contents of the packed resource.
+ */
+ uint64_t offset;
+
+ /** SHA1 message digest of the stream's uncompressed contents. */
+ uint8_t sha1_hash[20];
+
+ /** Which part of WIM this stream is in. */
+ uint32_t part_number;
+
+ /** Number of times this stream is referenced over all WIM images. */
+ uint32_t reference_count;
+
+ /** 1 if this stream is compressed. */
+ uint32_t is_compressed : 1;
+
+ /** 1 if this stream is a metadata resource rather than a file resource.
+ * */
+ uint32_t is_metadata : 1;
+
+ uint32_t is_free : 1;
+ uint32_t is_spanned : 1;
+
+ /** 1 if this stream was not found in the lookup table of the
+ * ::WIMStruct. This normally implies a missing call to
+ * wimlib_reference_resource_files() or wimlib_reference_resources().
+ * */
+ uint32_t is_missing : 1;
+
+ /** 1 if this stream is located in a packed resource which may contain
+ * other streams (all compressed together) as well. */
+ uint32_t packed : 1;
+
+ uint32_t reserved_flags : 26;
+
+ /** If @p packed is 1, then this will specify the offset of the packed
+ * resource in the WIM. */
+ uint64_t raw_resource_offset_in_wim;
+
+ /** If @p packed is 1, then this will specify the compressed size of the
+ * packed resource in the WIM. */
+ uint64_t raw_resource_compressed_size;
+
+ uint64_t reserved[2];
+};
+
+/**
+ * Information about a stream of a particular file in the WIM.
+ *
+ * Normally, only WIM images captured from NTFS filesystems will have multiple
+ * streams per file. In practice, this is a rarely used feature of the
+ * filesystem.
+ */
+struct wimlib_stream_entry {
+ /** Name of the stream, or NULL if the stream is unnamed. */
+ const wimlib_tchar *stream_name;
+ /** Location, size, and other information about the stream's data as
+ * stored in the WIM file. */
+ struct wimlib_resource_entry resource;
+ uint64_t reserved[4];
+};
+
+/** Structure passed to the wimlib_iterate_dir_tree() callback function.
+ * Roughly, the information about a "file" in the WIM--- but really a directory
+ * entry ("dentry") because hard links are allowed. The hard_link_group_id
+ * field can be used to distinguish actual file inodes. */
+struct wimlib_dir_entry {
+ /** Name of the file, or NULL if this file is unnamed. Only the root
+ * directory of an image will be unnamed. */
+ const wimlib_tchar *filename;
+
+ /** 8.3 name (or "DOS name", or "short name") of this file; or NULL if
+ * this file has no such name. */
+ const wimlib_tchar *dos_name;
+
+ /** Full path to this file within the WIM image. Path separators will
+ * be ::WIMLIB_WIM_PATH_SEPARATOR. */
+ const wimlib_tchar *full_path;
+
+ /** Depth of this directory entry, where 0 is the root, 1 is the root's
+ * children, ..., etc. */
+ size_t depth;
+
+ /** Pointer to the security descriptor for this file, in Windows
+ * SECURITY_DESCRIPTOR_RELATIVE format, or NULL if this file has no
+ * security descriptor. */
+ const char *security_descriptor;
+
+ /** Length of the above security descriptor. */
+ size_t security_descriptor_size;
+
+#define WIMLIB_FILE_ATTRIBUTE_READONLY 0x00000001
+#define WIMLIB_FILE_ATTRIBUTE_HIDDEN 0x00000002
+#define WIMLIB_FILE_ATTRIBUTE_SYSTEM 0x00000004
+#define WIMLIB_FILE_ATTRIBUTE_DIRECTORY 0x00000010
+#define WIMLIB_FILE_ATTRIBUTE_ARCHIVE 0x00000020
+#define WIMLIB_FILE_ATTRIBUTE_DEVICE 0x00000040
+#define WIMLIB_FILE_ATTRIBUTE_NORMAL 0x00000080
+#define WIMLIB_FILE_ATTRIBUTE_TEMPORARY 0x00000100
+#define WIMLIB_FILE_ATTRIBUTE_SPARSE_FILE 0x00000200
+#define WIMLIB_FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
+#define WIMLIB_FILE_ATTRIBUTE_COMPRESSED 0x00000800
+#define WIMLIB_FILE_ATTRIBUTE_OFFLINE 0x00001000
+#define WIMLIB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000
+#define WIMLIB_FILE_ATTRIBUTE_ENCRYPTED 0x00004000
+#define WIMLIB_FILE_ATTRIBUTE_VIRTUAL 0x00010000
+ /** File attributes, such as whether the file is a directory or not.
+ * These are the "standard" Windows FILE_ATTRIBUTE_* values, although in
+ * wimlib.h they are defined as WIMLIB_FILE_ATTRIBUTE_* for convenience
+ * on other platforms. */
+ uint32_t attributes;
+
+#define WIMLIB_REPARSE_TAG_RESERVED_ZERO 0x00000000
+#define WIMLIB_REPARSE_TAG_RESERVED_ONE 0x00000001
+#define WIMLIB_REPARSE_TAG_MOUNT_POINT 0xA0000003
+#define WIMLIB_REPARSE_TAG_HSM 0xC0000004
+#define WIMLIB_REPARSE_TAG_HSM2 0x80000006
+#define WIMLIB_REPARSE_TAG_DRIVER_EXTENDER 0x80000005
+#define WIMLIB_REPARSE_TAG_SIS 0x80000007
+#define WIMLIB_REPARSE_TAG_DFS 0x8000000A
+#define WIMLIB_REPARSE_TAG_DFSR 0x80000012
+#define WIMLIB_REPARSE_TAG_FILTER_MANAGER 0x8000000B
+#define WIMLIB_REPARSE_TAG_WOF 0x80000017
+#define WIMLIB_REPARSE_TAG_SYMLINK 0xA000000C
+ /** If the file is a reparse point (FILE_ATTRIBUTE_REPARSE_POINT set in
+ * the attributes), this will give the reparse tag. This tells you
+ * whether the reparse point is a symbolic link, junction point, or some
+ * other, more unusual kind of reparse point. */
+ uint32_t reparse_tag;
+
+ /** Number of links to this file's inode (hard links).
+ *
+ * Currently, this will always be 1 for directories. However, it can be
+ * greater than 1 for nondirectory files. */
+ uint32_t num_links;
+
+ /** Number of named data streams this file has. Normally 0. */
+ uint32_t num_named_streams;
+
+ /** A unique identifier for this file's inode. However, as a special
+ * case, if the inode only has a single link (@p num_links == 1), this
+ * value may be 0.
+ *
+ * Note: if a WIM image is captured from a filesystem, this value is not
+ * guaranteed to be the same as the original number of the inode on the
+ * filesystem. */
+ uint64_t hard_link_group_id;
+
+ /** Time this file was created. */
+ struct timespec creation_time;
+
+ /** Time this file was last written to. */
+ struct timespec last_write_time;
+
+ /** Time this file was last accessed. */
+ struct timespec last_access_time;
+
+ /** The UNIX user ID of this file. This is a wimlib extension.
+ *
+ * This field is only valid if @p unix_mode != 0. */
+ uint32_t unix_uid;
+
+ /** The UNIX group ID of this file. This is a wimlib extension.
+ *
+ * This field is only valid if @p unix_mode != 0. */
+ uint32_t unix_gid;
+
+ /** The UNIX mode of this file. This is a wimlib extension.
+ *
+ * If this field is 0, then @p unix_uid, @p unix_gid, @p unix_mode, and
+ * @p unix_rdev are all unknown (fields are not present in the WIM
+ * image). */
+ uint32_t unix_mode;
+
+ /** The UNIX device ID (major and minor number) of this file. This is a
+ * wimlib extension.
+ *
+ * This field is only valid if @p unix_mode != 0. */
+ uint32_t unix_rdev;
+
+ uint64_t reserved[14];
+
+ /**
+ * Array of streams that make up this file.
+ *
+ * The first entry will always exist and will correspond to the unnamed
+ * data stream (default file contents), so it will have <c>stream_name
+ * == NULL</c>. Alternatively, for reparse point files, the first entry
+ * will corresponding to the reparse data stream.
+ *
+ * Then, following the first entry, there be @p num_named_streams
+ * additional entries that specify the named data streams, if any, each
+ * of which will have <c>stream_name != NULL</c>.
+ */
+ struct wimlib_stream_entry streams[];
+};
+
+/**
+ * Type of a callback function to wimlib_iterate_dir_tree(). Must return 0 on
+ * success.
+ */
+typedef int (*wimlib_iterate_dir_tree_callback_t)(const struct wimlib_dir_entry *dentry,
+ void *user_ctx);
+
+/**
+ * Type of a callback function to wimlib_iterate_lookup_table(). Must return 0
+ * on success.
+ */
+typedef int (*wimlib_iterate_lookup_table_callback_t)(const struct wimlib_resource_entry *resource,
+ void *user_ctx);
+
+/** For wimlib_iterate_dir_tree(): Iterate recursively on children rather than
+ * just on the specified path. */
+#define WIMLIB_ITERATE_DIR_TREE_FLAG_RECURSIVE 0x00000001