X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=include%2Fwimlib%2Finode.h;h=ed6f9de92ee1ea088e1052c3b5f6c78a0b0681dd;hp=28285b2baca4af5da2d7cae5f691c6127732996a;hb=f9894b7e0e2a2a46fffdf7274d8671fb00f98089;hpb=3de1ec66f778edda19865482d685bc6f4e17faf7 diff --git a/include/wimlib/inode.h b/include/wimlib/inode.h index 28285b2b..ed6f9de9 100644 --- a/include/wimlib/inode.h +++ b/include/wimlib/inode.h @@ -10,6 +10,7 @@ struct avl_tree_node; struct blob_descriptor; struct blob_table; struct wim_dentry; +struct wim_inode_extra; struct wim_security_data; struct wimfs_fd; @@ -70,7 +71,7 @@ struct wim_inode_stream { union { u8 _stream_hash[SHA1_HASH_SIZE]; struct blob_descriptor *_stream_blob; - }; + } _packed_attribute; /* union is SHA1_HASH_SIZE bytes */ /* 'stream_resolved' determines whether 'stream_hash' or 'stream_blob' * is valid as described above. */ @@ -106,55 +107,41 @@ struct wim_inode { u32 i_attributes; /* Root of a balanced binary search tree storing the child directory - * entries of this inode, if any. Keyed by wim_dentry->file_name, case + * entries of this inode, if any. Keyed by wim_dentry->d_name, case * sensitively. If this inode is not a directory or if it has no * children then this will be an empty tree (NULL). */ struct avl_tree_node *i_children; /* Root of a balanced binary search tree storing the child directory - * entries of this inode, if any. Keyed by wim_dentry->file_name, case + * entries of this inode, if any. Keyed by wim_dentry->d_name, case * insensitively. If this inode is not a directory or if it has no * children then this will be an empty tree (NULL). */ struct avl_tree_node *i_children_ci; /* List of dentries that are aliases for this inode. There will be * i_nlink dentries in this list. */ - struct list_head i_dentry; + struct hlist_head i_alias_list; - /* Field to place this inode into a list. */ - union { - /* Hash list node- used in inode_fixup.c when the inodes are - * placed into a hash table keyed by inode number and optionally - * device number, in order to detect dentries that are aliases - * for the same inode. */ - struct hlist_node i_hlist; - - /* Normal list node- used to connect all the inodes of a WIM - * image into a single linked list referenced from the `struct - * wim_image_metadata' for that image. */ - struct list_head i_list; - }; + /* Field to place this inode into a list. While reading a WIM image or + * adding files to a WIM image this is owned by the inode table; + * otherwise this links the inodes for the WIM image. */ + struct hlist_node i_hlist_node; /* Number of dentries that are aliases for this inode. */ - u32 i_nlink; + u32 i_nlink : 30; - /* Flag used to mark this inode as visited; this is used when visiting - * all the inodes in a dentry tree exactly once. It will be 0 by - * default and must be cleared following the tree traversal, even in - * error paths. */ - u8 i_visited : 1; + /* Flag used by some code to mark this inode as visited. It will be 0 + * by default, and it always must be cleared after use. */ + u32 i_visited : 1; /* Cached value */ - u8 i_can_externally_back : 1; + u32 i_can_externally_back : 1; /* If not NULL, a pointer to the extra data that was read from the * dentry. This should be a series of tagged items, each of which * represents a bit of extra metadata, such as the file's object ID. * See tagged_items.c for more information. */ - void *i_extra; - - /* Size of @i_extra buffer in bytes. If 0, there is no extra data. */ - size_t i_extra_size; + struct wim_inode_extra *i_extra; /* Creation time, last access time, and last write time for this inode, * in 100-nanosecond intervals since 12:00 a.m UTC January 1, 1601. @@ -166,27 +153,20 @@ struct wim_inode { /* Corresponds to 'security_id' in `struct wim_dentry_on_disk': The * index of this inode's security descriptor in the WIM image's table of - * security descriptors, or -1. Note: when a WIM image is loaded, - * wimlib sets out-of-bounds indices and values less than -1 in this - * field to -1. So the extraction code need not do an upper bound check - * after checking for -1 (or equivalently < 0). */ - int32_t i_security_id; - - /* Identity of a reparse point. See - * http://msdn.microsoft.com/en-us/library/windows/desktop/aa365503(v=vs.85).aspx - * for what a reparse point is. */ - u32 i_reparse_tag; + * security descriptors, or -1 if this inode does not have a security + * descriptor. */ + s32 i_security_id; - /* Unused/unknown fields that we just read into memory so we can - * re-write them unchanged. */ - u32 i_rp_unknown_1; - u16 i_rp_unknown_2; + /* Unknown field that we only read into memory so we can re-write it + * unchanged. Probably it's actually just padding... */ + u32 i_unknown_0x54; - /* Corresponds to not_rpfixed in `struct wim_dentry_on_disk': Set to 0 - * if reparse point fixups have been done. Otherwise set to 1. Note: - * this actually may reflect the SYMBOLIC_LINK_RELATIVE flag. - */ - u16 i_not_rpfixed; + /* The following fields correspond to 'reparse_tag', 'rp_reserved', and + * 'rp_flags' in `struct wim_dentry_on_disk'. They are only meaningful + * for reparse point files. */ + u32 i_reparse_tag; + u16 i_rp_reserved; + u16 i_rp_flags; /* Inode number; corresponds to hard_link_group_id in the `struct * wim_dentry_on_disk'. */ @@ -196,19 +176,19 @@ struct wim_inode { /* Device number, used only during image capture, so we can * identify hard linked files by the combination of inode number * and device number (rather than just inode number, which could - * be ambigious if the captured tree spans a mountpoint). Set + * be ambiguous if the captured tree spans a mountpoint). Set * to 0 otherwise. */ u64 i_devno; /* Fields used only during extraction */ struct { - /* List of aliases of this dentry that are being - * extracted in the current extraction operation. This - * will be a (possibly nonproper) subset of the dentries - * in the i_dentry list. This list will be constructed + /* A singly linked list of aliases of this inode that + * are being extracted in the current extraction + * operation. This list may be shorter than the inode's + * full alias list. This list will be constructed * regardless of whether the extraction backend supports * hard links or not. */ - struct list_head i_extraction_aliases; + struct wim_dentry *i_first_extraction_alias; #ifdef WITH_NTFS_3G /* In NTFS-3g extraction mode, this is set to the Master @@ -222,7 +202,7 @@ struct wim_inode { * WIMLIB_WRITE_FLAG_SEND_DONE_WITH_FILE_MESSAGES: the number * of streams this inode has that have not yet been fully read. * */ - u32 num_remaining_streams; + u32 i_num_remaining_streams; #ifdef WITH_FUSE struct { @@ -248,22 +228,27 @@ struct wim_inode { u32 i_next_stream_id; }; +/* Optional extra data for a WIM inode */ +struct wim_inode_extra { + size_t size; /* Size of the extra data in bytes */ + u8 data[]; /* The extra data */ +}; + /* - * Reparse tags documented at - * http://msdn.microsoft.com/en-us/library/dd541667(v=prot.10).aspx + * The available reparse tags are documented at + * http://msdn.microsoft.com/en-us/library/dd541667(v=prot.10).aspx. + * Here we only define the ones of interest to us. */ -#define WIM_IO_REPARSE_TAG_RESERVED_ZERO 0x00000000 -#define WIM_IO_REPARSE_TAG_RESERVED_ONE 0x00000001 #define WIM_IO_REPARSE_TAG_MOUNT_POINT 0xA0000003 -#define WIM_IO_REPARSE_TAG_HSM 0xC0000004 -#define WIM_IO_REPARSE_TAG_HSM2 0x80000006 -#define WIM_IO_REPARSE_TAG_DRIVER_EXTENDER 0x80000005 -#define WIM_IO_REPARSE_TAG_SIS 0x80000007 -#define WIM_IO_REPARSE_TAG_DFS 0x8000000A -#define WIM_IO_REPARSE_TAG_DFSR 0x80000012 -#define WIM_IO_REPARSE_TAG_FILTER_MANAGER 0x8000000B #define WIM_IO_REPARSE_TAG_SYMLINK 0xA000000C +#define WIM_IO_REPARSE_TAG_WOF 0x80000017 + +/* Flags for the rp_flags field. Currently the only known flag is NOT_FIXED, + * which indicates that the target of the absolute symbolic link or junction was + * not changed when it was stored. */ +#define WIM_RP_FLAG_NOT_FIXED 0x0001 +/* Windows file attribute flags */ #define FILE_ATTRIBUTE_READONLY 0x00000001 #define FILE_ATTRIBUTE_HIDDEN 0x00000002 #define FILE_ATTRIBUTE_SYSTEM 0x00000004 @@ -281,23 +266,20 @@ struct wim_inode { #define FILE_ATTRIBUTE_VIRTUAL 0x00010000 extern struct wim_inode * -new_inode(void) _malloc_attribute; - -extern struct wim_inode * -new_timeless_inode(void) _malloc_attribute; +new_inode(struct wim_dentry *dentry, bool set_timestamps); /* Iterate through each alias of the specified inode. */ #define inode_for_each_dentry(dentry, inode) \ - list_for_each_entry((dentry), &(inode)->i_dentry, d_alias) + hlist_for_each_entry((dentry), &(inode)->i_alias_list, d_alias_node) /* Return an alias of the specified inode. */ -#define inode_first_dentry(inode) \ - container_of(inode->i_dentry.next, struct wim_dentry, d_alias) +#define inode_any_dentry(inode) \ + hlist_entry(inode->i_alias_list.first, struct wim_dentry, d_alias_node) /* Return the full path of an alias of the specified inode, or NULL if a full * path could not be determined. */ -#define inode_first_full_path(inode) \ - dentry_full_path(inode_first_dentry(inode)) +#define inode_any_full_path(inode) \ + dentry_full_path(inode_any_dentry(inode)) extern void d_associate(struct wim_dentry *dentry, struct wim_inode *inode); @@ -342,6 +324,13 @@ inode_has_children(const struct wim_inode *inode) return inode->i_children != NULL; } +/* Does the inode have a security descriptor? */ +static inline bool +inode_has_security_descriptor(const struct wim_inode *inode) +{ + return inode->i_security_id >= 0; +} + extern struct wim_inode_stream * inode_get_stream(const struct wim_inode *inode, int stream_type, const utf16lechar *stream_name); @@ -349,13 +338,31 @@ inode_get_stream(const struct wim_inode *inode, int stream_type, extern struct wim_inode_stream * inode_get_unnamed_stream(const struct wim_inode *inode, int stream_type); +static inline struct wim_inode_stream * +inode_get_unnamed_data_stream(const struct wim_inode *inode) +{ + return inode_get_unnamed_stream(inode, STREAM_TYPE_DATA); +} + extern struct wim_inode_stream * inode_add_stream(struct wim_inode *inode, int stream_type, const utf16lechar *stream_name, struct blob_descriptor *blob); -extern struct wim_inode_stream * -inode_add_stream_with_data(struct wim_inode *inode, int stream_type, - const utf16lechar *stream_name, +extern void +inode_replace_stream_blob(struct wim_inode *inode, + struct wim_inode_stream *strm, + struct blob_descriptor *new_blob, + struct blob_table *blob_table); + +extern bool +inode_replace_stream_data(struct wim_inode *inode, + struct wim_inode_stream *strm, + const void *data, size_t size, + struct blob_table *blob_table); + +extern bool +inode_add_stream_with_data(struct wim_inode *inode, + int stream_type, const utf16lechar *stream_name, const void *data, size_t size, struct blob_table *blob_table); @@ -370,13 +377,6 @@ stream_blob_resolved(const struct wim_inode_stream *strm) return strm->_stream_blob; } -static inline void -stream_set_blob(struct wim_inode_stream *strm, struct blob_descriptor *blob) -{ - strm->_stream_blob = blob; - strm->stream_resolved = 1; -} - static inline bool stream_is_named(const struct wim_inode_stream *strm) { @@ -399,11 +399,8 @@ extern bool inode_has_named_data_stream(const struct wim_inode *inode); extern int -inode_resolve_streams(struct wim_inode *inode, - struct blob_table *table, bool force); - -extern void -inode_unresolve_streams(struct wim_inode *inode); +inode_resolve_streams(struct wim_inode *inode, struct blob_table *table, + bool force); extern int blob_not_found_error(const struct wim_inode *inode, const u8 *hash); @@ -432,6 +429,6 @@ inode_unref_blobs(struct wim_inode *inode, struct blob_table *blob_table); /* inode_fixup.c */ extern int -dentry_tree_fix_inodes(struct wim_dentry *root, struct list_head *inode_list); +dentry_tree_fix_inodes(struct wim_dentry *root, struct hlist_head *inode_list); #endif /* _WIMLIB_INODE_H */