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