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
39 #ifdef ENABLE_SECURITY_DATA
43 /* The offset, from the start of the metadata section, of this directory
44 * entry's child files. 0 if the directory entry has no children. */
47 /* Reserved for future disuse. Currently ignoring these fields. */
51 /* Timestamps for the entry. The timestamps are the number of
52 * 100-nanosecond intervals that have elapsed since 12:00 A.M., January
58 /* A hash of the file's contents. */
59 u8 hash[WIM_HASH_SIZE];
61 /* Identity of a reparse point (whatever that is). Currently ignoring
65 /* Although M$'s documentation does not tell you this, it seems that the
66 * reparse_reserved field does not actually exist. So the hard_link
67 * field directly follows the reparse_tag on disk. */
68 //u32 reparse_reserved;
70 /* If the reparse_reserved field existed, there would be a 4-byte gap
71 * here to align hard_link on an 8-byte field. However,
72 * reparse_reserved does not actually exist, so there is no gap here. */
74 /* If the file is part of a hard link set, all the directory entries in
75 * the set will share the same value for this field. */
78 /* Number of WIMStreamEntry structures that follow this struct dentry.
79 * Currently ignoring this field. */
82 /* Length of short filename, in bytes, not including the terminating
83 * zero wide-character. */
86 /* Length of file name, in bytes, not including the terminating zero
90 /* Length of the filename converted into UTF-8, in bytes, not including
91 * the terminating zero byte. */
92 u16 file_name_utf8_len;
94 /* Pointer to the short filename */
97 /* Pointer to the filename. */
100 /* Pointer to the filename converted to UTF-8. */
101 char *file_name_utf8;
103 /* Full path to this dentry. */
104 char *full_path_utf8;
105 u32 full_path_utf8_len;
107 /* Stream entries for this dentry. Currently being ignored. */
108 //struct WIMStreamEntry *stream_entries;
110 /* Number of references to the dentry tree itself, as in multiple
115 #define WIM_FILE_ATTRIBUTE_READONLY 0x1
116 #define WIM_FILE_ATTRIBUTE_HIDDEN 0x2
117 #define WIM_FILE_ATTRIBUTE_SYSTEM 0x4
118 #define WIM_FILE_ATTRIBUTE_DIRECTORY 0x10
119 #define WIM_FILE_ATTRIBUTE_ARCHIVE 0x20
120 #define WIM_FILE_ATTRIBUTE_DEVICE 0x40
121 #define WIM_FILE_ATTRIBUTE_NORMAL 0x80
122 #define WIM_FILE_ATTRIBUTE_TEMPORARY 0x100
123 #define WIM_FILE_ATTRIBUTE_SPARSE_FILE 0x200
124 #define WIM_FILE_ATTRIBUTE_REPARSE_POINT 0x400
125 #define WIM_FILE_ATTRIBUTE_COMPRESSED 0x800
126 #define WIM_FILE_ATTRIBUTE_OFFLINE 0x1000
127 #define WIM_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x2000
128 #define WIM_FILE_ATTRIBUTE_ENCRYPTED 0x4000
129 #define WIM_FILE_ATTRIBUTE_VIRTUAL 0x10000
131 extern void stbuf_to_dentry(const struct stat *stbuf, struct dentry *dentry);
133 extern void dentry_to_stbuf(const struct dentry *dentry, struct stat *stbuf,
134 const struct lookup_table *table);
136 extern int for_dentry_in_tree(struct dentry *root,
137 int (*visitor)(struct dentry*, void*),
140 extern int for_dentry_in_tree_depth(struct dentry *root,
141 int (*visitor)(struct dentry*, void*),
144 extern int calculate_dentry_full_path(struct dentry *dentry, void *ignore);
145 extern void calculate_subdir_offsets(struct dentry *dentry, u64 *subdir_offset_p);
146 extern int change_dentry_name(struct dentry *dentry, const char *new_name);
148 extern void unlink_dentry(struct dentry *dentry);
149 extern void link_dentry(struct dentry *dentry, struct dentry *parent);
151 extern int print_dentry(struct dentry *dentry, void *lookup_table);
152 extern int print_dentry_full_path(struct dentry *entry, void *ignore);
154 extern struct dentry *get_dentry(WIMStruct *w, const char *path);
155 extern struct dentry *get_parent_dentry(WIMStruct *w, const char *path);
156 extern struct dentry *get_dentry_child_with_name(const struct dentry *dentry,
158 extern void dentry_update_all_timestamps(struct dentry *dentry);
159 extern void init_dentry(struct dentry *dentry, const char *name);
160 extern struct dentry *new_dentry(const char *name);
162 extern void free_dentry(struct dentry *dentry);
163 extern void free_dentry_tree(struct dentry *root,
164 struct lookup_table *lookup_table,
165 bool lt_decrement_refcnt);
166 extern int increment_dentry_refcnt(struct dentry *dentry, void *ignore);
167 extern int decrement_dentry_refcnt(struct dentry *dentry, void *ignore);
169 extern void calculate_dir_tree_statistics(struct dentry *root,
170 struct lookup_table *table,
173 u64 *total_bytes_ret,
174 u64 *hard_link_bytes_ret);
176 extern int read_dentry(const u8 metadata_resource[], u64 metadata_resource_len,
177 u64 offset, struct dentry *dentry);
179 extern int read_dentry_tree(const u8 metadata_resource[],
180 u64 metadata_resource_len, struct dentry *dentry);
182 extern u8 *write_dentry_tree(const struct dentry *tree, u8 *p);
184 /* Inline utility functions for WIMDentries */
187 * Returns true if @dentry has the UTF-8 file name @name that has length
190 static inline bool dentry_has_name(const struct dentry *dentry, const char *name,
193 if (dentry->file_name_utf8_len != name_len)
195 return memcmp(dentry->file_name_utf8, name, name_len) == 0;
198 static inline bool dentry_is_root(const struct dentry *dentry)
200 return dentry->parent == dentry;
203 static inline bool dentry_is_first_sibling(const struct dentry *dentry)
205 return dentry_is_root(dentry) || dentry->parent->children == dentry;
208 static inline bool dentry_is_only_child(const struct dentry *dentry)
210 return dentry->next == dentry;
213 static inline bool dentry_is_directory(const struct dentry *dentry)
215 return (dentry->attributes & WIM_FILE_ATTRIBUTE_DIRECTORY) != 0;
218 static inline bool dentry_is_regular_file(const struct dentry *dentry)
220 return !dentry_is_directory(dentry);
223 static inline bool dentry_is_empty_directory(const struct dentry *dentry)
225 return dentry_is_directory(dentry) && dentry->children == NULL;