6 * Copyright (C) 2012, 2013 Eric Biggers
8 * This file is part of wimlib, a library for working with WIM files.
10 * wimlib is free software; you can redistribute it and/or modify it under the
11 * terms of the GNU General Public License as published by the Free
12 * Software Foundation; either version 3 of the License, or (at your option)
15 * wimlib is distributed in the hope that it will be useful, but WITHOUT ANY
16 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
17 * A PARTICULAR PURPOSE. See the GNU General Public License for more
20 * You should have received a copy of the GNU General Public License
21 * along with wimlib; if not, see http://www.gnu.org/licenses/.
28 #include "wimlib/assert.h"
29 #include "wimlib/case.h"
30 #include "wimlib/dentry.h" /* Only for dentry_full_path(). Otherwise the code
31 in this file doesn't care about file names/paths.
33 #include "wimlib/encoding.h"
34 #include "wimlib/endianness.h"
35 #include "wimlib/error.h"
36 #include "wimlib/inode.h"
37 #include "wimlib/inode_table.h"
38 #include "wimlib/lookup_table.h"
39 #include "wimlib/security.h"
40 #include "wimlib/timestamp.h"
42 /* Allocate a new inode. Set the timestamps to the current time. */
46 struct wim_inode *inode = new_timeless_inode();
48 u64 now = get_wim_timestamp();
49 inode->i_creation_time = now;
50 inode->i_last_access_time = now;
51 inode->i_last_write_time = now;
57 /* Allocate a new inode. Leave the timestamps zeroed out. */
59 new_timeless_inode(void)
61 struct wim_inode *inode = CALLOC(1, sizeof(struct wim_inode));
63 inode->i_security_id = -1;
65 inode->i_next_stream_id = 1;
66 inode->i_not_rpfixed = 1;
67 inode->i_canonical_streams = 1;
68 INIT_LIST_HEAD(&inode->i_list);
69 INIT_LIST_HEAD(&inode->i_dentry);
74 /* Decrement link count on an inode. */
76 put_inode(struct wim_inode *inode)
78 wimlib_assert(inode->i_nlink != 0);
79 if (--inode->i_nlink == 0) {
80 /* If FUSE mounts are enabled, we must keep a unlinked inode
81 * around until all file descriptors to it have been closed.
82 * inode_put_fd() in mount_image.c handles dropping a file
85 if (inode->i_num_opened_fds == 0)
91 /* De-allocate memory for an alternate data stream entry. */
93 destroy_ads_entry(struct wim_ads_entry *ads_entry)
95 FREE(ads_entry->stream_name);
98 /* Free an inode. Only use this if there can't be other links to the inode or
99 * if it doesn't matter if there are. */
101 free_inode(struct wim_inode *inode)
106 if (inode->i_ads_entries) {
107 for (u16 i = 0; i < inode->i_num_ads; i++)
108 destroy_ads_entry(&inode->i_ads_entries[i]);
109 FREE(inode->i_ads_entries);
111 /* HACK: This may instead delete the inode from i_list, but hlist_del()
112 * behaves the same as list_del(). */
113 if (!hlist_unhashed(&inode->i_hlist))
114 hlist_del(&inode->i_hlist);
118 /* Return %true iff the alternate data stream entry @entry has the UTF-16LE
119 * stream name @name that has length @name_nbytes bytes. */
121 ads_entry_has_name(const struct wim_ads_entry *entry,
122 const utf16lechar *name, size_t name_nbytes,
125 return 0 == cmp_utf16le_strings(name,
128 entry->stream_name_nbytes / 2,
133 * Returns the alternate data stream entry belonging to @inode that has the
134 * stream name @stream_name, or NULL if the inode has no alternate data stream
137 * If @p stream_name is the empty string, NULL is returned --- that is, this
138 * function will not return "unnamed" alternate data stream entries.
140 struct wim_ads_entry *
141 inode_get_ads_entry(struct wim_inode *inode, const tchar *stream_name,
144 if (inode->i_num_ads == 0) {
147 size_t stream_name_utf16le_nbytes;
149 struct wim_ads_entry *result;
151 if (stream_name[0] == T('\0'))
155 const utf16lechar *stream_name_utf16le;
157 stream_name_utf16le = stream_name;
158 stream_name_utf16le_nbytes = tstrlen(stream_name) * sizeof(tchar);
160 utf16lechar *stream_name_utf16le;
163 int ret = tstr_to_utf16le(stream_name,
164 tstrlen(stream_name) *
166 &stream_name_utf16le,
167 &stream_name_utf16le_nbytes);
175 if (ads_entry_has_name(&inode->i_ads_entries[i],
177 stream_name_utf16le_nbytes,
178 default_ignore_case))
182 result = &inode->i_ads_entries[i];
185 } while (++i != inode->i_num_ads);
186 #if !TCHAR_IS_UTF16LE
187 FREE(stream_name_utf16le);
194 init_ads_entry(struct wim_ads_entry *ads_entry, const void *name,
195 size_t name_nbytes, bool is_utf16le)
198 memset(ads_entry, 0, sizeof(*ads_entry));
201 utf16lechar *p = MALLOC(name_nbytes + sizeof(utf16lechar));
203 return WIMLIB_ERR_NOMEM;
204 memcpy(p, name, name_nbytes);
205 p[name_nbytes / 2] = cpu_to_le16(0);
206 ads_entry->stream_name = p;
207 ads_entry->stream_name_nbytes = name_nbytes;
209 if (name && *(const tchar*)name != T('\0')) {
210 ret = get_utf16le_string(name, &ads_entry->stream_name,
211 &ads_entry->stream_name_nbytes);
217 static struct wim_ads_entry *
218 do_inode_add_ads(struct wim_inode *inode, const void *stream_name,
219 size_t stream_name_nbytes, bool is_utf16le)
222 struct wim_ads_entry *ads_entries;
223 struct wim_ads_entry *new_entry;
225 wimlib_assert(stream_name_nbytes != 0);
227 if (inode->i_num_ads >= 0xfffe) {
228 ERROR("Too many alternate data streams in one inode!");
231 num_ads = inode->i_num_ads + 1;
232 ads_entries = REALLOC(inode->i_ads_entries,
233 num_ads * sizeof(inode->i_ads_entries[0]));
234 if (ads_entries == NULL) {
235 ERROR("Failed to allocate memory for new alternate data stream");
238 inode->i_ads_entries = ads_entries;
240 new_entry = &inode->i_ads_entries[num_ads - 1];
241 if (init_ads_entry(new_entry, stream_name, stream_name_nbytes, is_utf16le))
243 new_entry->stream_id = inode->i_next_stream_id++;
244 inode->i_num_ads = num_ads;
248 struct wim_ads_entry *
249 inode_add_ads_utf16le(struct wim_inode *inode,
250 const utf16lechar *stream_name,
251 size_t stream_name_nbytes)
253 DEBUG("Add alternate data stream \"%"WS"\"", stream_name);
254 return do_inode_add_ads(inode, stream_name, stream_name_nbytes, true);
258 * Add an alternate stream entry to a WIM inode. On success, returns a pointer
259 * to the new entry; on failure, returns NULL.
261 * @stream_name must be a nonempty string.
263 struct wim_ads_entry *
264 inode_add_ads(struct wim_inode *inode, const tchar *stream_name)
266 DEBUG("Add alternate data stream \"%"TS"\"", stream_name);
267 return do_inode_add_ads(inode, stream_name,
268 tstrlen(stream_name) * sizeof(tchar),
273 inode_add_ads_with_data(struct wim_inode *inode, const tchar *name,
274 const void *value, size_t size,
275 struct wim_lookup_table *lookup_table)
277 struct wim_ads_entry *new_ads_entry;
279 wimlib_assert(inode->i_resolved);
281 new_ads_entry = inode_add_ads(inode, name);
282 if (new_ads_entry == NULL)
283 return WIMLIB_ERR_NOMEM;
285 new_ads_entry->lte = new_stream_from_data_buffer(value, size,
287 if (new_ads_entry->lte == NULL) {
288 inode_remove_ads(inode, new_ads_entry - inode->i_ads_entries,
290 return WIMLIB_ERR_NOMEM;
296 inode_has_named_stream(const struct wim_inode *inode)
298 for (u16 i = 0; i < inode->i_num_ads; i++)
299 if (ads_entry_is_named_stream(&inode->i_ads_entries[i]))
304 /* Set the unnamed stream of a WIM inode, given a data buffer containing the
305 * stream contents. */
307 inode_set_unnamed_stream(struct wim_inode *inode, const void *data, size_t len,
308 struct wim_lookup_table *lookup_table)
310 inode->i_lte = new_stream_from_data_buffer(data, len, lookup_table);
311 if (inode->i_lte == NULL)
312 return WIMLIB_ERR_NOMEM;
313 inode->i_resolved = 1;
317 /* Remove an alternate data stream from a WIM inode */
319 inode_remove_ads(struct wim_inode *inode, u16 idx,
320 struct wim_lookup_table *lookup_table)
322 struct wim_ads_entry *ads_entry;
323 struct wim_lookup_table_entry *lte;
325 wimlib_assert(idx < inode->i_num_ads);
326 wimlib_assert(inode->i_resolved);
328 ads_entry = &inode->i_ads_entries[idx];
330 DEBUG("Remove alternate data stream \"%"WS"\"", ads_entry->stream_name);
332 lte = ads_entry->lte;
334 lte_decrement_refcnt(lte, lookup_table);
336 destroy_ads_entry(ads_entry);
338 memmove(&inode->i_ads_entries[idx],
339 &inode->i_ads_entries[idx + 1],
340 (inode->i_num_ads - idx - 1) * sizeof(inode->i_ads_entries[0]));
345 inode_has_unix_data(const struct wim_inode *inode)
347 for (u16 i = 0; i < inode->i_num_ads; i++)
348 if (ads_entry_is_unix_data(&inode->i_ads_entries[i]))
355 inode_get_unix_data(const struct wim_inode *inode,
356 struct wimlib_unix_data *unix_data,
359 const struct wim_ads_entry *ads_entry;
360 const struct wim_lookup_table_entry *lte;
364 wimlib_assert(inode->i_resolved);
366 ads_entry = inode_get_ads_entry((struct wim_inode*)inode,
367 WIMLIB_UNIX_DATA_TAG, NULL);
368 if (ads_entry == NULL)
372 *stream_idx_ret = ads_entry - inode->i_ads_entries;
374 lte = ads_entry->lte;
379 if (size != sizeof(struct wimlib_unix_data))
380 return BAD_UNIX_DATA;
382 ret = read_full_stream_into_buf(lte, unix_data);
386 if (unix_data->version != 0)
387 return BAD_UNIX_DATA;
392 inode_set_unix_data(struct wim_inode *inode, u16 uid, u16 gid, u16 mode,
393 struct wim_lookup_table *lookup_table, int which)
395 struct wimlib_unix_data unix_data;
397 bool have_good_unix_data = false;
398 bool have_unix_data = false;
401 if (!(which & UNIX_DATA_CREATE)) {
402 ret = inode_get_unix_data(inode, &unix_data, &stream_idx);
403 if (ret == 0 || ret == BAD_UNIX_DATA || ret > 0)
404 have_unix_data = true;
406 have_good_unix_data = true;
408 unix_data.version = 0;
409 if (which & UNIX_DATA_UID || !have_good_unix_data)
411 if (which & UNIX_DATA_GID || !have_good_unix_data)
413 if (which & UNIX_DATA_MODE || !have_good_unix_data)
414 unix_data.mode = mode;
415 ret = inode_add_ads_with_data(inode, WIMLIB_UNIX_DATA_TAG,
417 sizeof(struct wimlib_unix_data),
419 if (ret == 0 && have_unix_data)
420 inode_remove_ads(inode, stream_idx, lookup_table);
423 #endif /* __WIN32__ */
426 * Resolve an inode's lookup table entries.
428 * This replaces the SHA1 hash fields (which are used to lookup an entry in the
429 * lookup table) with pointers directly to the lookup table entries.
431 * If @force is %false:
432 * If any needed SHA1 message digests are not found in the lookup table,
433 * WIMLIB_ERR_RESOURCE_NOT_FOUND is returned and the inode is left
435 * If @force is %true:
436 * If any needed SHA1 message digests are not found in the lookup table,
437 * new entries are allocated and inserted into the lookup table.
440 inode_resolve_streams(struct wim_inode *inode, struct wim_lookup_table *table,
445 if (!inode->i_resolved) {
446 struct wim_lookup_table_entry *lte, *ads_lte;
448 /* Resolve the default file stream */
450 hash = inode->i_hash;
451 if (!is_zero_hash(hash)) {
452 lte = lookup_stream(table, hash);
455 lte = new_lookup_table_entry();
457 return WIMLIB_ERR_NOMEM;
458 copy_hash(lte->hash, hash);
459 lookup_table_insert(table, lte);
461 goto stream_not_found;
466 /* Resolve the alternate data streams */
467 struct wim_lookup_table_entry *ads_ltes[inode->i_num_ads];
468 for (u16 i = 0; i < inode->i_num_ads; i++) {
469 struct wim_ads_entry *cur_entry;
472 cur_entry = &inode->i_ads_entries[i];
473 hash = cur_entry->hash;
474 if (!is_zero_hash(hash)) {
475 ads_lte = lookup_stream(table, hash);
478 ads_lte = new_lookup_table_entry();
480 return WIMLIB_ERR_NOMEM;
481 copy_hash(ads_lte->hash, hash);
482 lookup_table_insert(table, ads_lte);
484 goto stream_not_found;
488 ads_ltes[i] = ads_lte;
491 for (u16 i = 0; i < inode->i_num_ads; i++)
492 inode->i_ads_entries[i].lte = ads_ltes[i];
493 inode->i_resolved = 1;
498 return stream_not_found_error(inode, hash);
502 inode_unresolve_streams(struct wim_inode *inode)
504 if (inode->i_resolved) {
506 copy_hash(inode->i_hash, inode->i_lte->hash);
508 zero_out_hash(inode->i_hash);
510 for (u16 i = 0; i < inode->i_num_ads; i++) {
511 if (inode->i_ads_entries[i].lte)
512 copy_hash(inode->i_ads_entries[i].hash,
513 inode->i_ads_entries[i].lte->hash);
515 zero_out_hash(inode->i_ads_entries[i].hash);
517 inode->i_resolved = 0;
522 * Returns the lookup table entry for stream @stream_idx of the inode, where
523 * stream_idx = 0 means the default un-named file stream, and stream_idx >= 1
524 * corresponds to an alternate data stream.
526 * This works for both resolved and un-resolved inodes.
528 struct wim_lookup_table_entry *
529 inode_stream_lte(const struct wim_inode *inode, unsigned stream_idx,
530 const struct wim_lookup_table *table)
532 if (inode->i_resolved)
533 return inode_stream_lte_resolved(inode, stream_idx);
535 return inode_stream_lte_unresolved(inode, stream_idx, table);
538 struct wim_lookup_table_entry *
539 inode_unnamed_stream_resolved(const struct wim_inode *inode, u16 *stream_idx_ret)
541 wimlib_assert(inode->i_resolved);
542 for (unsigned i = 0; i <= inode->i_num_ads; i++) {
543 if (inode_stream_name_nbytes(inode, i) == 0 &&
544 !is_zero_hash(inode_stream_hash_resolved(inode, i)))
547 return inode_stream_lte_resolved(inode, i);
554 struct wim_lookup_table_entry *
555 inode_unnamed_lte_resolved(const struct wim_inode *inode)
558 return inode_unnamed_stream_resolved(inode, &stream_idx);
561 struct wim_lookup_table_entry *
562 inode_unnamed_lte_unresolved(const struct wim_inode *inode,
563 const struct wim_lookup_table *table)
565 wimlib_assert(!inode->i_resolved);
566 for (unsigned i = 0; i <= inode->i_num_ads; i++) {
567 if (inode_stream_name_nbytes(inode, i) == 0 &&
568 !is_zero_hash(inode_stream_hash_unresolved(inode, i)))
570 return inode_stream_lte_unresolved(inode, i, table);
576 /* Return the lookup table entry for the unnamed data stream of an inode, or
577 * NULL if there is none.
579 * You'd think this would be easier than it actually is, since the unnamed data
580 * stream should be the one referenced from the inode itself. Alas, if there
581 * are named data streams, Microsoft's "imagex.exe" program will put the unnamed
582 * data stream in one of the alternate data streams instead of inside the WIM
583 * dentry itself. So we need to check the alternate data streams too.
585 * Also, note that a dentry may appear to have more than one unnamed stream, but
586 * if the SHA1 message digest is all 0's then the corresponding stream does not
587 * really "count" (this is the case for the inode's own file stream when the
588 * file stream that should be there is actually in one of the alternate stream
589 * entries.). This is despite the fact that we may need to extract such a
590 * missing entry as an empty file or empty named data stream.
592 struct wim_lookup_table_entry *
593 inode_unnamed_lte(const struct wim_inode *inode,
594 const struct wim_lookup_table *table)
596 if (inode->i_resolved)
597 return inode_unnamed_lte_resolved(inode);
599 return inode_unnamed_lte_unresolved(inode, table);
602 /* Returns the SHA1 message digest of the unnamed data stream of a WIM inode, or
603 * 'zero_hash' if the unnamed data stream is missing has all zeroes in its SHA1
604 * message digest field. */
606 inode_unnamed_stream_hash(const struct wim_inode *inode)
610 for (unsigned i = 0; i <= inode->i_num_ads; i++) {
611 if (inode_stream_name_nbytes(inode, i) == 0) {
612 hash = inode_stream_hash(inode, i);
613 if (!is_zero_hash(hash))
620 /* Given an unhashed stream, get the pointer to it in an inode.
621 * As this is only for unhashed streams, there can only be one such pointer. */
622 struct wim_lookup_table_entry **
623 retrieve_lte_pointer(struct wim_lookup_table_entry *lte)
625 wimlib_assert(lte->unhashed);
626 struct wim_inode *inode = lte->back_inode;
627 u32 stream_id = lte->back_stream_id;
629 return &inode->i_lte;
631 for (u16 i = 0; i < inode->i_num_ads; i++)
632 if (inode->i_ads_entries[i].stream_id == stream_id)
633 return &inode->i_ads_entries[i].lte;
639 stream_not_found_error(const struct wim_inode *inode, const u8 *hash)
641 if (wimlib_print_errors) {
642 ERROR("\"%"TS"\": stream not found", inode_first_full_path(inode));
643 tfprintf(stderr, T(" SHA-1 message digest of missing stream:\n "));
644 print_hash(hash, stderr);
645 tputc(T('\n'), stderr);
647 return WIMLIB_ERR_RESOURCE_NOT_FOUND;
651 * Reads the alternate data stream entries of a WIM dentry.
654 * Pointer to buffer that starts with the first alternate stream entry.
657 * Inode to load the alternate data streams into. @inode->i_num_ads must
658 * have been set to the number of alternate data streams that are expected.
661 * Number of bytes of data remaining in the buffer pointed to by @p.
663 * On success, inode->i_ads_entries is set to an array of `struct
664 * wim_ads_entry's of length inode->i_num_ads. On failure, @inode is not
668 * WIMLIB_ERR_SUCCESS (0)
669 * WIMLIB_ERR_INVALID_METADATA_RESOURCE
673 read_ads_entries(const u8 * restrict p, struct wim_inode * restrict inode,
674 size_t nbytes_remaining)
677 struct wim_ads_entry *ads_entries;
680 BUILD_BUG_ON(sizeof(struct wim_ads_entry_on_disk) != WIM_ADS_ENTRY_DISK_SIZE);
682 /* Allocate an array for our in-memory representation of the alternate
683 * data stream entries. */
684 num_ads = inode->i_num_ads;
685 ads_entries = CALLOC(num_ads, sizeof(inode->i_ads_entries[0]));
686 if (ads_entries == NULL)
689 /* Read the entries into our newly allocated buffer. */
690 for (u16 i = 0; i < num_ads; i++) {
692 struct wim_ads_entry *cur_entry;
693 const struct wim_ads_entry_on_disk *disk_entry =
694 (const struct wim_ads_entry_on_disk*)p;
696 cur_entry = &ads_entries[i];
697 ads_entries[i].stream_id = i + 1;
699 /* Do we have at least the size of the fixed-length data we know
701 if (nbytes_remaining < sizeof(struct wim_ads_entry_on_disk))
704 /* Read the length field */
705 length = le64_to_cpu(disk_entry->length);
707 /* Make sure the length field is neither so small it doesn't
708 * include all the fixed-length data nor so large it overflows
709 * the metadata resource buffer. */
710 if (length < sizeof(struct wim_ads_entry_on_disk) ||
711 length > nbytes_remaining)
714 /* Read the rest of the fixed-length data. */
716 cur_entry->reserved = le64_to_cpu(disk_entry->reserved);
717 copy_hash(cur_entry->hash, disk_entry->hash);
718 cur_entry->stream_name_nbytes = le16_to_cpu(disk_entry->stream_name_nbytes);
720 /* If stream_name_nbytes != 0, this is a named stream.
721 * Otherwise this is an unnamed stream, or in some cases (bugs
722 * in Microsoft's software I guess) a meaningless entry
723 * distinguished from the real unnamed stream entry, if any, by
724 * the fact that the real unnamed stream entry has a nonzero
726 if (cur_entry->stream_name_nbytes) {
727 /* The name is encoded in UTF16-LE, which uses 2-byte
728 * coding units, so the length of the name had better be
729 * an even number of bytes... */
730 if (cur_entry->stream_name_nbytes & 1)
733 /* Add the length of the stream name to get the length
734 * we actually need to read. Make sure this isn't more
735 * than the specified length of the entry. */
736 if (sizeof(struct wim_ads_entry_on_disk) +
737 cur_entry->stream_name_nbytes > length)
740 cur_entry->stream_name = MALLOC(cur_entry->stream_name_nbytes + 2);
741 if (cur_entry->stream_name == NULL)
744 memcpy(cur_entry->stream_name,
745 disk_entry->stream_name,
746 cur_entry->stream_name_nbytes);
747 cur_entry->stream_name[cur_entry->stream_name_nbytes / 2] = cpu_to_le16(0);
749 /* Mark inode as having weird stream entries. */
750 inode->i_canonical_streams = 0;
753 /* It's expected that the size of every ADS entry is a multiple
754 * of 8. However, to be safe, I'm allowing the possibility of
755 * an ADS entry at the very end of the metadata resource ending
756 * un-aligned. So although we still need to increment the input
757 * pointer by @length to reach the next ADS entry, it's possible
758 * that less than @length is actually remaining in the metadata
759 * resource. We should set the remaining bytes to 0 if this
761 length = (length + 7) & ~(u64)7;
763 if (nbytes_remaining < length)
764 nbytes_remaining = 0;
766 nbytes_remaining -= length;
768 inode->i_ads_entries = ads_entries;
769 inode->i_next_stream_id = inode->i_num_ads + 1;
773 ret = WIMLIB_ERR_NOMEM;
774 goto out_free_ads_entries;
776 ERROR("An alternate data stream entry is invalid");
777 ret = WIMLIB_ERR_INVALID_METADATA_RESOURCE;
778 out_free_ads_entries:
780 for (u16 i = 0; i < num_ads; i++)
781 destroy_ads_entry(&ads_entries[i]);
789 * Verify a WIM inode:
791 * - Check to make sure the security ID is valid
792 * - Check to make sure there is at most one unnamed stream
793 * - Check to make sure there is at most one DOS name.
796 * WIMLIB_ERR_SUCCESS (0)
799 verify_inode(struct wim_inode *inode, const struct wim_security_data *sd)
801 struct wim_dentry *dentry;
803 /* Check the security ID. -1 is valid and means "no security
804 * descriptor". Anything else has to be a valid index into the WIM
805 * image's security descriptors table. */
806 if (inode->i_security_id < -1 ||
807 (inode->i_security_id >= 0 &&
808 inode->i_security_id >= sd->num_entries))
810 WARNING("\"%"TS"\" has an invalid security ID (%d)",
811 inode_first_full_path(inode), inode->i_security_id);
812 inode->i_security_id = -1;
815 /* Make sure there is only one unnamed data stream. */
816 unsigned num_unnamed_streams = 0;
817 for (unsigned i = 0; i <= inode->i_num_ads; i++) {
819 hash = inode_stream_hash(inode, i);
820 if (inode_stream_name_nbytes(inode, i) == 0 && !is_zero_hash(hash))
821 num_unnamed_streams++;
823 if (num_unnamed_streams > 1) {
824 WARNING("\"%"TS"\" has multiple (%u) un-named streams",
825 inode_first_full_path(inode), num_unnamed_streams);
828 /* Files cannot have multiple DOS names, even if they have multiple
829 * names in multiple directories (i.e. hard links).
830 * Source: NTFS-3g authors. */
831 struct wim_dentry *dentry_with_dos_name = NULL;
832 inode_for_each_dentry(dentry, inode) {
833 if (dentry_has_short_name(dentry)) {
834 if (dentry_with_dos_name) {
835 /* This was previously an error, but if we
836 * capture a WIM from UDF on Windows, hard links
837 * are supported but DOS names are automatically
838 * generated for all names for an inode. */
840 ERROR("Hard-linked file has a DOS name at "
841 "both `%"TS"' and `%"TS"'",
842 dentry_full_path(dentry_with_dos_name),
843 dentry_full_path(dentry));
844 return WIMLIB_ERR_INVALID_METADATA_RESOURCE;
846 dentry->dos_name_invalid = 1;
849 dentry_with_dos_name = dentry;
856 inode_ref_streams(struct wim_inode *inode)
858 for (unsigned i = 0; i <= inode->i_num_ads; i++) {
859 struct wim_lookup_table_entry *lte;
860 lte = inode_stream_lte_resolved(inode, i);
867 init_inode_table(struct wim_inode_table *table, size_t capacity)
869 table->array = CALLOC(capacity, sizeof(table->array[0]));
870 if (table->array == NULL) {
871 ERROR("Cannot initalize inode table: out of memory");
872 return WIMLIB_ERR_NOMEM;
874 table->num_entries = 0;
875 table->capacity = capacity;
876 INIT_LIST_HEAD(&table->extra_inodes);
881 destroy_inode_table(struct wim_inode_table *table)
886 static struct wim_inode *
887 inode_table_get_inode(struct wim_inode_table *table, u64 ino, u64 devno)
889 u64 hash = hash_u64(hash_u64(ino) + hash_u64(devno));
890 size_t pos = hash % table->capacity;
891 struct wim_inode *inode;
892 struct hlist_node *cur;
894 hlist_for_each_entry(inode, cur, &table->array[pos], i_hlist) {
895 if (inode->i_ino == ino && inode->i_devno == devno) {
896 DEBUG("Using existing inode {devno=%"PRIu64", ino=%"PRIu64"}",
902 inode = new_timeless_inode();
905 inode->i_devno = devno;
906 hlist_add_head(&inode->i_hlist, &table->array[pos]);
907 table->num_entries++;
913 /* Given a directory entry with the name @name for the file with the inode
914 * number @ino and device number @devno, create a new WIM dentry with an
915 * associated inode, where the inode is shared if an inode with the same @ino
916 * and @devno has already been created. On success, the new WIM dentry is
917 * written to *dentry_ret, and its inode has i_nlink > 1 if a previously
918 * existing inode was used.
921 inode_table_new_dentry(struct wim_inode_table *table, const tchar *name,
922 u64 ino, u64 devno, bool noshare,
923 struct wim_dentry **dentry_ret)
925 struct wim_dentry *dentry;
926 struct wim_inode *inode;
930 /* File that cannot be hardlinked--- Return a new inode with its
931 * inode and device numbers left at 0. */
932 ret = new_dentry_with_timeless_inode(name, &dentry);
935 list_add_tail(&dentry->d_inode->i_list, &table->extra_inodes);
937 /* File that can be hardlinked--- search the table for an
938 * existing inode matching the inode number and device;
939 * otherwise create a new inode. */
940 ret = new_dentry(name, &dentry);
943 inode = inode_table_get_inode(table, ino, devno);
946 return WIMLIB_ERR_NOMEM;
948 /* If using an existing inode, we need to gain a reference to
949 * each of its streams. */
950 if (inode->i_nlink > 1)
951 inode_ref_streams(inode);
952 dentry->d_inode = inode;
953 inode_add_dentry(dentry, inode);
955 *dentry_ret = dentry;
961 /* Assign consecutive inode numbers to a new set of inodes from the inode table,
962 * and append the inodes to a single list @head that contains the inodes already
963 * existing in the WIM image. */
965 inode_table_prepare_inode_list(struct wim_inode_table *table,
966 struct list_head *head)
968 struct wim_inode *inode, *tmp_inode;
969 struct hlist_node *cur, *tmp;
972 /* Re-assign inode numbers in the existing list to avoid duplicates. */
973 list_for_each_entry(inode, head, i_list)
974 inode->i_ino = cur_ino++;
976 /* Assign inode numbers to the new inodes and move them to the image's
978 for (size_t i = 0; i < table->capacity; i++) {
979 hlist_for_each_entry_safe(inode, cur, tmp, &table->array[i], i_hlist)
981 inode->i_ino = cur_ino++;
983 list_add_tail(&inode->i_list, head);
985 INIT_HLIST_HEAD(&table->array[i]);
987 list_for_each_entry_safe(inode, tmp_inode, &table->extra_inodes, i_list)
989 inode->i_ino = cur_ino++;
991 list_add_tail(&inode->i_list, head);
993 INIT_LIST_HEAD(&table->extra_inodes);
994 table->num_entries = 0;