1 #ifndef _WIMLIB_DENTRY_H
2 #define _WIMLIB_DENTRY_H
7 /* Size of the struct dentry up to and including the file_name_len. */
8 #define WIM_DENTRY_DISK_SIZE 102
10 /* In-memory structure for a directory entry. There is a directory tree for
11 * each image in the WIM. */
13 /* The parent of this directory entry. */
14 struct dentry *parent;
16 /* Linked list of sibling directory entries. */
21 /* Pointer to a child of this directory entry. */
22 struct dentry *children;
24 /* Size of directory entry, in bytes. Typical size is around 104 to 120
26 /* It is possible for the length field to be 0. This situation, which
27 * is undocumented, indicates the end of a list of sibling nodes in a
28 * directory. It also means the real length is 8, because the dentry
29 * included only the length field, but that takes up 8 bytes. */
33 /* The file attributes associated with this file. */
36 /* The index of the node in the security table that contains this file's
37 * security information. If -1, no security information exists for this
38 * file. Currently ignoring this field.*/
39 //int32_t security_id;
41 /* The offset, from the start of the metadata section, of this directory
42 * entry's child files. 0 if the directory entry has no children. */
45 /* Reserved for future disuse. Currently ignoring these fields. */
49 /* Timestamps for the entry. The timestamps are the number of
50 * 100-nanosecond intervals that have elapsed since 12:00 A.M., January
56 /* A hash of the file's contents. */
57 u8 hash[WIM_HASH_SIZE];
59 /* Identity of a reparse point (whatever that is). Currently ignoring
63 /* Although M$'s documentation does not tell you this, it seems that the
64 * reparse_reserved field does not actually exist. So the hard_link
65 * field directly follows the reparse_tag on disk. */
66 //u32 reparse_reserved;
68 /* If the reparse_reserved field existed, there would be a 4-byte gap
69 * here to align hard_link on an 8-byte field. However,
70 * reparse_reserved does not actually exist, so there is no gap here. */
72 /* If the file is part of a hard link set, all the directory entries in
73 * the set will share the same value for this field. */
76 /* Number of WIMStreamEntry structures that follow this struct dentry.
77 * Currently ignoring this field. */
80 /* Length of short filename, in bytes, not including the terminating
81 * zero wide-character. */
84 /* Length of file name, in bytes, not including the terminating zero
88 /* Length of the filename converted into UTF-8, in bytes, not including
89 * the terminating zero byte. */
90 u16 file_name_utf8_len;
92 /* Pointer to the short filename */
95 /* Pointer to the filename. */
98 /* Pointer to the filename converted to UTF-8. */
101 /* Full path to this dentry. */
102 char *full_path_utf8;
103 u32 full_path_utf8_len;
105 /* Stream entries for this dentry. Currently being ignored. */
106 //struct WIMStreamEntry *stream_entries;
108 /* Number of references to the dentry tree itself, as in multiple
113 #define WIM_FILE_ATTRIBUTE_READONLY 0x1
114 #define WIM_FILE_ATTRIBUTE_HIDDEN 0x2
115 #define WIM_FILE_ATTRIBUTE_SYSTEM 0x4
116 #define WIM_FILE_ATTRIBUTE_DIRECTORY 0x10
117 #define WIM_FILE_ATTRIBUTE_ARCHIVE 0x20
118 #define WIM_FILE_ATTRIBUTE_DEVICE 0x40
119 #define WIM_FILE_ATTRIBUTE_NORMAL 0x80
120 #define WIM_FILE_ATTRIBUTE_TEMPORARY 0x100
121 #define WIM_FILE_ATTRIBUTE_SPARSE_FILE 0x200
122 #define WIM_FILE_ATTRIBUTE_REPARSE_POINT 0x400
123 #define WIM_FILE_ATTRIBUTE_COMPRESSED 0x800
124 #define WIM_FILE_ATTRIBUTE_OFFLINE 0x1000
125 #define WIM_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x2000
126 #define WIM_FILE_ATTRIBUTE_ENCRYPTED 0x4000
127 #define WIM_FILE_ATTRIBUTE_VIRTUAL 0x10000
129 extern void stbuf_to_dentry(const struct stat *stbuf, struct dentry *dentry);
131 extern void dentry_to_stbuf(const struct dentry *dentry, struct stat *stbuf,
132 const struct lookup_table *table);
134 extern int for_dentry_in_tree(struct dentry *root,
135 int (*visitor)(struct dentry*, void*),
138 extern int for_dentry_in_tree_depth(struct dentry *root,
139 int (*visitor)(struct dentry*, void*),
142 extern int calculate_dentry_full_path(struct dentry *dentry, void *ignore);
143 extern void calculate_subdir_offsets(struct dentry *dentry, u64 *subdir_offset_p);
144 extern int change_dentry_name(struct dentry *dentry, const char *new_name);
146 extern void unlink_dentry(struct dentry *dentry);
147 extern void link_dentry(struct dentry *dentry, struct dentry *parent);
149 extern int print_dentry(struct dentry *dentry, void *lookup_table);
150 extern int print_dentry_full_path(struct dentry *entry, void *ignore);
152 extern struct dentry *get_dentry(WIMStruct *w, const char *path);
153 extern struct dentry *get_parent_dentry(WIMStruct *w, const char *path);
154 extern struct dentry *get_dentry_child_with_name(const struct dentry *dentry,
156 extern void dentry_update_all_timestamps(struct dentry *dentry);
157 extern void init_dentry(struct dentry *dentry, const char *name);
158 extern struct dentry *new_dentry(const char *name);
160 extern void free_dentry(struct dentry *dentry);
161 extern void free_dentry_tree(struct dentry *root, struct lookup_table *lookup_table,
162 bool decrement_refcnt);
163 extern int increment_dentry_refcnt(struct dentry *dentry, void *ignore);
165 extern void calculate_dir_tree_statistics(struct dentry *root,
166 struct lookup_table *table,
169 u64 *total_bytes_ret,
170 u64 *hard_link_bytes_ret);
172 extern int read_dentry(const u8 metadata_resource[], u64 metadata_resource_len,
173 u64 offset, struct dentry *dentry);
175 extern int read_dentry_tree(const u8 metadata_resource[],
176 u64 metadata_resource_len, struct dentry *dentry);
178 extern u8 *write_dentry_tree(const struct dentry *tree, u8 *p);
180 /* Inline utility functions for WIMDentries */
183 * Returns true if @dentry has the UTF-8 file name @name that has length
186 static inline bool dentry_has_name(const struct dentry *dentry, const char *name,
189 if (dentry->file_name_utf8_len != name_len)
191 return memcmp(dentry->file_name_utf8, name, name_len) == 0;
194 static inline bool dentry_is_root(const struct dentry *dentry)
196 return dentry->parent == dentry;
199 static inline bool dentry_is_first_sibling(const struct dentry *dentry)
201 return dentry_is_root(dentry) || dentry->parent->children == dentry;
204 static inline bool dentry_is_only_child(const struct dentry *dentry)
206 return dentry->next == dentry;
209 static inline bool dentry_is_directory(const struct dentry *dentry)
211 return (dentry->attributes & WIM_FILE_ATTRIBUTE_DIRECTORY) != 0;
214 static inline bool dentry_is_regular_file(const struct dentry *dentry)
216 return !dentry_is_directory(dentry);
219 static inline bool dentry_is_empty_directory(const struct dentry *dentry)
221 return dentry_is_directory(dentry) && dentry->children == NULL;