4 * Functions that operate on WIM inodes.
6 * See dentry.c for a description of the relationship between WIM dentries and
11 * Copyright (C) 2012, 2013, 2014 Eric Biggers
13 * This file is free software; you can redistribute it and/or modify it under
14 * the terms of the GNU Lesser General Public License as published by the Free
15 * Software Foundation; either version 3 of the License, or (at your option) any
18 * This file is distributed in the hope that it will be useful, but WITHOUT
19 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
23 * You should have received a copy of the GNU Lesser General Public License
24 * along with this file; if not, see http://www.gnu.org/licenses/.
33 #include "wimlib/assert.h"
34 #include "wimlib/dentry.h"
35 #include "wimlib/encoding.h"
36 #include "wimlib/endianness.h"
37 #include "wimlib/error.h"
38 #include "wimlib/inode.h"
39 #include "wimlib/lookup_table.h"
40 #include "wimlib/security.h"
41 #include "wimlib/timestamp.h"
43 /* Allocate a new inode. Set the timestamps to the current time. */
47 struct wim_inode *inode = new_timeless_inode();
49 u64 now = now_as_wim_timestamp();
50 inode->i_creation_time = now;
51 inode->i_last_access_time = now;
52 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;
64 /*inode->i_nlink = 0;*/
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 /* Free memory allocated within an alternate data stream entry. */
76 destroy_ads_entry(struct wim_ads_entry *ads_entry)
78 FREE(ads_entry->stream_name);
82 free_inode(struct wim_inode *inode)
84 if (unlikely(inode->i_ads_entries)) {
85 for (unsigned i = 0; i < inode->i_num_ads; i++)
86 destroy_ads_entry(&inode->i_ads_entries[i]);
87 FREE(inode->i_ads_entries);
89 if (unlikely(inode->i_extra))
91 /* HACK: This may instead delete the inode from i_list, but hlist_del()
92 * behaves the same as list_del(). */
93 if (!hlist_unhashed(&inode->i_hlist))
94 hlist_del(&inode->i_hlist);
99 free_inode_if_unneeded(struct wim_inode *inode)
104 if (inode->i_num_opened_fds)
110 /* Associate a dentry with the specified inode. */
112 d_associate(struct wim_dentry *dentry, struct wim_inode *inode)
114 wimlib_assert(!dentry->d_inode);
116 list_add_tail(&dentry->d_alias, &inode->i_dentry);
117 dentry->d_inode = inode;
121 /* Disassociate a dentry from its inode, if any. Following this, free the inode
122 * if it is no longer in use. */
124 d_disassociate(struct wim_dentry *dentry)
126 struct wim_inode *inode = dentry->d_inode;
128 if (unlikely(!inode))
131 wimlib_assert(inode->i_nlink > 0);
133 list_del(&dentry->d_alias);
134 dentry->d_inode = NULL;
137 free_inode_if_unneeded(inode);
142 inode_dec_num_opened_fds(struct wim_inode *inode)
144 wimlib_assert(inode->i_num_opened_fds > 0);
146 if (--inode->i_num_opened_fds == 0) {
147 /* The last file descriptor to this inode was closed. */
150 inode->i_num_allocated_fds = 0;
152 free_inode_if_unneeded(inode);
158 * Returns the alternate data stream entry belonging to @inode that has the
159 * stream name @stream_name, or NULL if the inode has no alternate data stream
162 * If @p stream_name is the empty string, NULL is returned --- that is, this
163 * function will not return "unnamed" alternate data stream entries.
165 * If NULL is returned, errno is set.
167 struct wim_ads_entry *
168 inode_get_ads_entry(struct wim_inode *inode, const tchar *stream_name)
171 const utf16lechar *stream_name_utf16le;
172 size_t stream_name_utf16le_nbytes;
174 struct wim_ads_entry *result;
176 if (inode->i_num_ads == 0) {
181 if (stream_name[0] == T('\0')) {
186 ret = tstr_get_utf16le_and_len(stream_name, &stream_name_utf16le,
187 &stream_name_utf16le_nbytes);
194 if (!cmp_utf16le_strings(inode->i_ads_entries[i].stream_name,
195 inode->i_ads_entries[i].stream_name_nbytes /
198 stream_name_utf16le_nbytes /
200 default_ignore_case))
202 result = &inode->i_ads_entries[i];
205 } while (++i != inode->i_num_ads);
207 tstr_put_utf16le(stream_name_utf16le);
214 static struct wim_ads_entry *
215 do_inode_add_ads(struct wim_inode *inode,
216 utf16lechar *stream_name, size_t stream_name_nbytes)
219 struct wim_ads_entry *ads_entries;
220 struct wim_ads_entry *new_entry;
222 if (unlikely(inode->i_num_ads >= 0xfffe)) {
223 ERROR("File \"%"TS"\" has too many alternate data streams!",
224 inode_first_full_path(inode));
228 num_ads = inode->i_num_ads + 1;
229 ads_entries = REALLOC(inode->i_ads_entries,
230 num_ads * sizeof(inode->i_ads_entries[0]));
234 inode->i_ads_entries = ads_entries;
236 new_entry = &inode->i_ads_entries[num_ads - 1];
238 memset(new_entry, 0, sizeof(struct wim_ads_entry));
239 new_entry->stream_name = stream_name;
240 new_entry->stream_name_nbytes = stream_name_nbytes;
241 new_entry->stream_id = inode->i_next_stream_id++;
242 inode->i_num_ads = num_ads;
247 * Add an alternate data stream entry to a WIM inode (UTF-16LE version). On
248 * success, returns a pointer to the new entry. Note that this pointer might
249 * become invalid if another ADS entry is added to the inode. On failure,
250 * returns NULL and sets errno.
252 struct wim_ads_entry *
253 inode_add_ads_utf16le(struct wim_inode *inode,
254 const utf16lechar *stream_name, size_t stream_name_nbytes)
256 utf16lechar *dup = NULL;
257 struct wim_ads_entry *result;
259 if (stream_name_nbytes) {
260 dup = utf16le_dupz(stream_name, stream_name_nbytes);
265 result = do_inode_add_ads(inode, dup, stream_name_nbytes);
272 * Add an alternate data stream entry to a WIM inode (tchar version). On
273 * success, returns a pointer to the new entry. Note that this pointer might
274 * become invalid if another ADS entry is added to the inode. On failure,
275 * returns NULL and sets errno.
277 struct wim_ads_entry *
278 inode_add_ads(struct wim_inode *inode, const tchar *stream_name)
280 utf16lechar *stream_name_utf16le = NULL;
281 size_t stream_name_utf16le_nbytes = 0;
282 struct wim_ads_entry *result;
284 if (stream_name && *stream_name)
285 if (tstr_to_utf16le(stream_name,
286 tstrlen(stream_name) * sizeof(tchar),
287 &stream_name_utf16le,
288 &stream_name_utf16le_nbytes))
291 result = do_inode_add_ads(inode, stream_name_utf16le,
292 stream_name_utf16le_nbytes);
294 FREE(stream_name_utf16le);
299 * Add an data alternate stream entry to a WIM inode, where the contents of the
300 * new stream are specified in a data buffer. The inode must be resolved.
302 * On success, returns a pointer to the new alternate data stream entry. Note
303 * that this pointer might become invalid if another ADS entry is added to the
304 * inode. On failure, returns NULL and sets errno.
306 struct wim_ads_entry *
307 inode_add_ads_with_data(struct wim_inode *inode, const tchar *name,
308 const void *value, size_t size,
309 struct wim_lookup_table *lookup_table)
311 struct wim_ads_entry *new_entry;
313 wimlib_assert(inode->i_resolved);
315 new_entry = inode_add_ads(inode, name);
316 if (unlikely(!new_entry))
319 new_entry->lte = new_stream_from_data_buffer(value, size, lookup_table);
320 if (unlikely(!new_entry->lte)) {
321 inode_remove_ads(inode, new_entry, NULL);
327 /* Remove an alternate data stream from a WIM inode. */
329 inode_remove_ads(struct wim_inode *inode, struct wim_ads_entry *entry,
330 struct wim_lookup_table *lookup_table)
332 struct wim_lookup_table_entry *lte;
333 unsigned idx = entry - inode->i_ads_entries;
335 wimlib_assert(idx < inode->i_num_ads);
336 wimlib_assert(inode->i_resolved);
340 lte_decrement_refcnt(lte, lookup_table);
342 destroy_ads_entry(entry);
344 memmove(&inode->i_ads_entries[idx],
345 &inode->i_ads_entries[idx + 1],
346 (inode->i_num_ads - idx - 1) * sizeof(inode->i_ads_entries[0]));
350 /* Return true iff the specified inode has at least one named data stream. */
352 inode_has_named_stream(const struct wim_inode *inode)
354 for (unsigned i = 0; i < inode->i_num_ads; i++)
355 if (inode->i_ads_entries[i].stream_name_nbytes)
360 /* Set the unnamed stream of a WIM inode, given a data buffer containing the
361 * stream contents. The inode must be resolved and cannot already have an
364 inode_set_unnamed_stream(struct wim_inode *inode, const void *data, size_t len,
365 struct wim_lookup_table *lookup_table)
367 wimlib_assert(inode->i_resolved);
368 wimlib_assert(!inode->i_lte);
370 inode->i_lte = new_stream_from_data_buffer(data, len, lookup_table);
372 return WIMLIB_ERR_NOMEM;
377 * Resolve an inode's single-instance streams.
379 * This takes each SHA-1 message digest stored in the inode or one of its ADS
380 * entries and replaces it with a pointer directly to the appropriate 'struct
381 * wim_lookup_table_entry' currently inserted into @table to represent the
382 * single-instance stream having that SHA-1 message digest.
384 * If @force is %false:
385 * If any of the needed single-instance streams do not exist in @table,
386 * return WIMLIB_ERR_RESOURCE_NOT_FOUND and leave the inode unmodified.
387 * If @force is %true:
388 * If any of the needed single-instance streams do not exist in @table,
389 * allocate new entries for them and insert them into @table. This does
390 * not, of course, cause these streams to magically exist, but this is
391 * needed by the code for extraction from a pipe.
393 * If the inode is already resolved, this function does nothing.
395 * Returns 0 on success; WIMLIB_ERR_NOMEM if out of memory; or
396 * WIMLIB_ERR_RESOURCE_NOT_FOUND if @force is %false and at least one
397 * single-instance stream referenced by the inode was missing.
400 inode_resolve_streams(struct wim_inode *inode, struct wim_lookup_table *table,
404 struct wim_lookup_table_entry *lte, *ads_lte;
406 if (inode->i_resolved)
409 struct wim_lookup_table_entry *ads_ltes[inode->i_num_ads];
411 /* Resolve the default data stream */
413 hash = inode->i_hash;
414 if (!is_zero_hash(hash)) {
415 lte = lookup_stream(table, hash);
418 lte = new_lookup_table_entry();
420 return WIMLIB_ERR_NOMEM;
421 copy_hash(lte->hash, hash);
422 lookup_table_insert(table, lte);
424 goto stream_not_found;
429 /* Resolve the alternate data streams */
430 for (unsigned i = 0; i < inode->i_num_ads; i++) {
431 struct wim_ads_entry *cur_entry;
434 cur_entry = &inode->i_ads_entries[i];
435 hash = cur_entry->hash;
436 if (!is_zero_hash(hash)) {
437 ads_lte = lookup_stream(table, hash);
440 ads_lte = new_lookup_table_entry();
442 return WIMLIB_ERR_NOMEM;
443 copy_hash(ads_lte->hash, hash);
444 lookup_table_insert(table, ads_lte);
446 goto stream_not_found;
450 ads_ltes[i] = ads_lte;
453 for (unsigned i = 0; i < inode->i_num_ads; i++)
454 inode->i_ads_entries[i].lte = ads_ltes[i];
455 inode->i_resolved = 1;
459 return stream_not_found_error(inode, hash);
463 * Undo the effects of inode_resolve_streams().
465 * If the inode is not resolved, this function does nothing.
468 inode_unresolve_streams(struct wim_inode *inode)
470 if (!inode->i_resolved)
474 copy_hash(inode->i_hash, inode->i_lte->hash);
476 zero_out_hash(inode->i_hash);
478 for (unsigned i = 0; i < inode->i_num_ads; i++) {
479 if (inode->i_ads_entries[i].lte)
480 copy_hash(inode->i_ads_entries[i].hash,
481 inode->i_ads_entries[i].lte->hash);
483 zero_out_hash(inode->i_ads_entries[i].hash);
485 inode->i_resolved = 0;
489 stream_not_found_error(const struct wim_inode *inode, const u8 *hash)
491 if (wimlib_print_errors) {
492 tchar hashstr[SHA1_HASH_SIZE * 2 + 1];
494 sprint_hash(hash, hashstr);
496 ERROR("\"%"TS"\": stream not found\n"
497 " SHA-1 message digest of missing stream:\n"
499 inode_first_full_path(inode), hashstr);
501 return WIMLIB_ERR_RESOURCE_NOT_FOUND;
505 * Return the lookup table entry for the specified stream of the inode, or NULL
506 * if the specified stream is empty or not available.
508 * stream_idx = 0: default data stream
509 * stream_idx > 0: alternate data stream
511 struct wim_lookup_table_entry *
512 inode_stream_lte(const struct wim_inode *inode, unsigned stream_idx,
513 const struct wim_lookup_table *table)
515 if (inode->i_resolved)
516 return inode_stream_lte_resolved(inode, stream_idx);
518 return lookup_stream(table, inode->i_hash);
519 return lookup_stream(table, inode->i_ads_entries[stream_idx - 1].hash);
523 * Return the lookup table entry for the unnamed data stream of a *resolved*
524 * inode, or NULL if the inode's unnamed data stream is empty. Also return the
525 * 0-based index of the unnamed data stream in *stream_idx_ret.
527 struct wim_lookup_table_entry *
528 inode_unnamed_stream_resolved(const struct wim_inode *inode,
529 unsigned *stream_idx_ret)
531 wimlib_assert(inode->i_resolved);
534 if (likely(inode->i_lte))
537 for (unsigned i = 0; i < inode->i_num_ads; i++) {
538 if (inode->i_ads_entries[i].stream_name_nbytes == 0 &&
539 inode->i_ads_entries[i].lte)
541 *stream_idx_ret = i + 1;
542 return inode->i_ads_entries[i].lte;
549 * Return the lookup table entry for the unnamed data stream of an inode, or
550 * NULL if the inode's unnamed data stream is empty or not available.
552 * Note: this is complicated by the fact that WIMGAPI may put the unnamed data
553 * stream in an alternate data stream entry rather than in the dentry itself.
555 struct wim_lookup_table_entry *
556 inode_unnamed_lte(const struct wim_inode *inode,
557 const struct wim_lookup_table *table)
559 struct wim_lookup_table_entry *lte;
561 if (inode->i_resolved)
562 return inode_unnamed_lte_resolved(inode);
564 lte = lookup_stream(table, inode->i_hash);
568 for (unsigned i = 0; i < inode->i_num_ads; i++) {
569 if (inode->i_ads_entries[i].stream_name_nbytes)
571 lte = lookup_stream(table, inode->i_ads_entries[i].hash);
578 /* Return the SHA-1 message digest of the specified stream of the inode, or a
579 * void SHA-1 of all zeroes if the specified stream is empty. */
581 inode_stream_hash(const struct wim_inode *inode, unsigned stream_idx)
583 if (inode->i_resolved) {
584 struct wim_lookup_table_entry *lte;
586 lte = inode_stream_lte_resolved(inode, stream_idx);
592 return inode->i_hash;
593 return inode->i_ads_entries[stream_idx - 1].hash;
596 /* Return the SHA-1 message digest of the unnamed data stream of the inode, or a
597 * void SHA-1 of all zeroes if the inode's unnamed data stream is empty. */
599 inode_unnamed_stream_hash(const struct wim_inode *inode)
603 for (unsigned i = 0; i <= inode->i_num_ads; i++) {
604 if (inode_stream_name_nbytes(inode, i) == 0) {
605 hash = inode_stream_hash(inode, i);
606 if (!is_zero_hash(hash))
613 /* Acquire another reference to each single-instance stream referenced by this
614 * inode. This is necessary when creating a hard link to this inode.
616 * The inode must be resolved. */
618 inode_ref_streams(struct wim_inode *inode)
620 wimlib_assert(inode->i_resolved);
623 inode->i_lte->refcnt++;
624 for (unsigned i = 0; i < inode->i_num_ads; i++)
625 if (inode->i_ads_entries[i].lte)
626 inode->i_ads_entries[i].lte->refcnt++;
629 /* Drop a reference to each single-instance stream referenced by this inode.
630 * This is necessary when deleting a hard link to this inode. */
632 inode_unref_streams(struct wim_inode *inode,
633 struct wim_lookup_table *lookup_table)
635 for (unsigned i = 0; i <= inode->i_num_ads; i++) {
636 struct wim_lookup_table_entry *lte;
638 lte = inode_stream_lte(inode, i, lookup_table);
640 lte_decrement_refcnt(lte, lookup_table);
645 * Read the alternate data stream entries of a WIM dentry.
648 * Pointer to buffer that starts with the first alternate stream entry.
651 * Inode to load the alternate data streams into. @inode->i_num_ads must
652 * have been set to the number of alternate data streams that are expected.
654 * @nbytes_remaining_p:
655 * Number of bytes of data remaining in the buffer pointed to by @p.
656 * On success this will be updated to point just past the ADS entries.
658 * On success, inode->i_ads_entries is set to an array of `struct
659 * wim_ads_entry's of length inode->i_num_ads. On failure, @inode is not
663 * WIMLIB_ERR_SUCCESS (0)
664 * WIMLIB_ERR_INVALID_METADATA_RESOURCE
668 read_ads_entries(const u8 * restrict p, struct wim_inode * restrict inode,
669 size_t *nbytes_remaining_p)
671 size_t nbytes_remaining = *nbytes_remaining_p;
673 struct wim_ads_entry *ads_entries;
676 BUILD_BUG_ON(sizeof(struct wim_ads_entry_on_disk) != WIM_ADS_ENTRY_DISK_SIZE);
678 /* Allocate an array for our in-memory representation of the alternate
679 * data stream entries. */
680 num_ads = inode->i_num_ads;
681 ads_entries = CALLOC(num_ads, sizeof(inode->i_ads_entries[0]));
685 /* Read the entries into our newly allocated buffer. */
686 for (unsigned i = 0; i < num_ads; i++) {
688 struct wim_ads_entry *cur_entry;
689 const struct wim_ads_entry_on_disk *disk_entry =
690 (const struct wim_ads_entry_on_disk*)p;
692 cur_entry = &ads_entries[i];
693 ads_entries[i].stream_id = i + 1;
695 /* Do we have at least the size of the fixed-length data we know
697 if (nbytes_remaining < sizeof(struct wim_ads_entry_on_disk))
700 /* Read the length field */
701 length = le64_to_cpu(disk_entry->length);
703 /* Make sure the length field is neither so small it doesn't
704 * include all the fixed-length data nor so large it overflows
705 * the metadata resource buffer. */
706 if (length < sizeof(struct wim_ads_entry_on_disk) ||
707 length > nbytes_remaining)
710 /* Read the rest of the fixed-length data. */
712 cur_entry->reserved = le64_to_cpu(disk_entry->reserved);
713 copy_hash(cur_entry->hash, disk_entry->hash);
714 cur_entry->stream_name_nbytes = le16_to_cpu(disk_entry->stream_name_nbytes);
716 /* If stream_name_nbytes != 0, this is a named stream.
717 * Otherwise this is an unnamed stream, or in some cases (bugs
718 * in Microsoft's software I guess) a meaningless entry
719 * distinguished from the real unnamed stream entry, if any, by
720 * the fact that the real unnamed stream entry has a nonzero
722 if (cur_entry->stream_name_nbytes) {
723 /* The name is encoded in UTF16-LE, which uses 2-byte
724 * coding units, so the length of the name had better be
725 * an even number of bytes... */
726 if (cur_entry->stream_name_nbytes & 1)
729 /* Add the length of the stream name to get the length
730 * we actually need to read. Make sure this isn't more
731 * than the specified length of the entry. */
732 if (sizeof(struct wim_ads_entry_on_disk) +
733 cur_entry->stream_name_nbytes > length)
736 cur_entry->stream_name = utf16le_dupz(disk_entry->stream_name,
737 cur_entry->stream_name_nbytes);
738 if (!cur_entry->stream_name)
741 /* Mark inode as having weird stream entries. */
742 inode->i_canonical_streams = 0;
745 /* It's expected that the size of every ADS entry is a multiple
746 * of 8. However, to be safe, I'm allowing the possibility of
747 * an ADS entry at the very end of the metadata resource ending
748 * unaligned. So although we still need to increment the input
749 * pointer by @length to reach the next ADS entry, it's possible
750 * that less than @length is actually remaining in the metadata
751 * resource. We should set the remaining bytes to 0 if this
753 length = (length + 7) & ~7;
755 if (nbytes_remaining < length)
756 nbytes_remaining = 0;
758 nbytes_remaining -= length;
760 inode->i_ads_entries = ads_entries;
761 inode->i_next_stream_id = inode->i_num_ads + 1;
762 *nbytes_remaining_p = nbytes_remaining;
766 ret = WIMLIB_ERR_NOMEM;
767 goto out_free_ads_entries;
769 ERROR("An alternate data stream entry is invalid");
770 ret = WIMLIB_ERR_INVALID_METADATA_RESOURCE;
771 out_free_ads_entries:
773 for (unsigned i = 0; i < num_ads; i++)
774 destroy_ads_entry(&ads_entries[i]);
781 /* Check a WIM inode for unusual field values. */
783 check_inode(struct wim_inode *inode, const struct wim_security_data *sd)
785 /* Check the security ID. -1 is valid and means "no security
786 * descriptor". Anything else has to be a valid index into the WIM
787 * image's security descriptors table. */
788 if (inode->i_security_id < -1 ||
789 (inode->i_security_id >= 0 &&
790 inode->i_security_id >= sd->num_entries))
792 WARNING("\"%"TS"\" has an invalid security ID (%d)",
793 inode_first_full_path(inode), inode->i_security_id);
794 inode->i_security_id = -1;
797 /* Make sure there is only one unnamed data stream. */
798 unsigned num_unnamed_streams = 0;
799 for (unsigned i = 0; i <= inode->i_num_ads; i++) {
801 hash = inode_stream_hash(inode, i);
802 if (inode_stream_name_nbytes(inode, i) == 0 && !is_zero_hash(hash))
803 num_unnamed_streams++;
805 if (num_unnamed_streams > 1) {
806 WARNING("\"%"TS"\" has multiple (%u) unnamed streams",
807 inode_first_full_path(inode), num_unnamed_streams);
808 /* We currently don't treat this as an error and will just end
809 * up using the first unnamed data stream in the inode. */
814 * Translate a single-instance stream entry into the pointer contained in the
815 * inode (or ads entry of an inode) that references it.
817 * This is only possible for "unhashed" streams, which are guaranteed to have
818 * only one reference, and that reference is guaranteed to be in a resolved
819 * inode. (It can't be in an unresolved inode, since that would imply the hash
822 struct wim_lookup_table_entry **
823 retrieve_lte_pointer(struct wim_lookup_table_entry *lte)
825 wimlib_assert(lte->unhashed);
826 struct wim_inode *inode = lte->back_inode;
827 u32 stream_id = lte->back_stream_id;
829 return &inode->i_lte;
830 for (unsigned i = 0; i < inode->i_num_ads; i++)
831 if (inode->i_ads_entries[i].stream_id == stream_id)
832 return &inode->i_ads_entries[i].lte;