]> wimlib.net Git - wimlib/blob - src/inode.c
inode.h, inode.c cleanup
[wimlib] / src / inode.c
1 /*
2  * inode.c
3  *
4  * Functions that operate on WIM inodes.
5  *
6  * See dentry.c for a description of the relationship between WIM dentries and
7  * WIM inodes.
8  */
9
10 /*
11  * Copyright (C) 2012, 2013, 2014 Eric Biggers
12  *
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
16  * later version.
17  *
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
21  * details.
22  *
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/.
25  */
26
27 #ifdef HAVE_CONFIG_H
28 #  include "config.h"
29 #endif
30
31 #include <errno.h>
32
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"
42
43 /* Allocate a new inode.  Set the timestamps to the current time.  */
44 struct wim_inode *
45 new_inode(void)
46 {
47         struct wim_inode *inode = new_timeless_inode();
48         if (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;
53         }
54         return inode;
55 }
56
57 /* Allocate a new inode.  Leave the timestamps zeroed out.  */
58 struct wim_inode *
59 new_timeless_inode(void)
60 {
61         struct wim_inode *inode = CALLOC(1, sizeof(struct wim_inode));
62         if (inode) {
63                 inode->i_security_id = -1;
64                 inode->i_nlink = 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);
70         }
71         return inode;
72 }
73
74 /* Decrement an inode's link count.  */
75 void
76 put_inode(struct wim_inode *inode)
77 {
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         #ifdef WITH_FUSE
83                 if (inode->i_num_opened_fds == 0)
84         #endif
85                         free_inode(inode);
86         }
87 }
88
89 /* Free memory allocated within an alternate data stream entry.  */
90 static void
91 destroy_ads_entry(struct wim_ads_entry *ads_entry)
92 {
93         FREE(ads_entry->stream_name);
94 }
95
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.  */
98 void
99 free_inode(struct wim_inode *inode)
100 {
101         if (unlikely(!inode))
102                 return;
103
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);
108         }
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);
115         FREE(inode);
116 }
117
118 /*
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
121  * with that name.
122  *
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.
125  *
126  * If NULL is returned, errno is set.
127  */
128 struct wim_ads_entry *
129 inode_get_ads_entry(struct wim_inode *inode, const tchar *stream_name)
130 {
131         int ret;
132         const utf16lechar *stream_name_utf16le;
133         size_t stream_name_utf16le_nbytes;
134         unsigned i;
135         struct wim_ads_entry *result;
136
137         if (inode->i_num_ads == 0) {
138                 errno = ENOENT;
139                 return NULL;
140         }
141
142         if (stream_name[0] == T('\0')) {
143                 errno = ENOENT;
144                 return NULL;
145         }
146
147         ret = tstr_get_utf16le_and_len(stream_name, &stream_name_utf16le,
148                                        &stream_name_utf16le_nbytes);
149         if (ret)
150                 return NULL;
151
152         i = 0;
153         result = NULL;
154         do {
155                 if (!cmp_utf16le_strings(inode->i_ads_entries[i].stream_name,
156                                          inode->i_ads_entries[i].stream_name_nbytes /
157                                                 sizeof(utf16lechar),
158                                          stream_name_utf16le,
159                                          stream_name_utf16le_nbytes /
160                                                 sizeof(utf16lechar),
161                                          default_ignore_case))
162                 {
163                         result = &inode->i_ads_entries[i];
164                         break;
165                 }
166         } while (++i != inode->i_num_ads);
167
168         tstr_put_utf16le(stream_name_utf16le);
169
170         if (!result)
171                 errno = ENOENT;
172         return result;
173 }
174
175 static struct wim_ads_entry *
176 do_inode_add_ads(struct wim_inode *inode,
177                  utf16lechar *stream_name, size_t stream_name_nbytes)
178 {
179         unsigned num_ads;
180         struct wim_ads_entry *ads_entries;
181         struct wim_ads_entry *new_entry;
182
183         if (unlikely(inode->i_num_ads >= 0xfffe)) {
184                 ERROR("File \"%"TS"\" has too many alternate data streams!",
185                       inode_first_full_path(inode));
186                 errno = EFBIG;
187                 return NULL;
188         }
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]));
192         if (!ads_entries)
193                 return NULL;
194
195         inode->i_ads_entries = ads_entries;
196
197         new_entry = &inode->i_ads_entries[num_ads - 1];
198
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;
204         return new_entry;
205 }
206
207 /*
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.
212  */
213 struct wim_ads_entry *
214 inode_add_ads_utf16le(struct wim_inode *inode,
215                       const utf16lechar *stream_name, size_t stream_name_nbytes)
216 {
217         utf16lechar *dup = NULL;
218         struct wim_ads_entry *result;
219
220         if (stream_name_nbytes) {
221                 dup = utf16le_dupz(stream_name, stream_name_nbytes);
222                 if (!dup)
223                         return NULL;
224         }
225
226         result = do_inode_add_ads(inode, dup, stream_name_nbytes);
227         if (!result)
228                 FREE(dup);
229         return result;
230 }
231
232 /*
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.
237  */
238 struct wim_ads_entry *
239 inode_add_ads(struct wim_inode *inode, const tchar *stream_name)
240 {
241         utf16lechar *stream_name_utf16le = NULL;
242         size_t stream_name_utf16le_nbytes = 0;
243         struct wim_ads_entry *result;
244
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))
250                         return NULL;
251
252         result = do_inode_add_ads(inode, stream_name_utf16le,
253                                   stream_name_utf16le_nbytes);
254         if (!result)
255                 FREE(stream_name_utf16le);
256         return result;
257 }
258
259 /*
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.
262  *
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.
266  */
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)
271 {
272         struct wim_ads_entry *new_entry;
273
274         wimlib_assert(inode->i_resolved);
275
276         new_entry = inode_add_ads(inode, name);
277         if (unlikely(!new_entry))
278                 return NULL;
279
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);
283                 return NULL;
284         }
285         return new_entry;
286 }
287
288 /* Remove an alternate data stream from a WIM inode.  */
289 void
290 inode_remove_ads(struct wim_inode *inode, struct wim_ads_entry *entry,
291                  struct wim_lookup_table *lookup_table)
292 {
293         struct wim_lookup_table_entry *lte;
294         unsigned idx = entry - inode->i_ads_entries;
295
296         wimlib_assert(idx < inode->i_num_ads);
297         wimlib_assert(inode->i_resolved);
298
299         lte = entry->lte;
300         if (lte)
301                 lte_decrement_refcnt(lte, lookup_table);
302
303         destroy_ads_entry(entry);
304
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]));
308         inode->i_num_ads--;
309 }
310
311 /* Return true iff the specified inode has at least one named data stream.  */
312 bool
313 inode_has_named_stream(const struct wim_inode *inode)
314 {
315         for (unsigned i = 0; i < inode->i_num_ads; i++)
316                 if (inode->i_ads_entries[i].stream_name_nbytes)
317                         return true;
318         return false;
319 }
320
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
323  * unnamed stream.  */
324 int
325 inode_set_unnamed_stream(struct wim_inode *inode, const void *data, size_t len,
326                          struct wim_lookup_table *lookup_table)
327 {
328         wimlib_assert(inode->i_resolved);
329         wimlib_assert(!inode->i_lte);
330
331         inode->i_lte = new_stream_from_data_buffer(data, len, lookup_table);
332         if (!inode->i_lte)
333                 return WIMLIB_ERR_NOMEM;
334         return 0;
335 }
336
337 /*
338  * Resolve an inode's single-instance streams.
339  *
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.
344  *
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.
353  *
354  * If the inode is already resolved, this function does nothing.
355  *
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.
359  */
360 int
361 inode_resolve_streams(struct wim_inode *inode, struct wim_lookup_table *table,
362                       bool force)
363 {
364         const u8 *hash;
365         struct wim_lookup_table_entry *lte, *ads_lte;
366
367         if (inode->i_resolved)
368                 return 0;
369
370         struct wim_lookup_table_entry *ads_ltes[inode->i_num_ads];
371
372         /* Resolve the default data stream */
373         lte = NULL;
374         hash = inode->i_hash;
375         if (!is_zero_hash(hash)) {
376                 lte = lookup_stream(table, hash);
377                 if (!lte) {
378                         if (force) {
379                                 lte = new_lookup_table_entry();
380                                 if (!lte)
381                                         return WIMLIB_ERR_NOMEM;
382                                 copy_hash(lte->hash, hash);
383                                 lookup_table_insert(table, lte);
384                         } else {
385                                 goto stream_not_found;
386                         }
387                 }
388         }
389
390         /* Resolve the alternate data streams */
391         for (unsigned i = 0; i < inode->i_num_ads; i++) {
392                 struct wim_ads_entry *cur_entry;
393
394                 ads_lte = NULL;
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);
399                         if (!ads_lte) {
400                                 if (force) {
401                                         ads_lte = new_lookup_table_entry();
402                                         if (!ads_lte)
403                                                 return WIMLIB_ERR_NOMEM;
404                                         copy_hash(ads_lte->hash, hash);
405                                         lookup_table_insert(table, ads_lte);
406                                 } else {
407                                         goto stream_not_found;
408                                 }
409                         }
410                 }
411                 ads_ltes[i] = ads_lte;
412         }
413         inode->i_lte = 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;
417         return 0;
418
419 stream_not_found:
420         return stream_not_found_error(inode, hash);
421 }
422
423 /*
424  * Undo the effects of inode_resolve_streams().
425  *
426  * If the inode is not resolved, this function does nothing.
427  */
428 void
429 inode_unresolve_streams(struct wim_inode *inode)
430 {
431         if (!inode->i_resolved)
432                 return;
433
434         if (inode->i_lte)
435                 copy_hash(inode->i_hash, inode->i_lte->hash);
436         else
437                 zero_out_hash(inode->i_hash);
438
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);
443                 else
444                         zero_out_hash(inode->i_ads_entries[i].hash);
445         }
446         inode->i_resolved = 0;
447 }
448
449 int
450 stream_not_found_error(const struct wim_inode *inode, const u8 *hash)
451 {
452         if (wimlib_print_errors) {
453                 tchar hashstr[SHA1_HASH_SIZE * 2 + 1];
454
455                 sprint_hash(hash, hashstr);
456
457                 ERROR("\"%"TS"\": stream not found\n"
458                       "        SHA-1 message digest of missing stream:\n"
459                       "        %"TS"",
460                       inode_first_full_path(inode), hashstr);
461         }
462         return WIMLIB_ERR_RESOURCE_NOT_FOUND;
463 }
464
465 /*
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.
468  *
469  * stream_idx = 0: default data stream
470  * stream_idx > 0: alternate data stream
471  */
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)
475 {
476         if (inode->i_resolved)
477                 return inode_stream_lte_resolved(inode, stream_idx);
478         if (stream_idx == 0)
479                 return lookup_stream(table, inode->i_hash);
480         return lookup_stream(table, inode->i_ads_entries[stream_idx - 1].hash);
481 }
482
483 /*
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.
487  */
488 struct wim_lookup_table_entry *
489 inode_unnamed_stream_resolved(const struct wim_inode *inode,
490                               unsigned *stream_idx_ret)
491 {
492         wimlib_assert(inode->i_resolved);
493
494         *stream_idx_ret = 0;
495         if (likely(inode->i_lte))
496                 return inode->i_lte;
497
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)
501                 {
502                         *stream_idx_ret = i + 1;
503                         return inode->i_ads_entries[i].lte;
504                 }
505         }
506         return NULL;
507 }
508
509 /*
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.
512  *
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.
515  */
516 struct wim_lookup_table_entry *
517 inode_unnamed_lte(const struct wim_inode *inode,
518                   const struct wim_lookup_table *table)
519 {
520         struct wim_lookup_table_entry *lte;
521
522         if (inode->i_resolved)
523                 return inode_unnamed_lte_resolved(inode);
524
525         lte = lookup_stream(table, inode->i_hash);
526         if (likely(lte))
527                 return lte;
528
529         for (unsigned i = 0; i < inode->i_num_ads; i++) {
530                 if (inode->i_ads_entries[i].stream_name_nbytes)
531                         continue;
532                 lte = lookup_stream(table, inode->i_ads_entries[i].hash);
533                 if (lte)
534                         return lte;
535         }
536         return NULL;
537 }
538
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.   */
541 const u8 *
542 inode_stream_hash(const struct wim_inode *inode, unsigned stream_idx)
543 {
544         if (inode->i_resolved) {
545                 struct wim_lookup_table_entry *lte;
546
547                 lte = inode_stream_lte_resolved(inode, stream_idx);
548                 if (lte)
549                         return lte->hash;
550                 return zero_hash;
551         }
552         if (stream_idx == 0)
553                 return inode->i_hash;
554         return inode->i_ads_entries[stream_idx - 1].hash;
555 }
556
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.   */
559 const u8 *
560 inode_unnamed_stream_hash(const struct wim_inode *inode)
561 {
562         const u8 *hash;
563
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))
568                                 return hash;
569                 }
570         }
571         return zero_hash;
572 }
573
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.
576  *
577  * The inode must be resolved.  */
578 void
579 inode_ref_streams(struct wim_inode *inode)
580 {
581         wimlib_assert(inode->i_resolved);
582
583         if (inode->i_lte)
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++;
588 }
589
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.  */
592 void
593 inode_unref_streams(struct wim_inode *inode,
594                     struct wim_lookup_table *lookup_table)
595 {
596         for (unsigned i = 0; i <= inode->i_num_ads; i++) {
597                 struct wim_lookup_table_entry *lte;
598
599                 lte = inode_stream_lte(inode, i, lookup_table);
600                 if (lte)
601                         lte_decrement_refcnt(lte, lookup_table);
602         }
603 }
604
605 /*
606  * Read the alternate data stream entries of a WIM dentry.
607  *
608  * @p:
609  *      Pointer to buffer that starts with the first alternate stream entry.
610  *
611  * @inode:
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.
614  *
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.
618  *
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
621  * modified.
622  *
623  * Return values:
624  *      WIMLIB_ERR_SUCCESS (0)
625  *      WIMLIB_ERR_INVALID_METADATA_RESOURCE
626  *      WIMLIB_ERR_NOMEM
627  */
628 int
629 read_ads_entries(const u8 * restrict p, struct wim_inode * restrict inode,
630                  size_t *nbytes_remaining_p)
631 {
632         size_t nbytes_remaining = *nbytes_remaining_p;
633         unsigned num_ads;
634         struct wim_ads_entry *ads_entries;
635         int ret;
636
637         BUILD_BUG_ON(sizeof(struct wim_ads_entry_on_disk) != WIM_ADS_ENTRY_DISK_SIZE);
638
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]));
643         if (!ads_entries)
644                 goto out_of_memory;
645
646         /* Read the entries into our newly allocated buffer. */
647         for (unsigned i = 0; i < num_ads; i++) {
648                 u64 length;
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;
652
653                 cur_entry = &ads_entries[i];
654                 ads_entries[i].stream_id = i + 1;
655
656                 /* Do we have at least the size of the fixed-length data we know
657                  * need? */
658                 if (nbytes_remaining < sizeof(struct wim_ads_entry_on_disk))
659                         goto out_invalid;
660
661                 /* Read the length field */
662                 length = le64_to_cpu(disk_entry->length);
663
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)
669                         goto out_invalid;
670
671                 /* Read the rest of the fixed-length data. */
672
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);
676
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
682                  * hash field. */
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)
688                                 goto out_invalid;
689
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)
695                                 goto out_invalid;
696
697                         cur_entry->stream_name = utf16le_dupz(disk_entry->stream_name,
698                                                               cur_entry->stream_name_nbytes);
699                         if (!cur_entry->stream_name)
700                                 goto out_of_memory;
701                 } else {
702                         /* Mark inode as having weird stream entries.  */
703                         inode->i_canonical_streams = 0;
704                 }
705
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
713                  * happens. */
714                 length = (length + 7) & ~7;
715                 p += length;
716                 if (nbytes_remaining < length)
717                         nbytes_remaining = 0;
718                 else
719                         nbytes_remaining -= length;
720         }
721         inode->i_ads_entries = ads_entries;
722         inode->i_next_stream_id = inode->i_num_ads + 1;
723         *nbytes_remaining_p = nbytes_remaining;
724         ret = 0;
725         goto out;
726 out_of_memory:
727         ret = WIMLIB_ERR_NOMEM;
728         goto out_free_ads_entries;
729 out_invalid:
730         ERROR("An alternate data stream entry is invalid");
731         ret = WIMLIB_ERR_INVALID_METADATA_RESOURCE;
732 out_free_ads_entries:
733         if (ads_entries) {
734                 for (unsigned i = 0; i < num_ads; i++)
735                         destroy_ads_entry(&ads_entries[i]);
736                 FREE(ads_entries);
737         }
738 out:
739         return ret;
740 }
741
742 /* Check a WIM inode for unusual field values.  */
743 void
744 check_inode(struct wim_inode *inode, const struct wim_security_data *sd)
745 {
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))
752         {
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;
756         }
757
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++) {
761                 const u8 *hash;
762                 hash = inode_stream_hash(inode, i);
763                 if (inode_stream_name_nbytes(inode, i) == 0 && !is_zero_hash(hash))
764                         num_unnamed_streams++;
765         }
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.  */
771         }
772 }
773
774 /*
775  * Translate a single-instance stream entry into the pointer contained in the
776  * inode (or ads entry of an inode) that references it.
777  *
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
781  * is known!)
782  */
783 struct wim_lookup_table_entry **
784 retrieve_lte_pointer(struct wim_lookup_table_entry *lte)
785 {
786         wimlib_assert(lte->unhashed);
787         struct wim_inode *inode = lte->back_inode;
788         u32 stream_id = lte->back_stream_id;
789         if (stream_id == 0)
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;
794         wimlib_assert(0);
795         return NULL;
796 }