]> wimlib.net Git - wimlib/blob - src/dentry.c
2dcc6167164d7d063adaade8c72163f62a4ec093
[wimlib] / src / dentry.c
1 /*
2  * dentry.c
3  *
4  * In the WIM file format, the dentries are stored in the "metadata resource"
5  * section right after the security data.  Each image in the WIM file has its
6  * own metadata resource with its own security data and dentry tree.  Dentries
7  * in different images may share file resources by referring to the same lookup
8  * table entries.
9  */
10
11 /*
12  * Copyright (C) 2012, 2013, 2014 Eric Biggers
13  *
14  * This file is part of wimlib, a library for working with WIM files.
15  *
16  * wimlib is free software; you can redistribute it and/or modify it under the
17  * terms of the GNU General Public License as published by the Free Software
18  * Foundation; either version 3 of the License, or (at your option) any later
19  * version.
20  *
21  * wimlib is distributed in the hope that it will be useful, but WITHOUT ANY
22  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
23  * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License along with
26  * wimlib; if not, see http://www.gnu.org/licenses/.
27  */
28
29 #ifdef HAVE_CONFIG_H
30 #  include "config.h"
31 #endif
32
33 #include "wimlib.h"
34 #include "wimlib/case.h"
35 #include "wimlib/dentry.h"
36 #include "wimlib/encoding.h"
37 #include "wimlib/endianness.h"
38 #include "wimlib/error.h"
39 #include "wimlib/lookup_table.h"
40 #include "wimlib/metadata.h"
41 #include "wimlib/paths.h"
42 #include "wimlib/resource.h"
43 #include "wimlib/security.h"
44 #include "wimlib/sha1.h"
45 #include "wimlib/timestamp.h"
46
47 #include <errno.h>
48
49 /* On-disk format of a WIM dentry (directory entry), located in the metadata
50  * resource for a WIM image.  */
51 struct wim_dentry_on_disk {
52
53         /* Length of this directory entry in bytes, not including any alternate
54          * data stream entries.  Should be a multiple of 8 so that the following
55          * dentry or alternate data stream entry is aligned on an 8-byte
56          * boundary.  (If not, wimlib will round it up.)  It must be at least as
57          * long as the fixed-length fields of the dentry (WIM_DENTRY_DISK_SIZE),
58          * plus the lengths of the file name and/or short name if present.
59          *
60          * It is also possible for this field to be 0.  This situation, which is
61          * undocumented, indicates the end of a list of sibling nodes in a
62          * directory.  It also means the real length is 8, because the dentry
63          * included only the length field, but that takes up 8 bytes.  */
64         le64 length;
65
66         /* Attributes of the file or directory.  This is a bitwise OR of the
67          * FILE_ATTRIBUTE_* constants and should correspond to the value
68          * retrieved by GetFileAttributes() on Windows. */
69         le32 attributes;
70
71         /* A value that specifies the security descriptor for this file or
72          * directory.  If -1, the file or directory has no security descriptor.
73          * Otherwise, it is a 0-based index into the WIM image's table of
74          * security descriptors (see: `struct wim_security_data') */
75         sle32 security_id;
76
77         /* Offset, in bytes, from the start of the uncompressed metadata
78          * resource of this directory's child directory entries, or 0 if this
79          * directory entry does not correspond to a directory or otherwise does
80          * not have any children. */
81         le64 subdir_offset;
82
83         /* Reserved fields */
84         le64 unused_1;
85         le64 unused_2;
86
87         /* Creation time, last access time, and last write time, in
88          * 100-nanosecond intervals since 12:00 a.m UTC January 1, 1601.  They
89          * should correspond to the times gotten by calling GetFileTime() on
90          * Windows. */
91         le64 creation_time;
92         le64 last_access_time;
93         le64 last_write_time;
94
95         /* Vaguely, the SHA-1 message digest ("hash") of the file's contents.
96          * More specifically, this is for the "unnamed data stream" rather than
97          * any "alternate data streams".  This hash value is used to look up the
98          * corresponding entry in the WIM's stream lookup table to actually find
99          * the file contents within the WIM.
100          *
101          * If the file has no unnamed data stream (e.g. is a directory), then
102          * this field will be all zeroes.  If the unnamed data stream is empty
103          * (i.e. an "empty file"), then this field is also expected to be all
104          * zeroes.  (It will be if wimlib created the WIM image, at least;
105          * otherwise it can't be ruled out that the SHA-1 message digest of 0
106          * bytes of data is given explicitly.)
107          *
108          * If the file has reparse data, then this field will instead specify
109          * the SHA-1 message digest of the reparse data.  If it is somehow
110          * possible for a file to have both an unnamed data stream and reparse
111          * data, then this is not handled by wimlib.
112          *
113          * As a further special case, if this field is all zeroes but there is
114          * an alternate data stream entry with no name and a nonzero SHA-1
115          * message digest field, then that hash must be used instead of this
116          * one.  In fact, when named data streams are present, some versions of
117          * Windows PE contain a bug where they only look in the alternate data
118          * stream entries for the unnamed data stream, not here.
119          */
120         u8 unnamed_stream_hash[SHA1_HASH_SIZE];
121
122         /* The format of the following data is not yet completely known and they
123          * do not correspond to Microsoft's documentation.
124          *
125          * If this directory entry is for a reparse point (has
126          * FILE_ATTRIBUTE_REPARSE_POINT set in the attributes field), then the
127          * version of the following fields containing the reparse tag is valid.
128          * Furthermore, the field notated as not_rpfixed, as far as I can tell,
129          * is supposed to be set to 1 if reparse point fixups (a.k.a. fixing the
130          * targets of absolute symbolic links) were *not* done, and otherwise 0.
131          *
132          * If this directory entry is not for a reparse point, then the version
133          * of the following fields containing the hard_link_group_id is valid.
134          * All MS says about this field is that "If this file is part of a hard
135          * link set, all the directory entries in the set will share the same
136          * value in this field.".  However, more specifically I have observed
137          * the following:
138          *    - If the file is part of a hard link set of size 1, then the
139          *    hard_link_group_id should be set to either 0, which is treated
140          *    specially as indicating "not hardlinked", or any unique value.
141          *    - The specific nonzero values used to identity hard link sets do
142          *    not matter, as long as they are unique.
143          *    - However, due to bugs in Microsoft's software, it is actually NOT
144          *    guaranteed that directory entries that share the same hard link
145          *    group ID are actually hard linked to each either.  We have to
146          *    handle this by using special code to use distinguishing features
147          *    (which is possible because some information about the underlying
148          *    inode is repeated in each dentry) to split up these fake hard link
149          *    groups into what they actually are supposed to be.
150          */
151         union {
152                 struct {
153                         le32 rp_unknown_1;
154                         le32 reparse_tag;
155                         le16 rp_unknown_2;
156                         le16 not_rpfixed;
157                 } _packed_attribute reparse;
158                 struct {
159                         le32 rp_unknown_1;
160                         le64 hard_link_group_id;
161                 } _packed_attribute nonreparse;
162         };
163
164         /* Number of alternate data stream entries that directly follow this
165          * dentry on-disk. */
166         le16 num_alternate_data_streams;
167
168         /* Length of this file's UTF-16LE encoded short name (8.3 DOS-compatible
169          * name), if present, in bytes, excluding the null terminator.  If this
170          * file has no short name, then this field should be 0.  */
171         le16 short_name_nbytes;
172
173         /* Length of this file's UTF-16LE encoded "long" name, excluding the
174          * null terminator.  If this file has no short name, then this field
175          * should be 0.  It's expected that only the root dentry has this field
176          * set to 0.  */
177         le16 file_name_nbytes;
178
179         /* Followed by variable length file name, in UTF16-LE, if
180          * file_name_nbytes != 0.  Includes null terminator. */
181         /*utf16lechar file_name[];*/
182
183         /* Followed by variable length short name, in UTF16-LE, if
184          * short_name_nbytes != 0.  Includes null terminator. */
185         /*utf16lechar short_name[];*/
186
187         /* And optionally followed by a variable-length series of tagged items;
188          * see tagged_items.c.  */
189 } _packed_attribute;
190
191 /* Calculates the unaligned length, in bytes, of an on-disk WIM dentry that has
192  * a file name and short name that take the specified numbers of bytes.  This
193  * excludes any alternate data stream entries that may follow the dentry. */
194 static u64
195 dentry_correct_length_unaligned(u16 file_name_nbytes, u16 short_name_nbytes)
196 {
197         u64 length = sizeof(struct wim_dentry_on_disk);
198         if (file_name_nbytes)
199                 length += file_name_nbytes + 2;
200         if (short_name_nbytes)
201                 length += short_name_nbytes + 2;
202         return length;
203 }
204
205 /* Calculates the unaligned length, in bytes, of an on-disk WIM dentry, based on
206  * the file name length, short name length, and optional tagged items.  Note
207  * that dentry->length is ignored; also, this excludes any alternate data stream
208  * entries that may follow the dentry.  */
209 static u64
210 dentry_correct_length_aligned(const struct wim_dentry *dentry)
211 {
212         u64 len;
213
214         len = dentry_correct_length_unaligned(dentry->file_name_nbytes,
215                                               dentry->short_name_nbytes);
216
217         if (dentry->d_inode->i_extra_size) {
218                 len = (len + 7) & ~7;
219                 len += dentry->d_inode->i_extra_size;
220         }
221
222         return (len + 7) & ~7;
223 }
224
225 static void
226 do_dentry_set_name(struct wim_dentry *dentry, utf16lechar *file_name,
227                    size_t file_name_nbytes)
228 {
229         FREE(dentry->file_name);
230         dentry->file_name = file_name;
231         dentry->file_name_nbytes = file_name_nbytes;
232
233         if (dentry_has_short_name(dentry)) {
234                 FREE(dentry->short_name);
235                 dentry->short_name = NULL;
236                 dentry->short_name_nbytes = 0;
237         }
238 }
239
240 /* Sets the name of a WIM dentry from a UTF-16LE string.
241  * Only use this on dentries not inserted into the tree.  Use rename_wim_path()
242  * to do a real rename.  */
243 int
244 dentry_set_name_utf16le(struct wim_dentry *dentry, const utf16lechar *name,
245                         size_t name_nbytes)
246 {
247         utf16lechar *dup = NULL;
248
249         if (name_nbytes) {
250                 dup = utf16le_dupz(name, name_nbytes);
251                 if (!dup)
252                         return WIMLIB_ERR_NOMEM;
253         }
254         do_dentry_set_name(dentry, dup, name_nbytes);
255         return 0;
256 }
257
258
259 /* Sets the name of a WIM dentry from a multibyte string.
260  * Only use this on dentries not inserted into the tree.  Use rename_wim_path()
261  * to do a real rename.  */
262 int
263 dentry_set_name(struct wim_dentry *dentry, const tchar *name)
264 {
265         utf16lechar *name_utf16le = NULL;
266         size_t name_utf16le_nbytes = 0;
267         int ret;
268
269         if (name && *name) {
270                 ret = tstr_to_utf16le(name, tstrlen(name) * sizeof(tchar),
271                                       &name_utf16le, &name_utf16le_nbytes);
272                 if (ret)
273                         return ret;
274         }
275
276         do_dentry_set_name(dentry, name_utf16le, name_utf16le_nbytes);
277         return 0;
278 }
279
280 /* Returns the total length of a WIM alternate data stream entry on-disk,
281  * including the stream name, the null terminator, AND the padding after the
282  * entry to align the next ADS entry or dentry on an 8-byte boundary. */
283 static u64
284 ads_entry_total_length(const struct wim_ads_entry *entry)
285 {
286         u64 len = sizeof(struct wim_ads_entry_on_disk);
287         if (entry->stream_name_nbytes)
288                 len += entry->stream_name_nbytes + 2;
289         return (len + 7) & ~7;
290 }
291
292 /*
293  * Determine whether to include a "dummy" stream when writing a WIM dentry:
294  *
295  * Some versions of Microsoft's WIM software (the boot driver(s) in WinPE 3.0,
296  * for example) contain a bug where they assume the first alternate data stream
297  * (ADS) entry of a dentry with a nonzero ADS count specifies the unnamed
298  * stream, even if it has a name and the unnamed stream is already specified in
299  * the hash field of the dentry itself.
300  *
301  * wimlib has to work around this behavior by carefully emulating the behavior
302  * of (most versions of) ImageX/WIMGAPI, which move the unnamed stream reference
303  * into the alternate stream entries whenever there are named data streams, even
304  * though there is already a field in the dentry itself for the unnamed stream
305  * reference, which then goes to waste.
306  */
307 static inline bool
308 inode_needs_dummy_stream(const struct wim_inode *inode)
309 {
310         return (inode->i_num_ads > 0 &&
311                 inode->i_num_ads < 0xffff && /* overflow check */
312                 inode->i_canonical_streams); /* assume the dentry is okay if it
313                                                 already had an unnamed ADS entry
314                                                 when it was read in  */
315 }
316
317 /* Calculate the total number of bytes that will be consumed when a WIM dentry
318  * is written.  This includes base dentry and name fields as well as all
319  * alternate data stream entries and alignment bytes.  */
320 u64
321 dentry_out_total_length(const struct wim_dentry *dentry)
322 {
323         u64 length = dentry_correct_length_aligned(dentry);
324         const struct wim_inode *inode = dentry->d_inode;
325
326         if (inode_needs_dummy_stream(inode))
327                 length += ads_entry_total_length(&(struct wim_ads_entry){});
328
329         for (u16 i = 0; i < inode->i_num_ads; i++)
330                 length += ads_entry_total_length(&inode->i_ads_entries[i]);
331
332         return length;
333 }
334
335 /* Calculate the aligned, total length of a dentry, including all alternate data
336  * stream entries.  Uses dentry->length.  */
337 static u64
338 dentry_in_total_length(const struct wim_dentry *dentry)
339 {
340         u64 length = dentry->length;
341         const struct wim_inode *inode = dentry->d_inode;
342         for (u16 i = 0; i < inode->i_num_ads; i++)
343                 length += ads_entry_total_length(&inode->i_ads_entries[i]);
344         return (length + 7) & ~7;
345 }
346
347 static int
348 do_for_dentry_in_tree(struct wim_dentry *dentry,
349                       int (*visitor)(struct wim_dentry *, void *), void *arg)
350 {
351         int ret;
352         struct wim_dentry *child;
353
354         ret = (*visitor)(dentry, arg);
355         if (unlikely(ret))
356                 return ret;
357
358         for_dentry_child(child, dentry) {
359                 ret = do_for_dentry_in_tree(child, visitor, arg);
360                 if (unlikely(ret))
361                         return ret;
362         }
363         return 0;
364 }
365
366
367 static int
368 do_for_dentry_in_tree_depth(struct wim_dentry *dentry,
369                             int (*visitor)(struct wim_dentry *, void *), void *arg)
370 {
371         int ret;
372         struct wim_dentry *child;
373
374         for_dentry_child_postorder(child, dentry) {
375                 ret = do_for_dentry_in_tree_depth(child, visitor, arg);
376                 if (unlikely(ret))
377                         return ret;
378         }
379         return unlikely((*visitor)(dentry, arg));
380 }
381
382 /* Calls a function on all directory entries in a WIM dentry tree.  Logically,
383  * this is a pre-order traversal (the function is called on a parent dentry
384  * before its children), but sibling dentries will be visited in order as well.
385  * */
386 int
387 for_dentry_in_tree(struct wim_dentry *root,
388                    int (*visitor)(struct wim_dentry *, void *), void *arg)
389 {
390         if (unlikely(!root))
391                 return 0;
392         return do_for_dentry_in_tree(root, visitor, arg);
393 }
394
395 /* Like for_dentry_in_tree(), but the visitor function is always called on a
396  * dentry's children before on itself. */
397 int
398 for_dentry_in_tree_depth(struct wim_dentry *root,
399                          int (*visitor)(struct wim_dentry *, void *), void *arg)
400 {
401         if (unlikely(!root))
402                 return 0;
403         return do_for_dentry_in_tree_depth(root, visitor, arg);
404 }
405
406 /* Calculate the full path of @dentry.  */
407 int
408 calculate_dentry_full_path(struct wim_dentry *dentry)
409 {
410         size_t ulen;
411         size_t dummy;
412         const struct wim_dentry *d;
413
414         if (dentry->_full_path)
415                 return 0;
416
417         ulen = 0;
418         d = dentry;
419         do {
420                 ulen += d->file_name_nbytes / sizeof(utf16lechar);
421                 ulen++;
422                 d = d->parent;  /* assumes d == d->parent for root  */
423         } while (!dentry_is_root(d));
424
425         utf16lechar ubuf[ulen];
426         utf16lechar *p = &ubuf[ulen];
427
428         d = dentry;
429         do {
430                 p -= d->file_name_nbytes / sizeof(utf16lechar);
431                 memcpy(p, d->file_name, d->file_name_nbytes);
432                 *--p = cpu_to_le16(WIM_PATH_SEPARATOR);
433                 d = d->parent;  /* assumes d == d->parent for root  */
434         } while (!dentry_is_root(d));
435
436         wimlib_assert(p == ubuf);
437
438         return utf16le_to_tstr(ubuf, ulen * sizeof(utf16lechar),
439                                &dentry->_full_path, &dummy);
440 }
441
442 tchar *
443 dentry_full_path(struct wim_dentry *dentry)
444 {
445         calculate_dentry_full_path(dentry);
446         return dentry->_full_path;
447 }
448
449 static int
450 dentry_calculate_subdir_offset(struct wim_dentry *dentry, void *_subdir_offset_p)
451 {
452
453         if (dentry_is_directory(dentry)) {
454                 u64 *subdir_offset_p = _subdir_offset_p;
455                 struct wim_dentry *child;
456
457                 /* Set offset of directory's child dentries  */
458                 dentry->subdir_offset = *subdir_offset_p;
459
460                 /* Account for child dentries  */
461                 for_dentry_child(child, dentry)
462                         *subdir_offset_p += dentry_out_total_length(child);
463
464                 /* Account for end-of-directory entry  */
465                 *subdir_offset_p += 8;
466         } else {
467                 /* Not a directory; set subdir_offset to 0  */
468                 dentry->subdir_offset = 0;
469         }
470         return 0;
471 }
472
473 /*
474  * Calculates the subdir offsets for a directory tree.
475  */
476 void
477 calculate_subdir_offsets(struct wim_dentry *root, u64 *subdir_offset_p)
478 {
479         for_dentry_in_tree(root, dentry_calculate_subdir_offset, subdir_offset_p);
480 }
481
482 /* Compare the UTF-16LE long filenames of two dentries case insensitively.  */
483 static int
484 dentry_compare_names_case_insensitive(const struct wim_dentry *d1,
485                                       const struct wim_dentry *d2)
486 {
487         return cmp_utf16le_strings(d1->file_name,
488                                    d1->file_name_nbytes / 2,
489                                    d2->file_name,
490                                    d2->file_name_nbytes / 2,
491                                    true);
492 }
493
494 /* Compare the UTF-16LE long filenames of two dentries case sensitively.  */
495 static int
496 dentry_compare_names_case_sensitive(const struct wim_dentry *d1,
497                                     const struct wim_dentry *d2)
498 {
499         return cmp_utf16le_strings(d1->file_name,
500                                    d1->file_name_nbytes / 2,
501                                    d2->file_name,
502                                    d2->file_name_nbytes / 2,
503                                    false);
504 }
505
506 static int
507 _avl_dentry_compare_names_ci(const struct avl_tree_node *n1,
508                              const struct avl_tree_node *n2)
509 {
510         const struct wim_dentry *d1, *d2;
511
512         d1 = avl_tree_entry(n1, struct wim_dentry, d_index_node_ci);
513         d2 = avl_tree_entry(n2, struct wim_dentry, d_index_node_ci);
514         return dentry_compare_names_case_insensitive(d1, d2);
515 }
516
517 static int
518 _avl_dentry_compare_names(const struct avl_tree_node *n1,
519                           const struct avl_tree_node *n2)
520 {
521         const struct wim_dentry *d1, *d2;
522
523         d1 = avl_tree_entry(n1, struct wim_dentry, d_index_node);
524         d2 = avl_tree_entry(n2, struct wim_dentry, d_index_node);
525         return dentry_compare_names_case_sensitive(d1, d2);
526 }
527
528 /* Default case sensitivity behavior for searches with
529  * WIMLIB_CASE_PLATFORM_DEFAULT specified.  This can be modified by
530  * wimlib_global_init().  */
531 bool default_ignore_case =
532 #ifdef __WIN32__
533         true
534 #else
535         false
536 #endif
537 ;
538
539 /* Case-sensitive dentry lookup.  Only @file_name and @file_name_nbytes of
540  * @dummy must be valid.  */
541 static struct wim_dentry *
542 dir_lookup(const struct wim_inode *dir, const struct wim_dentry *dummy)
543 {
544         struct avl_tree_node *node;
545
546         node = avl_tree_lookup_node(dir->i_children,
547                                     &dummy->d_index_node,
548                                     _avl_dentry_compare_names);
549         if (!node)
550                 return NULL;
551         return avl_tree_entry(node, struct wim_dentry, d_index_node);
552 }
553
554 /* Case-insensitive dentry lookup.  Only @file_name and @file_name_nbytes of
555  * @dummy must be valid.  */
556 static struct wim_dentry *
557 dir_lookup_ci(const struct wim_inode *dir, const struct wim_dentry *dummy)
558 {
559         struct avl_tree_node *node;
560
561         node = avl_tree_lookup_node(dir->i_children_ci,
562                                     &dummy->d_index_node_ci,
563                                     _avl_dentry_compare_names_ci);
564         if (!node)
565                 return NULL;
566         return avl_tree_entry(node, struct wim_dentry, d_index_node_ci);
567 }
568
569 /* Given a UTF-16LE filename and a directory, look up the dentry for the file.
570  * Return it if found, otherwise NULL.  This has configurable case sensitivity,
571  * and @name need not be null-terminated.  */
572 struct wim_dentry *
573 get_dentry_child_with_utf16le_name(const struct wim_dentry *dentry,
574                                    const utf16lechar *name,
575                                    size_t name_nbytes,
576                                    CASE_SENSITIVITY_TYPE case_ctype)
577 {
578         const struct wim_inode *dir = dentry->d_inode;
579         bool ignore_case = will_ignore_case(case_ctype);
580         struct wim_dentry dummy;
581         struct wim_dentry *child;
582
583         dummy.file_name = (utf16lechar*)name;
584         dummy.file_name_nbytes = name_nbytes;
585
586         if (!ignore_case)
587                 /* Case-sensitive lookup.  */
588                 return dir_lookup(dir, &dummy);
589
590         /* Case-insensitive lookup.  */
591
592         child = dir_lookup_ci(dir, &dummy);
593         if (!child)
594                 return NULL;
595
596         if (likely(list_empty(&child->d_ci_conflict_list)))
597                 /* Only one dentry has this case-insensitive name; return it */
598                 return child;
599
600         /* Multiple dentries have the same case-insensitive name.  Choose the
601          * dentry with the same case-sensitive name, if one exists; otherwise
602          * print a warning and choose one of the possible dentries arbitrarily.
603          */
604         struct wim_dentry *alt = child;
605         size_t num_alts = 0;
606
607         do {
608                 num_alts++;
609                 if (!dentry_compare_names_case_sensitive(&dummy, alt))
610                         return alt;
611                 alt = list_entry(alt->d_ci_conflict_list.next,
612                                  struct wim_dentry, d_ci_conflict_list);
613         } while (alt != child);
614
615         WARNING("Result of case-insensitive lookup is ambiguous\n"
616                 "          (returning \"%"TS"\" of %zu "
617                 "possible files, including \"%"TS"\")",
618                 dentry_full_path(child),
619                 num_alts,
620                 dentry_full_path(list_entry(child->d_ci_conflict_list.next,
621                                             struct wim_dentry,
622                                             d_ci_conflict_list)));
623         return child;
624 }
625
626 /* Returns the child of @dentry that has the file name @name.  Returns NULL if
627  * no child has the name. */
628 struct wim_dentry *
629 get_dentry_child_with_name(const struct wim_dentry *dentry, const tchar *name,
630                            CASE_SENSITIVITY_TYPE case_type)
631 {
632         int ret;
633         const utf16lechar *name_utf16le;
634         size_t name_utf16le_nbytes;
635         struct wim_dentry *child;
636
637         ret = tstr_get_utf16le_and_len(name, &name_utf16le,
638                                        &name_utf16le_nbytes);
639         if (ret)
640                 return NULL;
641
642         child = get_dentry_child_with_utf16le_name(dentry,
643                                                    name_utf16le,
644                                                    name_utf16le_nbytes,
645                                                    case_type);
646         tstr_put_utf16le(name_utf16le);
647         return child;
648 }
649
650 static struct wim_dentry *
651 get_dentry_utf16le(WIMStruct *wim, const utf16lechar *path,
652                    CASE_SENSITIVITY_TYPE case_type)
653 {
654         struct wim_dentry *cur_dentry;
655         const utf16lechar *name_start, *name_end;
656
657         /* Start with the root directory of the image.  Note: this will be NULL
658          * if an image has been added directly with wimlib_add_empty_image() but
659          * no files have been added yet; in that case we fail with ENOENT.  */
660         cur_dentry = wim_get_current_root_dentry(wim);
661
662         name_start = path;
663         for (;;) {
664                 if (cur_dentry == NULL) {
665                         errno = ENOENT;
666                         return NULL;
667                 }
668
669                 if (*name_start && !dentry_is_directory(cur_dentry)) {
670                         errno = ENOTDIR;
671                         return NULL;
672                 }
673
674                 while (*name_start == cpu_to_le16(WIM_PATH_SEPARATOR))
675                         name_start++;
676
677                 if (!*name_start)
678                         return cur_dentry;
679
680                 name_end = name_start;
681                 do {
682                         ++name_end;
683                 } while (*name_end != cpu_to_le16(WIM_PATH_SEPARATOR) && *name_end);
684
685                 cur_dentry = get_dentry_child_with_utf16le_name(cur_dentry,
686                                                                 name_start,
687                                                                 (u8*)name_end - (u8*)name_start,
688                                                                 case_type);
689                 name_start = name_end;
690         }
691 }
692
693 /*
694  * WIM path lookup: translate a path in the currently selected WIM image to the
695  * corresponding dentry, if it exists.
696  *
697  * @wim
698  *      The WIMStruct for the WIM.  The search takes place in the currently
699  *      selected image.
700  *
701  * @path
702  *      The path to look up, given relative to the root of the WIM image.
703  *      Characters with value WIM_PATH_SEPARATOR are taken to be path
704  *      separators.  Leading path separators are ignored, whereas one or more
705  *      trailing path separators cause the path to only match a directory.
706  *
707  * @case_type
708  *      The case-sensitivity behavior of this function, as one of the following
709  *      constants:
710  *
711  *    - WIMLIB_CASE_SENSITIVE:  Perform the search case sensitively.  This means
712  *      that names must match exactly.
713  *
714  *    - WIMLIB_CASE_INSENSITIVE:  Perform the search case insensitively.  This
715  *      means that names are considered to match if they are equal when
716  *      transformed to upper case.  If a path component matches multiple names
717  *      case-insensitively, the name that matches the path component
718  *      case-sensitively is chosen, if existent; otherwise one
719  *      case-insensitively matching name is chosen arbitrarily.
720  *
721  *    - WIMLIB_CASE_PLATFORM_DEFAULT:  Perform either case-sensitive or
722  *      case-insensitive search, depending on the value of the global variable
723  *      default_ignore_case.
724  *
725  *    In any case, no Unicode normalization is done before comparing strings.
726  *
727  * Returns a pointer to the dentry that is the result of the lookup, or NULL if
728  * no such dentry exists.  If NULL is returned, errno is set to one of the
729  * following values:
730  *
731  *      ENOTDIR if one of the path components used as a directory existed but
732  *      was not, in fact, a directory.
733  *
734  *      ENOENT otherwise.
735  *
736  * Additional notes:
737  *
738  *    - This function does not consider a reparse point to be a directory, even
739  *      if it has FILE_ATTRIBUTE_DIRECTORY set.
740  *
741  *    - This function does not dereference symbolic links or junction points
742  *      when performing the search.
743  *
744  *    - Since this function ignores leading slashes, the empty path is valid and
745  *      names the root directory of the WIM image.
746  *
747  *    - An image added with wimlib_add_empty_image() does not have a root
748  *      directory yet, and this function will fail with ENOENT for any path on
749  *      such an image.
750  */
751 struct wim_dentry *
752 get_dentry(WIMStruct *wim, const tchar *path, CASE_SENSITIVITY_TYPE case_type)
753 {
754         int ret;
755         const utf16lechar *path_utf16le;
756         struct wim_dentry *dentry;
757
758         ret = tstr_get_utf16le(path, &path_utf16le);
759         if (ret)
760                 return NULL;
761         dentry = get_dentry_utf16le(wim, path_utf16le, case_type);
762         tstr_put_utf16le(path_utf16le);
763         return dentry;
764 }
765
766 /* Takes in a path of length @len in @buf, and transforms it into a string for
767  * the path of its parent directory. */
768 static void
769 to_parent_name(tchar *buf, size_t len)
770 {
771         ssize_t i = (ssize_t)len - 1;
772         while (i >= 0 && buf[i] == WIM_PATH_SEPARATOR)
773                 i--;
774         while (i >= 0 && buf[i] != WIM_PATH_SEPARATOR)
775                 i--;
776         while (i >= 0 && buf[i] == WIM_PATH_SEPARATOR)
777                 i--;
778         buf[i + 1] = T('\0');
779 }
780
781 /* Similar to get_dentry(), but returns the dentry named by @path with the last
782  * component stripped off.
783  *
784  * Note: The returned dentry is NOT guaranteed to be a directory.  */
785 struct wim_dentry *
786 get_parent_dentry(WIMStruct *wim, const tchar *path,
787                   CASE_SENSITIVITY_TYPE case_type)
788 {
789         size_t path_len = tstrlen(path);
790         tchar buf[path_len + 1];
791
792         tmemcpy(buf, path, path_len + 1);
793         to_parent_name(buf, path_len);
794         return get_dentry(wim, buf, case_type);
795 }
796
797 #ifdef WITH_FUSE
798 /* Finds the dentry, lookup table entry, and stream index for a WIM file stream,
799  * given a path name.
800  *
801  * Currently, lookups of this type are only needed if FUSE is enabled.  */
802 int
803 wim_pathname_to_stream(WIMStruct *wim,
804                        const tchar *path,
805                        int lookup_flags,
806                        struct wim_dentry **dentry_ret,
807                        struct wim_lookup_table_entry **lte_ret,
808                        u16 *stream_idx_ret)
809 {
810         struct wim_dentry *dentry;
811         struct wim_lookup_table_entry *lte;
812         u16 stream_idx;
813         const tchar *stream_name = NULL;
814         struct wim_inode *inode;
815         tchar *p = NULL;
816
817         if (lookup_flags & LOOKUP_FLAG_ADS_OK) {
818                 stream_name = path_stream_name(path);
819                 if (stream_name) {
820                         p = (tchar*)stream_name - 1;
821                         *p = T('\0');
822                 }
823         }
824
825         dentry = get_dentry(wim, path, WIMLIB_CASE_SENSITIVE);
826         if (p)
827                 *p = T(':');
828         if (!dentry)
829                 return -errno;
830
831         inode = dentry->d_inode;
832
833         if (!inode->i_resolved)
834                 if (inode_resolve_streams(inode, wim->lookup_table, false))
835                         return -EIO;
836
837         if (!(lookup_flags & LOOKUP_FLAG_DIRECTORY_OK)
838               && inode_is_directory(inode))
839                 return -EISDIR;
840
841         if (stream_name) {
842                 struct wim_ads_entry *ads_entry;
843                 u16 ads_idx;
844                 ads_entry = inode_get_ads_entry(inode, stream_name,
845                                                 &ads_idx);
846                 if (ads_entry) {
847                         stream_idx = ads_idx + 1;
848                         lte = ads_entry->lte;
849                 } else {
850                         return -ENOENT;
851                 }
852         } else {
853                 lte = inode_unnamed_stream_resolved(inode, &stream_idx);
854         }
855         if (dentry_ret)
856                 *dentry_ret = dentry;
857         if (lte_ret)
858                 *lte_ret = lte;
859         if (stream_idx_ret)
860                 *stream_idx_ret = stream_idx;
861         return 0;
862 }
863 #endif /* WITH_FUSE  */
864
865 /* Creates an unlinked directory entry. */
866 int
867 new_dentry(const tchar *name, struct wim_dentry **dentry_ret)
868 {
869         struct wim_dentry *dentry;
870         int ret;
871
872         dentry = CALLOC(1, sizeof(struct wim_dentry));
873         if (!dentry)
874                 return WIMLIB_ERR_NOMEM;
875
876         if (*name) {
877                 ret = dentry_set_name(dentry, name);
878                 if (ret) {
879                         FREE(dentry);
880                         ERROR("Failed to set name on new dentry with name \"%"TS"\"",
881                               name);
882                         return ret;
883                 }
884         }
885         dentry->parent = dentry;
886         *dentry_ret = dentry;
887         return 0;
888 }
889
890 static int
891 _new_dentry_with_inode(const tchar *name, struct wim_dentry **dentry_ret,
892                         bool timeless)
893 {
894         struct wim_dentry *dentry;
895         int ret;
896
897         ret = new_dentry(name, &dentry);
898         if (ret)
899                 return ret;
900
901         if (timeless)
902                 dentry->d_inode = new_timeless_inode();
903         else
904                 dentry->d_inode = new_inode();
905         if (dentry->d_inode == NULL) {
906                 free_dentry(dentry);
907                 return WIMLIB_ERR_NOMEM;
908         }
909
910         inode_add_dentry(dentry, dentry->d_inode);
911         *dentry_ret = dentry;
912         return 0;
913 }
914
915 int
916 new_dentry_with_timeless_inode(const tchar *name, struct wim_dentry **dentry_ret)
917 {
918         return _new_dentry_with_inode(name, dentry_ret, true);
919 }
920
921 int
922 new_dentry_with_inode(const tchar *name, struct wim_dentry **dentry_ret)
923 {
924         return _new_dentry_with_inode(name, dentry_ret, false);
925 }
926
927 int
928 new_filler_directory(struct wim_dentry **dentry_ret)
929 {
930         int ret;
931         struct wim_dentry *dentry;
932
933         ret = new_dentry_with_inode(T(""), &dentry);
934         if (ret)
935                 return ret;
936         /* Leave the inode number as 0; this is allowed for non
937          * hard-linked files. */
938         dentry->d_inode->i_resolved = 1;
939         dentry->d_inode->i_attributes = FILE_ATTRIBUTE_DIRECTORY;
940         *dentry_ret = dentry;
941         return 0;
942 }
943
944 static int
945 dentry_clear_inode_visited(struct wim_dentry *dentry, void *_ignore)
946 {
947         dentry->d_inode->i_visited = 0;
948         return 0;
949 }
950
951 void
952 dentry_tree_clear_inode_visited(struct wim_dentry *root)
953 {
954         for_dentry_in_tree(root, dentry_clear_inode_visited, NULL);
955 }
956
957 /*
958  * Free a WIM dentry.
959  *
960  * In addition to freeing the dentry itself, this decrements the link count of
961  * the corresponding inode (if any).  If the inode's link count reaches 0, the
962  * inode is freed as well.
963  */
964 void
965 free_dentry(struct wim_dentry *dentry)
966 {
967         if (dentry) {
968                 FREE(dentry->file_name);
969                 FREE(dentry->short_name);
970                 FREE(dentry->_full_path);
971                 if (dentry->d_inode)
972                         put_inode(dentry->d_inode);
973                 FREE(dentry);
974         }
975 }
976
977 static int
978 do_free_dentry(struct wim_dentry *dentry, void *_ignore)
979 {
980         free_dentry(dentry);
981         return 0;
982 }
983
984 static int
985 do_free_dentry_and_unref_streams(struct wim_dentry *dentry, void *lookup_table)
986 {
987         inode_unref_streams(dentry->d_inode, lookup_table);
988         free_dentry(dentry);
989         return 0;
990 }
991
992 /*
993  * Recursively frees all directory entries in the specified tree.
994  *
995  * @root:
996  *      The root of the tree.
997  *
998  * @lookup_table:
999  *      The lookup table for dentries.  If non-NULL, the reference counts in the
1000  *      lookup table for the lookup table entries corresponding to the dentries
1001  *      will be decremented.
1002  *
1003  * This also puts references to the corresponding inodes.
1004  *
1005  * This does *not* unlink @root from its parent directory (if it has one).
1006  */
1007 void
1008 free_dentry_tree(struct wim_dentry *root, struct wim_lookup_table *lookup_table)
1009 {
1010         int (*f)(struct wim_dentry *, void *);
1011
1012         if (lookup_table)
1013                 f = do_free_dentry_and_unref_streams;
1014         else
1015                 f = do_free_dentry;
1016
1017         for_dentry_in_tree_depth(root, f, lookup_table);
1018 }
1019
1020 /* Insert the @child dentry into the case sensitive index of the @dir directory.
1021  * Return NULL if successfully inserted, otherwise a pointer to the
1022  * already-inserted duplicate.  */
1023 static struct wim_dentry *
1024 dir_index_child(struct wim_inode *dir, struct wim_dentry *child)
1025 {
1026         struct avl_tree_node *duplicate;
1027
1028         duplicate = avl_tree_insert(&dir->i_children,
1029                                     &child->d_index_node,
1030                                     _avl_dentry_compare_names);
1031         if (!duplicate)
1032                 return NULL;
1033         return avl_tree_entry(duplicate, struct wim_dentry, d_index_node);
1034 }
1035
1036 /* Insert the @child dentry into the case insensitive index of the @dir
1037  * directory.  Return NULL if successfully inserted, otherwise a pointer to the
1038  * already-inserted duplicate.  */
1039 static struct wim_dentry *
1040 dir_index_child_ci(struct wim_inode *dir, struct wim_dentry *child)
1041 {
1042         struct avl_tree_node *duplicate;
1043
1044         duplicate = avl_tree_insert(&dir->i_children_ci,
1045                                     &child->d_index_node_ci,
1046                                     _avl_dentry_compare_names_ci);
1047         if (!duplicate)
1048                 return NULL;
1049         return avl_tree_entry(duplicate, struct wim_dentry, d_index_node_ci);
1050 }
1051
1052 /* Removes the specified dentry from its directory's case-sensitive index.  */
1053 static void
1054 dir_unindex_child(struct wim_inode *dir, struct wim_dentry *child)
1055 {
1056         avl_tree_remove(&dir->i_children, &child->d_index_node);
1057 }
1058
1059 /* Removes the specified dentry from its directory's case-insensitive index.  */
1060 static void
1061 dir_unindex_child_ci(struct wim_inode *dir, struct wim_dentry *child)
1062 {
1063         avl_tree_remove(&dir->i_children_ci, &child->d_index_node_ci);
1064 }
1065
1066 /* Returns true iff the specified dentry is in its parent directory's
1067  * case-insensitive index.  */
1068 static bool
1069 dentry_in_ci_index(const struct wim_dentry *dentry)
1070 {
1071         return !avl_tree_node_is_unlinked(&dentry->d_index_node_ci);
1072 }
1073
1074 /*
1075  * Links a dentry into the directory tree.
1076  *
1077  * @parent: The dentry that will be the parent of @child.
1078  * @child: The dentry to link.
1079  *
1080  * Returns NULL if successful.  If @parent already contains a dentry with the
1081  * same case-sensitive name as @child, returns a pointer to this duplicate
1082  * dentry.
1083  */
1084 struct wim_dentry *
1085 dentry_add_child(struct wim_dentry *parent, struct wim_dentry *child)
1086 {
1087         struct wim_dentry *duplicate;
1088         struct wim_inode *dir;
1089
1090         wimlib_assert(parent != child);
1091
1092         dir = parent->d_inode;
1093
1094         wimlib_assert(inode_is_directory(dir));
1095
1096         duplicate = dir_index_child(dir, child);
1097         if (duplicate)
1098                 return duplicate;
1099
1100         duplicate = dir_index_child_ci(dir, child);
1101         if (duplicate) {
1102                 list_add(&child->d_ci_conflict_list, &duplicate->d_ci_conflict_list);
1103                 avl_tree_node_set_unlinked(&child->d_index_node_ci);
1104         } else {
1105                 INIT_LIST_HEAD(&child->d_ci_conflict_list);
1106         }
1107         child->parent = parent;
1108         return NULL;
1109 }
1110
1111 /* Unlink a WIM dentry from the directory entry tree.  */
1112 void
1113 unlink_dentry(struct wim_dentry *dentry)
1114 {
1115         struct wim_inode *dir;
1116
1117         if (dentry_is_root(dentry))
1118                 return;
1119
1120         dir = dentry->parent->d_inode;
1121
1122         dir_unindex_child(dir, dentry);
1123
1124         if (dentry_in_ci_index(dentry)) {
1125
1126                 dir_unindex_child_ci(dir, dentry);
1127
1128                 if (!list_empty(&dentry->d_ci_conflict_list)) {
1129                         /* Make a different case-insensitively-the-same dentry
1130                          * be the "representative" in the search index. */
1131                         struct list_head *next;
1132                         struct wim_dentry *other;
1133                         struct wim_dentry *existing;
1134
1135                         next = dentry->d_ci_conflict_list.next;
1136                         other = list_entry(next, struct wim_dentry, d_ci_conflict_list);
1137                         existing = dir_index_child_ci(dir, other);
1138                         wimlib_assert(existing == NULL);
1139                 }
1140         }
1141         list_del(&dentry->d_ci_conflict_list);
1142 }
1143
1144 static int
1145 read_extra_data(const u8 *p, const u8 *end, struct wim_inode *inode)
1146 {
1147         while (((uintptr_t)p & 7) && p < end)
1148                 p++;
1149
1150         if (unlikely(p < end)) {
1151                 inode->i_extra = memdup(p, end - p);
1152                 if (!inode->i_extra)
1153                         return WIMLIB_ERR_NOMEM;
1154                 inode->i_extra_size = end - p;
1155         }
1156         return 0;
1157 }
1158
1159 /* Reads a WIM directory entry, including all alternate data stream entries that
1160  * follow it, from the WIM image's metadata resource.  */
1161 static int
1162 read_dentry(const u8 * restrict buf, size_t buf_len,
1163             u64 offset, struct wim_dentry **dentry_ret)
1164 {
1165         u64 length;
1166         const u8 *p;
1167         const struct wim_dentry_on_disk *disk_dentry;
1168         struct wim_dentry *dentry;
1169         struct wim_inode *inode;
1170         u16 short_name_nbytes;
1171         u16 file_name_nbytes;
1172         u64 calculated_size;
1173         int ret;
1174
1175         BUILD_BUG_ON(sizeof(struct wim_dentry_on_disk) != WIM_DENTRY_DISK_SIZE);
1176
1177         /* Before reading the whole dentry, we need to read just the length.
1178          * This is because a dentry of length 8 (that is, just the length field)
1179          * terminates the list of sibling directory entries. */
1180
1181         /* Check for buffer overrun.  */
1182         if (unlikely(offset + sizeof(u64) > buf_len ||
1183                      offset + sizeof(u64) < offset))
1184         {
1185                 ERROR("Directory entry starting at %"PRIu64" ends past the "
1186                       "end of the metadata resource (size %zu)",
1187                       offset, buf_len);
1188                 return WIMLIB_ERR_INVALID_METADATA_RESOURCE;
1189         }
1190
1191         /* Get pointer to the dentry data.  */
1192         p = &buf[offset];
1193         disk_dentry = (const struct wim_dentry_on_disk*)p;
1194
1195         /* Get dentry length.  */
1196         length = le64_to_cpu(disk_dentry->length);
1197
1198         /* Check for end-of-directory.  */
1199         if (length <= 8) {
1200                 *dentry_ret = NULL;
1201                 return 0;
1202         }
1203
1204         /* Validate dentry length.  */
1205         if (unlikely(length < sizeof(struct wim_dentry_on_disk))) {
1206                 ERROR("Directory entry has invalid length of %"PRIu64" bytes",
1207                       length);
1208                 return WIMLIB_ERR_INVALID_METADATA_RESOURCE;
1209         }
1210
1211         /* Check for buffer overrun.  */
1212         if (unlikely(offset + length > buf_len ||
1213                      offset + length < offset))
1214         {
1215                 ERROR("Directory entry at offset %"PRIu64" and with size "
1216                       "%"PRIu64" ends past the end of the metadata resource "
1217                       "(size %zu)", offset, length, buf_len);
1218                 return WIMLIB_ERR_INVALID_METADATA_RESOURCE;
1219         }
1220
1221         /* Allocate new dentry structure, along with a preliminary inode.  */
1222         ret = new_dentry_with_timeless_inode(T(""), &dentry);
1223         if (ret)
1224                 return ret;
1225
1226         dentry->length = length;
1227         inode = dentry->d_inode;
1228
1229         /* Read more fields: some into the dentry, and some into the inode.  */
1230         inode->i_attributes = le32_to_cpu(disk_dentry->attributes);
1231         inode->i_security_id = le32_to_cpu(disk_dentry->security_id);
1232         dentry->subdir_offset = le64_to_cpu(disk_dentry->subdir_offset);
1233         inode->i_creation_time = le64_to_cpu(disk_dentry->creation_time);
1234         inode->i_last_access_time = le64_to_cpu(disk_dentry->last_access_time);
1235         inode->i_last_write_time = le64_to_cpu(disk_dentry->last_write_time);
1236         copy_hash(inode->i_hash, disk_dentry->unnamed_stream_hash);
1237
1238         /* I don't know what's going on here.  It seems like M$ screwed up the
1239          * reparse points, then put the fields in the same place and didn't
1240          * document it.  So we have some fields we read for reparse points, and
1241          * some fields in the same place for non-reparse-points.  */
1242         if (inode->i_attributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1243                 inode->i_rp_unknown_1 = le32_to_cpu(disk_dentry->reparse.rp_unknown_1);
1244                 inode->i_reparse_tag = le32_to_cpu(disk_dentry->reparse.reparse_tag);
1245                 inode->i_rp_unknown_2 = le16_to_cpu(disk_dentry->reparse.rp_unknown_2);
1246                 inode->i_not_rpfixed = le16_to_cpu(disk_dentry->reparse.not_rpfixed);
1247                 /* Leave inode->i_ino at 0.  Note that this means the WIM file
1248                  * cannot archive hard-linked reparse points.  Such a thing
1249                  * doesn't really make sense anyway, although I believe it's
1250                  * theoretically possible to have them on NTFS.  */
1251         } else {
1252                 inode->i_rp_unknown_1 = le32_to_cpu(disk_dentry->nonreparse.rp_unknown_1);
1253                 inode->i_ino = le64_to_cpu(disk_dentry->nonreparse.hard_link_group_id);
1254         }
1255         inode->i_num_ads = le16_to_cpu(disk_dentry->num_alternate_data_streams);
1256
1257         /* Now onto reading the names.  There are two of them: the (long) file
1258          * name, and the short name.  */
1259
1260         short_name_nbytes = le16_to_cpu(disk_dentry->short_name_nbytes);
1261         file_name_nbytes = le16_to_cpu(disk_dentry->file_name_nbytes);
1262
1263         if (unlikely((short_name_nbytes & 1) | (file_name_nbytes & 1))) {
1264                 ERROR("Dentry name is not valid UTF-16 (odd number of bytes)!");
1265                 ret = WIMLIB_ERR_INVALID_METADATA_RESOURCE;
1266                 goto err_free_dentry;
1267         }
1268
1269         /* We now know the length of the file name and short name.  Make sure
1270          * the length of the dentry is large enough to actually hold them.
1271          *
1272          * The calculated length here is unaligned to allow for the possibility
1273          * that the dentry->length names an unaligned length, although this
1274          * would be unexpected.  */
1275         calculated_size = dentry_correct_length_unaligned(file_name_nbytes,
1276                                                           short_name_nbytes);
1277
1278         if (unlikely(dentry->length < calculated_size)) {
1279                 ERROR("Unexpected end of directory entry! (Expected "
1280                       "at least %"PRIu64" bytes, got %"PRIu64" bytes.)",
1281                       calculated_size, dentry->length);
1282                 ret = WIMLIB_ERR_INVALID_METADATA_RESOURCE;
1283                 goto err_free_dentry;
1284         }
1285
1286         /* Advance p to point past the base dentry, to the first name.  */
1287         p += sizeof(struct wim_dentry_on_disk);
1288
1289         /* Read the filename if present.  Note: if the filename is empty, there
1290          * is no null terminator following it.  */
1291         if (file_name_nbytes) {
1292                 dentry->file_name = utf16le_dupz((const utf16lechar *)p,
1293                                                  file_name_nbytes);
1294                 if (dentry->file_name == NULL) {
1295                         ret = WIMLIB_ERR_NOMEM;
1296                         goto err_free_dentry;
1297                 }
1298                 dentry->file_name_nbytes = file_name_nbytes;
1299                 p += file_name_nbytes + 2;
1300         }
1301
1302         /* Read the short filename if present.  Note: if there is no short
1303          * filename, there is no null terminator following it. */
1304         if (short_name_nbytes) {
1305                 dentry->short_name = utf16le_dupz((const utf16lechar *)p,
1306                                                   short_name_nbytes);
1307                 if (dentry->short_name == NULL) {
1308                         ret = WIMLIB_ERR_NOMEM;
1309                         goto err_free_dentry;
1310                 }
1311                 dentry->short_name_nbytes = short_name_nbytes;
1312                 p += short_name_nbytes + 2;
1313         }
1314
1315         /* Read extra data at end of dentry (but before alternate data stream
1316          * entries).  This may contain tagged items.  */
1317         ret = read_extra_data(p, &buf[offset + dentry->length], inode);
1318         if (ret)
1319                 goto err_free_dentry;
1320
1321         /* Align the dentry length.  */
1322         dentry->length = (dentry->length + 7) & ~7;
1323
1324         /* Read the alternate data streams, if present.  inode->i_num_ads tells
1325          * us how many they are, and they will directly follow the dentry in the
1326          * metadata resource buffer.
1327          *
1328          * Note that each alternate data stream entry begins on an 8-byte
1329          * aligned boundary, and the alternate data stream entries seem to NOT
1330          * be included in the dentry->length field for some reason.  */
1331         if (unlikely(inode->i_num_ads != 0)) {
1332                 ret = WIMLIB_ERR_INVALID_METADATA_RESOURCE;
1333                 if (offset + dentry->length > buf_len ||
1334                     (ret = read_ads_entries(&buf[offset + dentry->length],
1335                                             inode,
1336                                             buf_len - offset - dentry->length)))
1337                 {
1338                         goto err_free_dentry;
1339                 }
1340         }
1341
1342         *dentry_ret = dentry;
1343         return 0;
1344
1345 err_free_dentry:
1346         free_dentry(dentry);
1347         return ret;
1348 }
1349
1350 static bool
1351 dentry_is_dot_or_dotdot(const struct wim_dentry *dentry)
1352 {
1353         if (dentry->file_name_nbytes <= 4) {
1354                 if (dentry->file_name_nbytes == 4) {
1355                         if (dentry->file_name[0] == cpu_to_le16('.') &&
1356                             dentry->file_name[1] == cpu_to_le16('.'))
1357                                 return true;
1358                 } else if (dentry->file_name_nbytes == 2) {
1359                         if (dentry->file_name[0] == cpu_to_le16('.'))
1360                                 return true;
1361                 }
1362         }
1363         return false;
1364 }
1365
1366 static int
1367 read_dentry_tree_recursive(const u8 * restrict buf, size_t buf_len,
1368                            struct wim_dentry * restrict dir)
1369 {
1370         u64 cur_offset = dir->subdir_offset;
1371
1372         /* Check for cyclic directory structure, which would cause infinite
1373          * recursion if not handled.  */
1374         for (struct wim_dentry *d = dir->parent;
1375              !dentry_is_root(d); d = d->parent)
1376         {
1377                 if (unlikely(d->subdir_offset == cur_offset)) {
1378                         ERROR("Cyclic directory structure detected: children "
1379                               "of \"%"TS"\" coincide with children of \"%"TS"\"",
1380                               dentry_full_path(dir), dentry_full_path(d));
1381                         return WIMLIB_ERR_INVALID_METADATA_RESOURCE;
1382                 }
1383         }
1384
1385         for (;;) {
1386                 struct wim_dentry *child;
1387                 struct wim_dentry *duplicate;
1388                 int ret;
1389
1390                 /* Read next child of @dir.  */
1391                 ret = read_dentry(buf, buf_len, cur_offset, &child);
1392                 if (ret)
1393                         return ret;
1394
1395                 /* Check for end of directory.  */
1396                 if (child == NULL)
1397                         return 0;
1398
1399                 /* Advance to the offset of the next child.  Note: We need to
1400                  * advance by the TOTAL length of the dentry, not by the length
1401                  * child->length, which although it does take into account the
1402                  * padding, it DOES NOT take into account alternate stream
1403                  * entries.  */
1404                 cur_offset += dentry_in_total_length(child);
1405
1406                 /* All dentries except the root should be named.  */
1407                 if (unlikely(!dentry_has_long_name(child))) {
1408                         WARNING("Ignoring unnamed dentry in "
1409                                 "directory \"%"TS"\"", dentry_full_path(dir));
1410                         free_dentry(child);
1411                         continue;
1412                 }
1413
1414                 /* Don't allow files named "." or "..".  */
1415                 if (unlikely(dentry_is_dot_or_dotdot(child))) {
1416                         WARNING("Ignoring file named \".\" or \"..\"; "
1417                                 "potentially malicious archive!!!");
1418                         free_dentry(child);
1419                         continue;
1420                 }
1421
1422                 /* Link the child into the directory.  */
1423                 duplicate = dentry_add_child(dir, child);
1424                 if (unlikely(duplicate)) {
1425                         /* We already found a dentry with this same
1426                          * case-sensitive long name.  Only keep the first one.
1427                          */
1428                         WARNING("Ignoring duplicate file \"%"TS"\" "
1429                                 "(the WIM image already contains a file "
1430                                 "at that path with the exact same name)",
1431                                 dentry_full_path(duplicate));
1432                         free_dentry(child);
1433                         continue;
1434                 }
1435
1436                 /* If this child is a directory that itself has children, call
1437                  * this procedure recursively.  */
1438                 if (child->subdir_offset != 0) {
1439                         if (likely(dentry_is_directory(child))) {
1440                                 ret = read_dentry_tree_recursive(buf,
1441                                                                  buf_len,
1442                                                                  child);
1443                                 if (ret)
1444                                         return ret;
1445                         } else {
1446                                 WARNING("Ignoring children of "
1447                                         "non-directory file \"%"TS"\"",
1448                                         dentry_full_path(child));
1449                         }
1450                 }
1451         }
1452 }
1453
1454 /*
1455  * Read a tree of dentries (directory entries) from a WIM metadata resource.
1456  *
1457  * @buf:
1458  *      Buffer containing an uncompressed WIM metadata resource.
1459  *
1460  * @buf_len:
1461  *      Length of the uncompressed metadata resource, in bytes.
1462  *
1463  * @root_offset
1464  *      Offset in the metadata resource of the root of the dentry tree.
1465  *
1466  * @root_ret:
1467  *      On success, either NULL or a pointer to the root dentry is written to
1468  *      this location.  The former case only occurs in the unexpected case that
1469  *      the tree began with an end-of-directory entry.
1470  *
1471  * Return values:
1472  *      WIMLIB_ERR_SUCCESS (0)
1473  *      WIMLIB_ERR_INVALID_METADATA_RESOURCE
1474  *      WIMLIB_ERR_NOMEM
1475  */
1476 int
1477 read_dentry_tree(const u8 *buf, size_t buf_len,
1478                  u64 root_offset, struct wim_dentry **root_ret)
1479 {
1480         int ret;
1481         struct wim_dentry *root;
1482
1483         DEBUG("Reading dentry tree (root_offset=%"PRIu64")", root_offset);
1484
1485         ret = read_dentry(buf, buf_len, root_offset, &root);
1486         if (ret)
1487                 return ret;
1488
1489         if (likely(root != NULL)) {
1490                 if (unlikely(dentry_has_long_name(root) ||
1491                              dentry_has_short_name(root)))
1492                 {
1493                         WARNING("The root directory has a nonempty name; "
1494                                 "removing it.");
1495                         FREE(root->file_name);
1496                         FREE(root->short_name);
1497                         root->file_name = NULL;
1498                         root->short_name = NULL;
1499                         root->file_name_nbytes = 0;
1500                         root->short_name_nbytes = 0;
1501                 }
1502
1503                 if (unlikely(!dentry_is_directory(root))) {
1504                         ERROR("The root of the WIM image is not a directory!");
1505                         ret = WIMLIB_ERR_INVALID_METADATA_RESOURCE;
1506                         goto err_free_dentry_tree;
1507                 }
1508
1509                 if (likely(root->subdir_offset != 0)) {
1510                         ret = read_dentry_tree_recursive(buf, buf_len, root);
1511                         if (ret)
1512                                 goto err_free_dentry_tree;
1513                 }
1514         } else {
1515                 WARNING("The metadata resource has no directory entries; "
1516                         "treating as an empty image.");
1517         }
1518         *root_ret = root;
1519         return 0;
1520
1521 err_free_dentry_tree:
1522         free_dentry_tree(root, NULL);
1523         return ret;
1524 }
1525
1526 /*
1527  * Writes a WIM alternate data stream (ADS) entry to an output buffer.
1528  *
1529  * @ads_entry:  The ADS entry structure.
1530  * @hash:       The hash field to use (instead of the one in the ADS entry).
1531  * @p:          The memory location to write the data to.
1532  *
1533  * Returns a pointer to the byte after the last byte written.
1534  */
1535 static u8 *
1536 write_ads_entry(const struct wim_ads_entry *ads_entry,
1537                 const u8 *hash, u8 * restrict p)
1538 {
1539         struct wim_ads_entry_on_disk *disk_ads_entry =
1540                         (struct wim_ads_entry_on_disk*)p;
1541         u8 *orig_p = p;
1542
1543         disk_ads_entry->reserved = cpu_to_le64(ads_entry->reserved);
1544         copy_hash(disk_ads_entry->hash, hash);
1545         disk_ads_entry->stream_name_nbytes = cpu_to_le16(ads_entry->stream_name_nbytes);
1546         p += sizeof(struct wim_ads_entry_on_disk);
1547         if (ads_entry->stream_name_nbytes) {
1548                 p = mempcpy(p, ads_entry->stream_name,
1549                             ads_entry->stream_name_nbytes + 2);
1550         }
1551         /* Align to 8-byte boundary */
1552         while ((uintptr_t)p & 7)
1553                 *p++ = 0;
1554         disk_ads_entry->length = cpu_to_le64(p - orig_p);
1555         return p;
1556 }
1557
1558 /*
1559  * Writes a WIM dentry to an output buffer.
1560  *
1561  * @dentry:  The dentry structure.
1562  * @p:       The memory location to write the data to.
1563  *
1564  * Returns the pointer to the byte after the last byte we wrote as part of the
1565  * dentry, including any alternate data stream entries.
1566  */
1567 static u8 *
1568 write_dentry(const struct wim_dentry * restrict dentry, u8 * restrict p)
1569 {
1570         const struct wim_inode *inode;
1571         struct wim_dentry_on_disk *disk_dentry;
1572         const u8 *orig_p;
1573         const u8 *hash;
1574         bool use_dummy_stream;
1575         u16 num_ads;
1576
1577         wimlib_assert(((uintptr_t)p & 7) == 0); /* 8 byte aligned */
1578         orig_p = p;
1579
1580         inode = dentry->d_inode;
1581         use_dummy_stream = inode_needs_dummy_stream(inode);
1582         disk_dentry = (struct wim_dentry_on_disk*)p;
1583
1584         disk_dentry->attributes = cpu_to_le32(inode->i_attributes);
1585         disk_dentry->security_id = cpu_to_le32(inode->i_security_id);
1586         disk_dentry->subdir_offset = cpu_to_le64(dentry->subdir_offset);
1587
1588         /* UNIX data uses the two 8-byte reserved fields.  So if no UNIX data
1589          * exists, they get set to 0, just as we would do anyway.  */
1590         disk_dentry->unused_1 = cpu_to_le64(0);
1591         disk_dentry->unused_2 = cpu_to_le64(0);
1592
1593         disk_dentry->creation_time = cpu_to_le64(inode->i_creation_time);
1594         disk_dentry->last_access_time = cpu_to_le64(inode->i_last_access_time);
1595         disk_dentry->last_write_time = cpu_to_le64(inode->i_last_write_time);
1596         if (use_dummy_stream)
1597                 hash = zero_hash;
1598         else
1599                 hash = inode_stream_hash(inode, 0);
1600         copy_hash(disk_dentry->unnamed_stream_hash, hash);
1601         if (inode->i_attributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1602                 disk_dentry->reparse.rp_unknown_1 = cpu_to_le32(inode->i_rp_unknown_1);
1603                 disk_dentry->reparse.reparse_tag = cpu_to_le32(inode->i_reparse_tag);
1604                 disk_dentry->reparse.rp_unknown_2 = cpu_to_le16(inode->i_rp_unknown_2);
1605                 disk_dentry->reparse.not_rpfixed = cpu_to_le16(inode->i_not_rpfixed);
1606         } else {
1607                 disk_dentry->nonreparse.rp_unknown_1 = cpu_to_le32(inode->i_rp_unknown_1);
1608                 disk_dentry->nonreparse.hard_link_group_id =
1609                         cpu_to_le64((inode->i_nlink == 1) ? 0 : inode->i_ino);
1610         }
1611         num_ads = inode->i_num_ads;
1612         if (use_dummy_stream)
1613                 num_ads++;
1614         disk_dentry->num_alternate_data_streams = cpu_to_le16(num_ads);
1615         disk_dentry->short_name_nbytes = cpu_to_le16(dentry->short_name_nbytes);
1616         disk_dentry->file_name_nbytes = cpu_to_le16(dentry->file_name_nbytes);
1617         p += sizeof(struct wim_dentry_on_disk);
1618
1619         wimlib_assert(dentry_is_root(dentry) != dentry_has_long_name(dentry));
1620
1621         if (dentry_has_long_name(dentry))
1622                 p = mempcpy(p, dentry->file_name, dentry->file_name_nbytes + 2);
1623
1624         if (dentry_has_short_name(dentry))
1625                 p = mempcpy(p, dentry->short_name, dentry->short_name_nbytes + 2);
1626
1627         /* Align to 8-byte boundary */
1628         while ((uintptr_t)p & 7)
1629                 *p++ = 0;
1630
1631         if (inode->i_extra_size) {
1632                 /* Extra tagged items --- not usually present.  */
1633                 p = mempcpy(p, inode->i_extra, inode->i_extra_size);
1634                 while ((uintptr_t)p & 7)
1635                         *p++ = 0;
1636         }
1637
1638         disk_dentry->length = cpu_to_le64(p - orig_p);
1639
1640         if (use_dummy_stream) {
1641                 hash = inode_unnamed_stream_hash(inode);
1642                 p = write_ads_entry(&(struct wim_ads_entry){}, hash, p);
1643         }
1644
1645         /* Write the alternate data streams entries, if any. */
1646         for (u16 i = 0; i < inode->i_num_ads; i++) {
1647                 hash = inode_stream_hash(inode, i + 1);
1648                 p = write_ads_entry(&inode->i_ads_entries[i], hash, p);
1649         }
1650
1651         return p;
1652 }
1653
1654 static int
1655 write_dir_dentries(struct wim_dentry *dir, void *_pp)
1656 {
1657         if (dir->subdir_offset != 0) {
1658                 u8 **pp = _pp;
1659                 u8 *p = *pp;
1660                 struct wim_dentry *child;
1661
1662                 /* write child dentries */
1663                 for_dentry_child(child, dir)
1664                         p = write_dentry(child, p);
1665
1666                 /* write end of directory entry */
1667                 *(u64*)p = 0;
1668                 p += 8;
1669                 *pp = p;
1670         }
1671         return 0;
1672 }
1673
1674 /* Writes a directory tree to the metadata resource.
1675  *
1676  * @root:       Root of the dentry tree.
1677  * @p:          Pointer to a buffer with enough space for the dentry tree.
1678  *
1679  * Returns pointer to the byte after the last byte we wrote.
1680  */
1681 u8 *
1682 write_dentry_tree(struct wim_dentry *root, u8 *p)
1683 {
1684         DEBUG("Writing dentry tree.");
1685         wimlib_assert(dentry_is_root(root));
1686
1687         /* write root dentry and end-of-directory entry following it */
1688         p = write_dentry(root, p);
1689         *(u64*)p = 0;
1690         p += 8;
1691
1692         /* write the rest of the dentry tree */
1693         for_dentry_in_tree(root, write_dir_dentries, &p);
1694
1695         return p;
1696 }