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;
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 an inode's link count. */
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. */
83 if (inode->i_num_opened_fds == 0)
89 /* Free memory allocated within an alternate data stream entry. */
91 destroy_ads_entry(struct wim_ads_entry *ads_entry)
93 FREE(ads_entry->stream_name);
96 /* Free an inode. Only use this if there can't be other links to the inode or
97 * if it doesn't matter if there are. */
99 free_inode(struct wim_inode *inode)
101 if (unlikely(!inode))
104 if (unlikely(inode->i_ads_entries)) {
105 for (unsigned i = 0; i < inode->i_num_ads; i++)
106 destroy_ads_entry(&inode->i_ads_entries[i]);
107 FREE(inode->i_ads_entries);
109 if (unlikely(inode->i_extra))
110 FREE(inode->i_extra);
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);
119 * Returns the alternate data stream entry belonging to @inode that has the
120 * stream name @stream_name, or NULL if the inode has no alternate data stream
123 * If @p stream_name is the empty string, NULL is returned --- that is, this
124 * function will not return "unnamed" alternate data stream entries.
126 * If NULL is returned, errno is set.
128 struct wim_ads_entry *
129 inode_get_ads_entry(struct wim_inode *inode, const tchar *stream_name)
132 const utf16lechar *stream_name_utf16le;
133 size_t stream_name_utf16le_nbytes;
135 struct wim_ads_entry *result;
137 if (inode->i_num_ads == 0) {
142 if (stream_name[0] == T('\0')) {
147 ret = tstr_get_utf16le_and_len(stream_name, &stream_name_utf16le,
148 &stream_name_utf16le_nbytes);
155 if (!cmp_utf16le_strings(inode->i_ads_entries[i].stream_name,
156 inode->i_ads_entries[i].stream_name_nbytes /
159 stream_name_utf16le_nbytes /
161 default_ignore_case))
163 result = &inode->i_ads_entries[i];
166 } while (++i != inode->i_num_ads);
168 tstr_put_utf16le(stream_name_utf16le);
175 static struct wim_ads_entry *
176 do_inode_add_ads(struct wim_inode *inode,
177 utf16lechar *stream_name, size_t stream_name_nbytes)
180 struct wim_ads_entry *ads_entries;
181 struct wim_ads_entry *new_entry;
183 if (unlikely(inode->i_num_ads >= 0xfffe)) {
184 ERROR("File \"%"TS"\" has too many alternate data streams!",
185 inode_first_full_path(inode));
189 num_ads = inode->i_num_ads + 1;
190 ads_entries = REALLOC(inode->i_ads_entries,
191 num_ads * sizeof(inode->i_ads_entries[0]));
195 inode->i_ads_entries = ads_entries;
197 new_entry = &inode->i_ads_entries[num_ads - 1];
199 memset(new_entry, 0, sizeof(struct wim_ads_entry));
200 new_entry->stream_name = stream_name;
201 new_entry->stream_name_nbytes = stream_name_nbytes;
202 new_entry->stream_id = inode->i_next_stream_id++;
203 inode->i_num_ads = num_ads;
208 * Add an alternate data stream entry to a WIM inode (UTF-16LE version). On
209 * success, returns a pointer to the new entry. Note that this pointer might
210 * become invalid if another ADS entry is added to the inode. On failure,
211 * returns NULL and sets errno.
213 struct wim_ads_entry *
214 inode_add_ads_utf16le(struct wim_inode *inode,
215 const utf16lechar *stream_name, size_t stream_name_nbytes)
217 utf16lechar *dup = NULL;
218 struct wim_ads_entry *result;
220 if (stream_name_nbytes) {
221 dup = utf16le_dupz(stream_name, stream_name_nbytes);
226 result = do_inode_add_ads(inode, dup, stream_name_nbytes);
233 * Add an alternate data stream entry to a WIM inode (tchar version). On
234 * success, returns a pointer to the new entry. Note that this pointer might
235 * become invalid if another ADS entry is added to the inode. On failure,
236 * returns NULL and sets errno.
238 struct wim_ads_entry *
239 inode_add_ads(struct wim_inode *inode, const tchar *stream_name)
241 utf16lechar *stream_name_utf16le = NULL;
242 size_t stream_name_utf16le_nbytes = 0;
243 struct wim_ads_entry *result;
245 if (stream_name && *stream_name)
246 if (tstr_to_utf16le(stream_name,
247 tstrlen(stream_name) * sizeof(tchar),
248 &stream_name_utf16le,
249 &stream_name_utf16le_nbytes))
252 result = do_inode_add_ads(inode, stream_name_utf16le,
253 stream_name_utf16le_nbytes);
255 FREE(stream_name_utf16le);
260 * Add an data alternate stream entry to a WIM inode, where the contents of the
261 * new stream are specified in a data buffer. The inode must be resolved.
263 * On success, returns a pointer to the new alternate data stream entry. Note
264 * that this pointer might become invalid if another ADS entry is added to the
265 * inode. On failure, returns NULL and sets errno.
267 struct wim_ads_entry *
268 inode_add_ads_with_data(struct wim_inode *inode, const tchar *name,
269 const void *value, size_t size,
270 struct wim_lookup_table *lookup_table)
272 struct wim_ads_entry *new_entry;
274 wimlib_assert(inode->i_resolved);
276 new_entry = inode_add_ads(inode, name);
277 if (unlikely(!new_entry))
280 new_entry->lte = new_stream_from_data_buffer(value, size, lookup_table);
281 if (unlikely(!new_entry->lte)) {
282 inode_remove_ads(inode, new_entry, NULL);
288 /* Remove an alternate data stream from a WIM inode. */
290 inode_remove_ads(struct wim_inode *inode, struct wim_ads_entry *entry,
291 struct wim_lookup_table *lookup_table)
293 struct wim_lookup_table_entry *lte;
294 unsigned idx = entry - inode->i_ads_entries;
296 wimlib_assert(idx < inode->i_num_ads);
297 wimlib_assert(inode->i_resolved);
301 lte_decrement_refcnt(lte, lookup_table);
303 destroy_ads_entry(entry);
305 memmove(&inode->i_ads_entries[idx],
306 &inode->i_ads_entries[idx + 1],
307 (inode->i_num_ads - idx - 1) * sizeof(inode->i_ads_entries[0]));
311 /* Return true iff the specified inode has at least one named data stream. */
313 inode_has_named_stream(const struct wim_inode *inode)
315 for (unsigned i = 0; i < inode->i_num_ads; i++)
316 if (inode->i_ads_entries[i].stream_name_nbytes)
321 /* Set the unnamed stream of a WIM inode, given a data buffer containing the
322 * stream contents. The inode must be resolved and cannot already have an
325 inode_set_unnamed_stream(struct wim_inode *inode, const void *data, size_t len,
326 struct wim_lookup_table *lookup_table)
328 wimlib_assert(inode->i_resolved);
329 wimlib_assert(!inode->i_lte);
331 inode->i_lte = new_stream_from_data_buffer(data, len, lookup_table);
333 return WIMLIB_ERR_NOMEM;
338 * Resolve an inode's single-instance streams.
340 * This takes each SHA-1 message digest stored in the inode or one of its ADS
341 * entries and replaces it with a pointer directly to the appropriate 'struct
342 * wim_lookup_table_entry' currently inserted into @table to represent the
343 * single-instance stream having that SHA-1 message digest.
345 * If @force is %false:
346 * If any of the needed single-instance streams do not exist in @table,
347 * return WIMLIB_ERR_RESOURCE_NOT_FOUND and leave the inode unmodified.
348 * If @force is %true:
349 * If any of the needed single-instance streams do not exist in @table,
350 * allocate new entries for them and insert them into @table. This does
351 * not, of course, cause these streams to magically exist, but this is
352 * needed by the code for extraction from a pipe.
354 * If the inode is already resolved, this function does nothing.
356 * Returns 0 on success; WIMLIB_ERR_NOMEM if out of memory; or
357 * WIMLIB_ERR_RESOURCE_NOT_FOUND if @force is %false and at least one
358 * single-instance stream referenced by the inode was missing.
361 inode_resolve_streams(struct wim_inode *inode, struct wim_lookup_table *table,
365 struct wim_lookup_table_entry *lte, *ads_lte;
367 if (inode->i_resolved)
370 struct wim_lookup_table_entry *ads_ltes[inode->i_num_ads];
372 /* Resolve the default data stream */
374 hash = inode->i_hash;
375 if (!is_zero_hash(hash)) {
376 lte = lookup_stream(table, hash);
379 lte = new_lookup_table_entry();
381 return WIMLIB_ERR_NOMEM;
382 copy_hash(lte->hash, hash);
383 lookup_table_insert(table, lte);
385 goto stream_not_found;
390 /* Resolve the alternate data streams */
391 for (unsigned i = 0; i < inode->i_num_ads; i++) {
392 struct wim_ads_entry *cur_entry;
395 cur_entry = &inode->i_ads_entries[i];
396 hash = cur_entry->hash;
397 if (!is_zero_hash(hash)) {
398 ads_lte = lookup_stream(table, hash);
401 ads_lte = new_lookup_table_entry();
403 return WIMLIB_ERR_NOMEM;
404 copy_hash(ads_lte->hash, hash);
405 lookup_table_insert(table, ads_lte);
407 goto stream_not_found;
411 ads_ltes[i] = ads_lte;
414 for (unsigned i = 0; i < inode->i_num_ads; i++)
415 inode->i_ads_entries[i].lte = ads_ltes[i];
416 inode->i_resolved = 1;
420 return stream_not_found_error(inode, hash);
424 * Undo the effects of inode_resolve_streams().
426 * If the inode is not resolved, this function does nothing.
429 inode_unresolve_streams(struct wim_inode *inode)
431 if (!inode->i_resolved)
435 copy_hash(inode->i_hash, inode->i_lte->hash);
437 zero_out_hash(inode->i_hash);
439 for (unsigned i = 0; i < inode->i_num_ads; i++) {
440 if (inode->i_ads_entries[i].lte)
441 copy_hash(inode->i_ads_entries[i].hash,
442 inode->i_ads_entries[i].lte->hash);
444 zero_out_hash(inode->i_ads_entries[i].hash);
446 inode->i_resolved = 0;
450 stream_not_found_error(const struct wim_inode *inode, const u8 *hash)
452 if (wimlib_print_errors) {
453 tchar hashstr[SHA1_HASH_SIZE * 2 + 1];
455 sprint_hash(hash, hashstr);
457 ERROR("\"%"TS"\": stream not found\n"
458 " SHA-1 message digest of missing stream:\n"
460 inode_first_full_path(inode), hashstr);
462 return WIMLIB_ERR_RESOURCE_NOT_FOUND;
466 * Return the lookup table entry for the specified stream of the inode, or NULL
467 * if the specified stream is empty or not available.
469 * stream_idx = 0: default data stream
470 * stream_idx > 0: alternate data stream
472 struct wim_lookup_table_entry *
473 inode_stream_lte(const struct wim_inode *inode, unsigned stream_idx,
474 const struct wim_lookup_table *table)
476 if (inode->i_resolved)
477 return inode_stream_lte_resolved(inode, stream_idx);
479 return lookup_stream(table, inode->i_hash);
480 return lookup_stream(table, inode->i_ads_entries[stream_idx - 1].hash);
484 * Return the lookup table entry for the unnamed data stream of a *resolved*
485 * inode, or NULL if the inode's unnamed data stream is empty. Also return the
486 * 0-based index of the unnamed data stream in *stream_idx_ret.
488 struct wim_lookup_table_entry *
489 inode_unnamed_stream_resolved(const struct wim_inode *inode,
490 unsigned *stream_idx_ret)
492 wimlib_assert(inode->i_resolved);
495 if (likely(inode->i_lte))
498 for (unsigned i = 0; i < inode->i_num_ads; i++) {
499 if (inode->i_ads_entries[i].stream_name_nbytes == 0 &&
500 inode->i_ads_entries[i].lte)
502 *stream_idx_ret = i + 1;
503 return inode->i_ads_entries[i].lte;
510 * Return the lookup table entry for the unnamed data stream of an inode, or
511 * NULL if the inode's unnamed data stream is empty or not available.
513 * Note: this is complicated by the fact that WIMGAPI may put the unnamed data
514 * stream in an alternate data stream entry rather than in the dentry itself.
516 struct wim_lookup_table_entry *
517 inode_unnamed_lte(const struct wim_inode *inode,
518 const struct wim_lookup_table *table)
520 struct wim_lookup_table_entry *lte;
522 if (inode->i_resolved)
523 return inode_unnamed_lte_resolved(inode);
525 lte = lookup_stream(table, inode->i_hash);
529 for (unsigned i = 0; i < inode->i_num_ads; i++) {
530 if (inode->i_ads_entries[i].stream_name_nbytes)
532 lte = lookup_stream(table, inode->i_ads_entries[i].hash);
539 /* Return the SHA-1 message digest of the specified stream of the inode, or a
540 * void SHA-1 of all zeroes if the specified stream is empty. */
542 inode_stream_hash(const struct wim_inode *inode, unsigned stream_idx)
544 if (inode->i_resolved) {
545 struct wim_lookup_table_entry *lte;
547 lte = inode_stream_lte_resolved(inode, stream_idx);
553 return inode->i_hash;
554 return inode->i_ads_entries[stream_idx - 1].hash;
557 /* Return the SHA-1 message digest of the unnamed data stream of the inode, or a
558 * void SHA-1 of all zeroes if the inode's unnamed data stream is empty. */
560 inode_unnamed_stream_hash(const struct wim_inode *inode)
564 for (unsigned i = 0; i <= inode->i_num_ads; i++) {
565 if (inode_stream_name_nbytes(inode, i) == 0) {
566 hash = inode_stream_hash(inode, i);
567 if (!is_zero_hash(hash))
574 /* Acquire another reference to each single-instance stream referenced by this
575 * inode. This is necessary when creating a hard link to this inode.
577 * The inode must be resolved. */
579 inode_ref_streams(struct wim_inode *inode)
581 wimlib_assert(inode->i_resolved);
584 inode->i_lte->refcnt++;
585 for (unsigned i = 0; i < inode->i_num_ads; i++)
586 if (inode->i_ads_entries[i].lte)
587 inode->i_ads_entries[i].lte->refcnt++;
590 /* Drop a reference to each single-instance stream referenced by this inode.
591 * This is necessary when deleting a hard link to this inode. */
593 inode_unref_streams(struct wim_inode *inode,
594 struct wim_lookup_table *lookup_table)
596 for (unsigned i = 0; i <= inode->i_num_ads; i++) {
597 struct wim_lookup_table_entry *lte;
599 lte = inode_stream_lte(inode, i, lookup_table);
601 lte_decrement_refcnt(lte, lookup_table);
606 * Read the alternate data stream entries of a WIM dentry.
609 * Pointer to buffer that starts with the first alternate stream entry.
612 * Inode to load the alternate data streams into. @inode->i_num_ads must
613 * have been set to the number of alternate data streams that are expected.
615 * @nbytes_remaining_p:
616 * Number of bytes of data remaining in the buffer pointed to by @p.
617 * On success this will be updated to point just past the ADS entries.
619 * On success, inode->i_ads_entries is set to an array of `struct
620 * wim_ads_entry's of length inode->i_num_ads. On failure, @inode is not
624 * WIMLIB_ERR_SUCCESS (0)
625 * WIMLIB_ERR_INVALID_METADATA_RESOURCE
629 read_ads_entries(const u8 * restrict p, struct wim_inode * restrict inode,
630 size_t *nbytes_remaining_p)
632 size_t nbytes_remaining = *nbytes_remaining_p;
634 struct wim_ads_entry *ads_entries;
637 BUILD_BUG_ON(sizeof(struct wim_ads_entry_on_disk) != WIM_ADS_ENTRY_DISK_SIZE);
639 /* Allocate an array for our in-memory representation of the alternate
640 * data stream entries. */
641 num_ads = inode->i_num_ads;
642 ads_entries = CALLOC(num_ads, sizeof(inode->i_ads_entries[0]));
646 /* Read the entries into our newly allocated buffer. */
647 for (unsigned i = 0; i < num_ads; i++) {
649 struct wim_ads_entry *cur_entry;
650 const struct wim_ads_entry_on_disk *disk_entry =
651 (const struct wim_ads_entry_on_disk*)p;
653 cur_entry = &ads_entries[i];
654 ads_entries[i].stream_id = i + 1;
656 /* Do we have at least the size of the fixed-length data we know
658 if (nbytes_remaining < sizeof(struct wim_ads_entry_on_disk))
661 /* Read the length field */
662 length = le64_to_cpu(disk_entry->length);
664 /* Make sure the length field is neither so small it doesn't
665 * include all the fixed-length data nor so large it overflows
666 * the metadata resource buffer. */
667 if (length < sizeof(struct wim_ads_entry_on_disk) ||
668 length > nbytes_remaining)
671 /* Read the rest of the fixed-length data. */
673 cur_entry->reserved = le64_to_cpu(disk_entry->reserved);
674 copy_hash(cur_entry->hash, disk_entry->hash);
675 cur_entry->stream_name_nbytes = le16_to_cpu(disk_entry->stream_name_nbytes);
677 /* If stream_name_nbytes != 0, this is a named stream.
678 * Otherwise this is an unnamed stream, or in some cases (bugs
679 * in Microsoft's software I guess) a meaningless entry
680 * distinguished from the real unnamed stream entry, if any, by
681 * the fact that the real unnamed stream entry has a nonzero
683 if (cur_entry->stream_name_nbytes) {
684 /* The name is encoded in UTF16-LE, which uses 2-byte
685 * coding units, so the length of the name had better be
686 * an even number of bytes... */
687 if (cur_entry->stream_name_nbytes & 1)
690 /* Add the length of the stream name to get the length
691 * we actually need to read. Make sure this isn't more
692 * than the specified length of the entry. */
693 if (sizeof(struct wim_ads_entry_on_disk) +
694 cur_entry->stream_name_nbytes > length)
697 cur_entry->stream_name = utf16le_dupz(disk_entry->stream_name,
698 cur_entry->stream_name_nbytes);
699 if (!cur_entry->stream_name)
702 /* Mark inode as having weird stream entries. */
703 inode->i_canonical_streams = 0;
706 /* It's expected that the size of every ADS entry is a multiple
707 * of 8. However, to be safe, I'm allowing the possibility of
708 * an ADS entry at the very end of the metadata resource ending
709 * unaligned. So although we still need to increment the input
710 * pointer by @length to reach the next ADS entry, it's possible
711 * that less than @length is actually remaining in the metadata
712 * resource. We should set the remaining bytes to 0 if this
714 length = (length + 7) & ~7;
716 if (nbytes_remaining < length)
717 nbytes_remaining = 0;
719 nbytes_remaining -= length;
721 inode->i_ads_entries = ads_entries;
722 inode->i_next_stream_id = inode->i_num_ads + 1;
723 *nbytes_remaining_p = nbytes_remaining;
727 ret = WIMLIB_ERR_NOMEM;
728 goto out_free_ads_entries;
730 ERROR("An alternate data stream entry is invalid");
731 ret = WIMLIB_ERR_INVALID_METADATA_RESOURCE;
732 out_free_ads_entries:
734 for (unsigned i = 0; i < num_ads; i++)
735 destroy_ads_entry(&ads_entries[i]);
742 /* Check a WIM inode for unusual field values. */
744 check_inode(struct wim_inode *inode, const struct wim_security_data *sd)
746 /* Check the security ID. -1 is valid and means "no security
747 * descriptor". Anything else has to be a valid index into the WIM
748 * image's security descriptors table. */
749 if (inode->i_security_id < -1 ||
750 (inode->i_security_id >= 0 &&
751 inode->i_security_id >= sd->num_entries))
753 WARNING("\"%"TS"\" has an invalid security ID (%d)",
754 inode_first_full_path(inode), inode->i_security_id);
755 inode->i_security_id = -1;
758 /* Make sure there is only one unnamed data stream. */
759 unsigned num_unnamed_streams = 0;
760 for (unsigned i = 0; i <= inode->i_num_ads; i++) {
762 hash = inode_stream_hash(inode, i);
763 if (inode_stream_name_nbytes(inode, i) == 0 && !is_zero_hash(hash))
764 num_unnamed_streams++;
766 if (num_unnamed_streams > 1) {
767 WARNING("\"%"TS"\" has multiple (%u) unnamed streams",
768 inode_first_full_path(inode), num_unnamed_streams);
769 /* We currently don't treat this as an error and will just end
770 * up using the first unnamed data stream in the inode. */
775 * Translate a single-instance stream entry into the pointer contained in the
776 * inode (or ads entry of an inode) that references it.
778 * This is only possible for "unhashed" streams, which are guaranteed to have
779 * only one reference, and that reference is guaranteed to be in a resolved
780 * inode. (It can't be in an unresolved inode, since that would imply the hash
783 struct wim_lookup_table_entry **
784 retrieve_lte_pointer(struct wim_lookup_table_entry *lte)
786 wimlib_assert(lte->unhashed);
787 struct wim_inode *inode = lte->back_inode;
788 u32 stream_id = lte->back_stream_id;
790 return &inode->i_lte;
791 for (unsigned i = 0; i < inode->i_num_ads; i++)
792 if (inode->i_ads_entries[i].stream_id == stream_id)
793 return &inode->i_ads_entries[i].lte;