]> wimlib.net Git - wimlib/blob - src/inode.c
inode_set_unnamed_stream(): inode must be resolved
[wimlib] / src / inode.c
1 /*
2  * inode.c
3  */
4
5 /*
6  * Copyright (C) 2012, 2013 Eric Biggers
7  *
8  * This file is part of wimlib, a library for working with WIM files.
9  *
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)
13  * any later version.
14  *
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
18  * details.
19  *
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/.
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #  include "config.h"
26 #endif
27
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.
32                             */
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"
41
42 /* Allocate a new inode.  Set the timestamps to the current time.  */
43 struct wim_inode *
44 new_inode(void)
45 {
46         struct wim_inode *inode = new_timeless_inode();
47         if (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;
52         }
53         return inode;
54 }
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 link count on an inode.  */
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                  * inode_put_fd() in mount_image.c handles dropping a file
83                  * descriptor.  */
84         #ifdef WITH_FUSE
85                 if (inode->i_num_opened_fds == 0)
86         #endif
87                         free_inode(inode);
88         }
89 }
90
91 /* De-allocate memory for an alternate data stream entry.  */
92 static void
93 destroy_ads_entry(struct wim_ads_entry *ads_entry)
94 {
95         FREE(ads_entry->stream_name);
96 }
97
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.  */
100 void
101 free_inode(struct wim_inode *inode)
102 {
103         if (inode == NULL)
104                 return;
105
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);
110         }
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 /* Return %true iff the alternate data stream entry @entry has the UTF-16LE
119  * stream name @name that has length @name_nbytes bytes.  */
120 static inline bool
121 ads_entry_has_name(const struct wim_ads_entry *entry,
122                    const utf16lechar *name, size_t name_nbytes,
123                    bool ignore_case)
124 {
125         return 0 == cmp_utf16le_strings(name,
126                                         name_nbytes / 2,
127                                         entry->stream_name,
128                                         entry->stream_name_nbytes / 2,
129                                         ignore_case);
130 }
131
132 /*
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
135  * with that name.
136  *
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.
139  */
140 struct wim_ads_entry *
141 inode_get_ads_entry(struct wim_inode *inode, const tchar *stream_name,
142                     u16 *idx_ret)
143 {
144         int ret;
145         const utf16lechar *stream_name_utf16le;
146         size_t stream_name_utf16le_nbytes;
147         u16 i;
148         struct wim_ads_entry *result;
149
150         if (inode->i_num_ads == 0)
151                 return NULL;
152
153         if (stream_name[0] == T('\0'))
154                 return NULL;
155
156         ret = tstr_get_utf16le_and_len(stream_name, &stream_name_utf16le,
157                                        &stream_name_utf16le_nbytes);
158         if (ret)
159                 return NULL;
160
161         i = 0;
162         result = NULL;
163         do {
164                 if (ads_entry_has_name(&inode->i_ads_entries[i],
165                                        stream_name_utf16le,
166                                        stream_name_utf16le_nbytes,
167                                        default_ignore_case))
168                 {
169                         if (idx_ret)
170                                 *idx_ret = i;
171                         result = &inode->i_ads_entries[i];
172                         break;
173                 }
174         } while (++i != inode->i_num_ads);
175
176         tstr_put_utf16le(stream_name_utf16le);
177
178         return result;
179 }
180
181 static struct wim_ads_entry *
182 do_inode_add_ads(struct wim_inode *inode,
183                  utf16lechar *stream_name, size_t stream_name_nbytes)
184 {
185         u16 num_ads;
186         struct wim_ads_entry *ads_entries;
187         struct wim_ads_entry *new_entry;
188
189         if (inode->i_num_ads >= 0xfffe) {
190                 ERROR("Too many alternate data streams in one inode!");
191                 return NULL;
192         }
193         num_ads = inode->i_num_ads + 1;
194         ads_entries = REALLOC(inode->i_ads_entries,
195                               num_ads * sizeof(inode->i_ads_entries[0]));
196         if (ads_entries == NULL) {
197                 ERROR("Failed to allocate memory for new alternate data stream");
198                 return NULL;
199         }
200         inode->i_ads_entries = ads_entries;
201
202         new_entry = &inode->i_ads_entries[num_ads - 1];
203
204         memset(new_entry, 0, sizeof(struct wim_ads_entry));
205         new_entry->stream_name = stream_name;
206         new_entry->stream_name_nbytes = stream_name_nbytes;
207         new_entry->stream_id = inode->i_next_stream_id++;
208         inode->i_num_ads = num_ads;
209         return new_entry;
210 }
211
212 struct wim_ads_entry *
213 inode_add_ads_utf16le(struct wim_inode *inode,
214                       const utf16lechar *stream_name, size_t stream_name_nbytes)
215 {
216         utf16lechar *dup = NULL;
217         struct wim_ads_entry *result;
218
219         if (stream_name_nbytes) {
220                 dup = utf16le_dupz(stream_name, stream_name_nbytes);
221                 if (!dup)
222                         return NULL;
223         }
224
225         result = do_inode_add_ads(inode, dup, stream_name_nbytes);
226         if (!result)
227                 FREE(dup);
228         return result;
229 }
230
231 /*
232  * Add an alternate stream entry to a WIM inode.  On success, returns a pointer
233  * to the new entry; on failure, returns NULL.
234  */
235 struct wim_ads_entry *
236 inode_add_ads(struct wim_inode *inode, const tchar *stream_name)
237 {
238         utf16lechar *stream_name_utf16le = NULL;
239         size_t stream_name_utf16le_nbytes = 0;
240         int ret;
241         struct wim_ads_entry *result;
242
243         if (stream_name && *stream_name) {
244                 ret = tstr_to_utf16le(stream_name,
245                                       tstrlen(stream_name) * sizeof(tchar),
246                                       &stream_name_utf16le,
247                                       &stream_name_utf16le_nbytes);
248                 if (ret)
249                         return NULL;
250         }
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 int
260 inode_add_ads_with_data(struct wim_inode *inode, const tchar *name,
261                         const void *value, size_t size,
262                         struct wim_lookup_table *lookup_table)
263 {
264         struct wim_ads_entry *new_ads_entry;
265
266         wimlib_assert(inode->i_resolved);
267
268         new_ads_entry = inode_add_ads(inode, name);
269         if (new_ads_entry == NULL)
270                 return WIMLIB_ERR_NOMEM;
271
272         new_ads_entry->lte = new_stream_from_data_buffer(value, size,
273                                                          lookup_table);
274         if (new_ads_entry->lte == NULL) {
275                 inode_remove_ads(inode, new_ads_entry - inode->i_ads_entries,
276                                  lookup_table);
277                 return WIMLIB_ERR_NOMEM;
278         }
279         return 0;
280 }
281
282 bool
283 inode_has_named_stream(const struct wim_inode *inode)
284 {
285         for (u16 i = 0; i < inode->i_num_ads; i++)
286                 if (ads_entry_is_named_stream(&inode->i_ads_entries[i]))
287                         return true;
288         return false;
289 }
290
291 /* Set the unnamed stream of a WIM inode, given a data buffer containing the
292  * stream contents. */
293 int
294 inode_set_unnamed_stream(struct wim_inode *inode, const void *data, size_t len,
295                          struct wim_lookup_table *lookup_table)
296 {
297         wimlib_assert(inode->i_resolved);
298         inode->i_lte = new_stream_from_data_buffer(data, len, lookup_table);
299         if (inode->i_lte == NULL)
300                 return WIMLIB_ERR_NOMEM;
301         return 0;
302 }
303
304 /* Remove an alternate data stream from a WIM inode  */
305 void
306 inode_remove_ads(struct wim_inode *inode, u16 idx,
307                  struct wim_lookup_table *lookup_table)
308 {
309         struct wim_ads_entry *ads_entry;
310         struct wim_lookup_table_entry *lte;
311
312         wimlib_assert(idx < inode->i_num_ads);
313         wimlib_assert(inode->i_resolved);
314
315         ads_entry = &inode->i_ads_entries[idx];
316
317         DEBUG("Remove alternate data stream \"%"WS"\"", ads_entry->stream_name);
318
319         lte = ads_entry->lte;
320         if (lte)
321                 lte_decrement_refcnt(lte, lookup_table);
322
323         destroy_ads_entry(ads_entry);
324
325         memmove(&inode->i_ads_entries[idx],
326                 &inode->i_ads_entries[idx + 1],
327                 (inode->i_num_ads - idx - 1) * sizeof(inode->i_ads_entries[0]));
328         inode->i_num_ads--;
329 }
330
331 bool
332 inode_has_unix_data(const struct wim_inode *inode)
333 {
334         for (u16 i = 0; i < inode->i_num_ads; i++)
335                 if (ads_entry_is_unix_data(&inode->i_ads_entries[i]))
336                         return true;
337         return false;
338 }
339
340 #ifndef __WIN32__
341 int
342 inode_get_unix_data(const struct wim_inode *inode,
343                     struct wimlib_unix_data *unix_data,
344                     u16 *stream_idx_ret)
345 {
346         const struct wim_ads_entry *ads_entry;
347         const struct wim_lookup_table_entry *lte;
348         size_t size;
349         int ret;
350
351         wimlib_assert(inode->i_resolved);
352
353         ads_entry = inode_get_ads_entry((struct wim_inode*)inode,
354                                         WIMLIB_UNIX_DATA_TAG, NULL);
355         if (ads_entry == NULL)
356                 return NO_UNIX_DATA;
357
358         if (stream_idx_ret)
359                 *stream_idx_ret = ads_entry - inode->i_ads_entries;
360
361         lte = ads_entry->lte;
362         if (lte == NULL)
363                 return NO_UNIX_DATA;
364
365         size = lte->size;
366         if (size != sizeof(struct wimlib_unix_data))
367                 return BAD_UNIX_DATA;
368
369         ret = read_full_stream_into_buf(lte, unix_data);
370         if (ret)
371                 return ret;
372
373         if (unix_data->version != 0)
374                 return BAD_UNIX_DATA;
375         return 0;
376 }
377
378 int
379 inode_set_unix_data(struct wim_inode *inode, u16 uid, u16 gid, u16 mode,
380                     struct wim_lookup_table *lookup_table, int which)
381 {
382         struct wimlib_unix_data unix_data;
383         int ret;
384         bool have_good_unix_data = false;
385         bool have_unix_data = false;
386         u16 stream_idx;
387
388         if (!(which & UNIX_DATA_CREATE)) {
389                 ret = inode_get_unix_data(inode, &unix_data, &stream_idx);
390                 if (ret == 0 || ret == BAD_UNIX_DATA || ret > 0)
391                         have_unix_data = true;
392                 if (ret == 0)
393                         have_good_unix_data = true;
394         }
395         unix_data.version = 0;
396         if (which & UNIX_DATA_UID || !have_good_unix_data)
397                 unix_data.uid = uid;
398         if (which & UNIX_DATA_GID || !have_good_unix_data)
399                 unix_data.gid = gid;
400         if (which & UNIX_DATA_MODE || !have_good_unix_data)
401                 unix_data.mode = mode;
402         ret = inode_add_ads_with_data(inode, WIMLIB_UNIX_DATA_TAG,
403                                       &unix_data,
404                                       sizeof(struct wimlib_unix_data),
405                                       lookup_table);
406         if (ret == 0 && have_unix_data)
407                 inode_remove_ads(inode, stream_idx, lookup_table);
408         return ret;
409 }
410 #endif /* __WIN32__  */
411
412 /*
413  * Resolve an inode's lookup table entries.
414  *
415  * This replaces the SHA1 hash fields (which are used to lookup an entry in the
416  * lookup table) with pointers directly to the lookup table entries.
417  *
418  * If @force is %false:
419  *      If any needed SHA1 message digests are not found in the lookup table,
420  *      WIMLIB_ERR_RESOURCE_NOT_FOUND is returned and the inode is left
421  *      unmodified.
422  * If @force is %true:
423  *      If any needed SHA1 message digests are not found in the lookup table,
424  *      new entries are allocated and inserted into the lookup table.
425  */
426 int
427 inode_resolve_streams(struct wim_inode *inode, struct wim_lookup_table *table,
428                       bool force)
429 {
430         const u8 *hash;
431
432         if (!inode->i_resolved) {
433                 struct wim_lookup_table_entry *lte, *ads_lte;
434
435                 /* Resolve the default file stream */
436                 lte = NULL;
437                 hash = inode->i_hash;
438                 if (!is_zero_hash(hash)) {
439                         lte = lookup_stream(table, hash);
440                         if (!lte) {
441                                 if (force) {
442                                         lte = new_lookup_table_entry();
443                                         if (!lte)
444                                                 return WIMLIB_ERR_NOMEM;
445                                         copy_hash(lte->hash, hash);
446                                         lookup_table_insert(table, lte);
447                                 } else {
448                                         goto stream_not_found;
449                                 }
450                         }
451                 }
452
453                 /* Resolve the alternate data streams */
454                 struct wim_lookup_table_entry *ads_ltes[inode->i_num_ads];
455                 for (u16 i = 0; i < inode->i_num_ads; i++) {
456                         struct wim_ads_entry *cur_entry;
457
458                         ads_lte = NULL;
459                         cur_entry = &inode->i_ads_entries[i];
460                         hash = cur_entry->hash;
461                         if (!is_zero_hash(hash)) {
462                                 ads_lte = lookup_stream(table, hash);
463                                 if (!ads_lte) {
464                                         if (force) {
465                                                 ads_lte = new_lookup_table_entry();
466                                                 if (!ads_lte)
467                                                         return WIMLIB_ERR_NOMEM;
468                                                 copy_hash(ads_lte->hash, hash);
469                                                 lookup_table_insert(table, ads_lte);
470                                         } else {
471                                                 goto stream_not_found;
472                                         }
473                                 }
474                         }
475                         ads_ltes[i] = ads_lte;
476                 }
477                 inode->i_lte = lte;
478                 for (u16 i = 0; i < inode->i_num_ads; i++)
479                         inode->i_ads_entries[i].lte = ads_ltes[i];
480                 inode->i_resolved = 1;
481         }
482         return 0;
483
484 stream_not_found:
485         return stream_not_found_error(inode, hash);
486 }
487
488 void
489 inode_unresolve_streams(struct wim_inode *inode)
490 {
491         if (inode->i_resolved) {
492                 if (inode->i_lte)
493                         copy_hash(inode->i_hash, inode->i_lte->hash);
494                 else
495                         zero_out_hash(inode->i_hash);
496
497                 for (u16 i = 0; i < inode->i_num_ads; i++) {
498                         if (inode->i_ads_entries[i].lte)
499                                 copy_hash(inode->i_ads_entries[i].hash,
500                                           inode->i_ads_entries[i].lte->hash);
501                         else
502                                 zero_out_hash(inode->i_ads_entries[i].hash);
503                 }
504                 inode->i_resolved = 0;
505         }
506 }
507
508 /*
509  * Returns the lookup table entry for stream @stream_idx of the inode, where
510  * stream_idx = 0 means the default un-named file stream, and stream_idx >= 1
511  * corresponds to an alternate data stream.
512  *
513  * This works for both resolved and un-resolved inodes.
514  */
515 struct wim_lookup_table_entry *
516 inode_stream_lte(const struct wim_inode *inode, unsigned stream_idx,
517                  const struct wim_lookup_table *table)
518 {
519         if (inode->i_resolved)
520                 return inode_stream_lte_resolved(inode, stream_idx);
521         else
522                 return inode_stream_lte_unresolved(inode, stream_idx, table);
523 }
524
525 struct wim_lookup_table_entry *
526 inode_unnamed_stream_resolved(const struct wim_inode *inode, u16 *stream_idx_ret)
527 {
528         wimlib_assert(inode->i_resolved);
529         for (unsigned i = 0; i <= inode->i_num_ads; i++) {
530                 if (inode_stream_name_nbytes(inode, i) == 0 &&
531                     !is_zero_hash(inode_stream_hash_resolved(inode, i)))
532                 {
533                         *stream_idx_ret = i;
534                         return inode_stream_lte_resolved(inode, i);
535                 }
536         }
537         *stream_idx_ret = 0;
538         return NULL;
539 }
540
541 struct wim_lookup_table_entry *
542 inode_unnamed_lte_resolved(const struct wim_inode *inode)
543 {
544         u16 stream_idx;
545         return inode_unnamed_stream_resolved(inode, &stream_idx);
546 }
547
548 struct wim_lookup_table_entry *
549 inode_unnamed_lte_unresolved(const struct wim_inode *inode,
550                              const struct wim_lookup_table *table)
551 {
552         wimlib_assert(!inode->i_resolved);
553         for (unsigned i = 0; i <= inode->i_num_ads; i++) {
554                 if (inode_stream_name_nbytes(inode, i) == 0 &&
555                     !is_zero_hash(inode_stream_hash_unresolved(inode, i)))
556                 {
557                         return inode_stream_lte_unresolved(inode, i, table);
558                 }
559         }
560         return NULL;
561 }
562
563 /* Return the lookup table entry for the unnamed data stream of an inode, or
564  * NULL if there is none.
565  *
566  * You'd think this would be easier than it actually is, since the unnamed data
567  * stream should be the one referenced from the inode itself.  Alas, if there
568  * are named data streams, Microsoft's "imagex.exe" program will put the unnamed
569  * data stream in one of the alternate data streams instead of inside the WIM
570  * dentry itself.  So we need to check the alternate data streams too.
571  *
572  * Also, note that a dentry may appear to have more than one unnamed stream, but
573  * if the SHA1 message digest is all 0's then the corresponding stream does not
574  * really "count" (this is the case for the inode's own file stream when the
575  * file stream that should be there is actually in one of the alternate stream
576  * entries.).  This is despite the fact that we may need to extract such a
577  * missing entry as an empty file or empty named data stream.
578  */
579 struct wim_lookup_table_entry *
580 inode_unnamed_lte(const struct wim_inode *inode,
581                   const struct wim_lookup_table *table)
582 {
583         if (inode->i_resolved)
584                 return inode_unnamed_lte_resolved(inode);
585         else
586                 return inode_unnamed_lte_unresolved(inode, table);
587 }
588
589 /* Returns the SHA1 message digest of the unnamed data stream of a WIM inode, or
590  * 'zero_hash' if the unnamed data stream is missing has all zeroes in its SHA1
591  * message digest field.  */
592 const u8 *
593 inode_unnamed_stream_hash(const struct wim_inode *inode)
594 {
595         const u8 *hash;
596
597         for (unsigned i = 0; i <= inode->i_num_ads; i++) {
598                 if (inode_stream_name_nbytes(inode, i) == 0) {
599                         hash = inode_stream_hash(inode, i);
600                         if (!is_zero_hash(hash))
601                                 return hash;
602                 }
603         }
604         return zero_hash;
605 }
606
607 /* Given an unhashed stream, get the pointer to it in an inode.
608  * As this is only for unhashed streams, there can only be one such pointer.  */
609 struct wim_lookup_table_entry **
610 retrieve_lte_pointer(struct wim_lookup_table_entry *lte)
611 {
612         wimlib_assert(lte->unhashed);
613         struct wim_inode *inode = lte->back_inode;
614         u32 stream_id = lte->back_stream_id;
615         if (stream_id == 0)
616                 return &inode->i_lte;
617         else
618                 for (u16 i = 0; i < inode->i_num_ads; i++)
619                         if (inode->i_ads_entries[i].stream_id == stream_id)
620                                 return &inode->i_ads_entries[i].lte;
621         wimlib_assert(0);
622         return NULL;
623 }
624
625 int
626 stream_not_found_error(const struct wim_inode *inode, const u8 *hash)
627 {
628         if (wimlib_print_errors) {
629                 ERROR("\"%"TS"\": stream not found", inode_first_full_path(inode));
630                 tfprintf(stderr, T("        SHA-1 message digest of missing stream:\n        "));
631                 print_hash(hash, stderr);
632                 tputc(T('\n'), stderr);
633         }
634         return WIMLIB_ERR_RESOURCE_NOT_FOUND;
635 }
636
637 /*
638  * Reads the alternate data stream entries of a WIM dentry.
639  *
640  * @p:
641  *      Pointer to buffer that starts with the first alternate stream entry.
642  *
643  * @inode:
644  *      Inode to load the alternate data streams into.  @inode->i_num_ads must
645  *      have been set to the number of alternate data streams that are expected.
646  *
647  * @remaining_size:
648  *      Number of bytes of data remaining in the buffer pointed to by @p.
649  *
650  * On success, inode->i_ads_entries is set to an array of `struct
651  * wim_ads_entry's of length inode->i_num_ads.  On failure, @inode is not
652  * modified.
653  *
654  * Return values:
655  *      WIMLIB_ERR_SUCCESS (0)
656  *      WIMLIB_ERR_INVALID_METADATA_RESOURCE
657  *      WIMLIB_ERR_NOMEM
658  */
659 int
660 read_ads_entries(const u8 * restrict p, struct wim_inode * restrict inode,
661                  size_t nbytes_remaining)
662 {
663         u16 num_ads;
664         struct wim_ads_entry *ads_entries;
665         int ret;
666
667         BUILD_BUG_ON(sizeof(struct wim_ads_entry_on_disk) != WIM_ADS_ENTRY_DISK_SIZE);
668
669         /* Allocate an array for our in-memory representation of the alternate
670          * data stream entries. */
671         num_ads = inode->i_num_ads;
672         ads_entries = CALLOC(num_ads, sizeof(inode->i_ads_entries[0]));
673         if (ads_entries == NULL)
674                 goto out_of_memory;
675
676         /* Read the entries into our newly allocated buffer. */
677         for (u16 i = 0; i < num_ads; i++) {
678                 u64 length;
679                 struct wim_ads_entry *cur_entry;
680                 const struct wim_ads_entry_on_disk *disk_entry =
681                         (const struct wim_ads_entry_on_disk*)p;
682
683                 cur_entry = &ads_entries[i];
684                 ads_entries[i].stream_id = i + 1;
685
686                 /* Do we have at least the size of the fixed-length data we know
687                  * need? */
688                 if (nbytes_remaining < sizeof(struct wim_ads_entry_on_disk))
689                         goto out_invalid;
690
691                 /* Read the length field */
692                 length = le64_to_cpu(disk_entry->length);
693
694                 /* Make sure the length field is neither so small it doesn't
695                  * include all the fixed-length data nor so large it overflows
696                  * the metadata resource buffer. */
697                 if (length < sizeof(struct wim_ads_entry_on_disk) ||
698                     length > nbytes_remaining)
699                         goto out_invalid;
700
701                 /* Read the rest of the fixed-length data. */
702
703                 cur_entry->reserved = le64_to_cpu(disk_entry->reserved);
704                 copy_hash(cur_entry->hash, disk_entry->hash);
705                 cur_entry->stream_name_nbytes = le16_to_cpu(disk_entry->stream_name_nbytes);
706
707                 /* If stream_name_nbytes != 0, this is a named stream.
708                  * Otherwise this is an unnamed stream, or in some cases (bugs
709                  * in Microsoft's software I guess) a meaningless entry
710                  * distinguished from the real unnamed stream entry, if any, by
711                  * the fact that the real unnamed stream entry has a nonzero
712                  * hash field. */
713                 if (cur_entry->stream_name_nbytes) {
714                         /* The name is encoded in UTF16-LE, which uses 2-byte
715                          * coding units, so the length of the name had better be
716                          * an even number of bytes... */
717                         if (cur_entry->stream_name_nbytes & 1)
718                                 goto out_invalid;
719
720                         /* Add the length of the stream name to get the length
721                          * we actually need to read.  Make sure this isn't more
722                          * than the specified length of the entry. */
723                         if (sizeof(struct wim_ads_entry_on_disk) +
724                             cur_entry->stream_name_nbytes > length)
725                                 goto out_invalid;
726
727                         cur_entry->stream_name = utf16le_dupz(disk_entry->stream_name,
728                                                               cur_entry->stream_name_nbytes);
729                         if (cur_entry->stream_name == NULL)
730                                 goto out_of_memory;
731                 } else {
732                         /* Mark inode as having weird stream entries.  */
733                         inode->i_canonical_streams = 0;
734                 }
735
736                 /* It's expected that the size of every ADS entry is a multiple
737                  * of 8.  However, to be safe, I'm allowing the possibility of
738                  * an ADS entry at the very end of the metadata resource ending
739                  * un-aligned.  So although we still need to increment the input
740                  * pointer by @length to reach the next ADS entry, it's possible
741                  * that less than @length is actually remaining in the metadata
742                  * resource. We should set the remaining bytes to 0 if this
743                  * happens. */
744                 length = (length + 7) & ~(u64)7;
745                 p += length;
746                 if (nbytes_remaining < length)
747                         nbytes_remaining = 0;
748                 else
749                         nbytes_remaining -= length;
750         }
751         inode->i_ads_entries = ads_entries;
752         inode->i_next_stream_id = inode->i_num_ads + 1;
753         ret = 0;
754         goto out;
755 out_of_memory:
756         ret = WIMLIB_ERR_NOMEM;
757         goto out_free_ads_entries;
758 out_invalid:
759         ERROR("An alternate data stream entry is invalid");
760         ret = WIMLIB_ERR_INVALID_METADATA_RESOURCE;
761 out_free_ads_entries:
762         if (ads_entries) {
763                 for (u16 i = 0; i < num_ads; i++)
764                         destroy_ads_entry(&ads_entries[i]);
765                 FREE(ads_entries);
766         }
767 out:
768         return ret;
769 }
770
771 /*
772  * Verify a WIM inode:
773  *
774  * - Check to make sure the security ID is valid
775  * - Check to make sure there is at most one unnamed stream
776  * - Check to make sure there is at most one DOS name.
777  *
778  * Return values:
779  *      WIMLIB_ERR_SUCCESS (0)
780  */
781 int
782 verify_inode(struct wim_inode *inode, const struct wim_security_data *sd)
783 {
784         /* Check the security ID.  -1 is valid and means "no security
785          * descriptor".  Anything else has to be a valid index into the WIM
786          * image's security descriptors table. */
787         if (inode->i_security_id < -1 ||
788             (inode->i_security_id >= 0 &&
789              inode->i_security_id >= sd->num_entries))
790         {
791                 WARNING("\"%"TS"\" has an invalid security ID (%d)",
792                         inode_first_full_path(inode), inode->i_security_id);
793                 inode->i_security_id = -1;
794         }
795
796         /* Make sure there is only one unnamed data stream. */
797         unsigned num_unnamed_streams = 0;
798         for (unsigned i = 0; i <= inode->i_num_ads; i++) {
799                 const u8 *hash;
800                 hash = inode_stream_hash(inode, i);
801                 if (inode_stream_name_nbytes(inode, i) == 0 && !is_zero_hash(hash))
802                         num_unnamed_streams++;
803         }
804         if (num_unnamed_streams > 1) {
805                 WARNING("\"%"TS"\" has multiple (%u) un-named streams",
806                         inode_first_full_path(inode), num_unnamed_streams);
807         }
808
809         return 0;
810 }
811
812 void
813 inode_ref_streams(struct wim_inode *inode)
814 {
815         for (unsigned i = 0; i <= inode->i_num_ads; i++) {
816                 struct wim_lookup_table_entry *lte;
817                 lte = inode_stream_lte_resolved(inode, i);
818                 if (lte)
819                         lte->refcnt++;
820         }
821 }
822
823 void
824 inode_unref_streams(struct wim_inode *inode,
825                     struct wim_lookup_table *lookup_table)
826 {
827         struct wim_lookup_table_entry *lte;
828         unsigned i;
829
830         for (i = 0; i <= inode->i_num_ads; i++) {
831                 lte = inode_stream_lte(inode, i, lookup_table);
832                 if (lte)
833                         lte_decrement_refcnt(lte, lookup_table);
834         }
835 }
836
837 int
838 init_inode_table(struct wim_inode_table *table, size_t capacity)
839 {
840         table->array = CALLOC(capacity, sizeof(table->array[0]));
841         if (table->array == NULL) {
842                 ERROR("Cannot initalize inode table: out of memory");
843                 return WIMLIB_ERR_NOMEM;
844         }
845         table->num_entries  = 0;
846         table->capacity  = capacity;
847         INIT_LIST_HEAD(&table->extra_inodes);
848         return 0;
849 }
850
851 void
852 destroy_inode_table(struct wim_inode_table *table)
853 {
854         FREE(table->array);
855 }
856
857 static struct wim_inode *
858 inode_table_get_inode(struct wim_inode_table *table, u64 ino, u64 devno)
859 {
860         u64 hash = hash_u64(hash_u64(ino) + hash_u64(devno));
861         size_t pos = hash % table->capacity;
862         struct wim_inode *inode;
863         struct hlist_node *cur;
864
865         hlist_for_each_entry(inode, cur, &table->array[pos], i_hlist) {
866                 if (inode->i_ino == ino && inode->i_devno == devno) {
867                         DEBUG("Using existing inode {devno=%"PRIu64", ino=%"PRIu64"}",
868                               devno, ino);
869                         inode->i_nlink++;
870                         return inode;
871                 }
872         }
873         inode = new_timeless_inode();
874         if (inode) {
875                 inode->i_ino = ino;
876                 inode->i_devno = devno;
877                 hlist_add_head(&inode->i_hlist, &table->array[pos]);
878                 table->num_entries++;
879         }
880         return inode;
881 }
882
883
884 /* Given a directory entry with the name @name for the file with the inode
885  * number @ino and device number @devno, create a new WIM dentry with an
886  * associated inode, where the inode is shared if an inode with the same @ino
887  * and @devno has already been created.  On success, the new WIM dentry is
888  * written to *dentry_ret, and its inode has i_nlink > 1 if a previously
889  * existing inode was used.
890  */
891 int
892 inode_table_new_dentry(struct wim_inode_table *table, const tchar *name,
893                        u64 ino, u64 devno, bool noshare,
894                        struct wim_dentry **dentry_ret)
895 {
896         struct wim_dentry *dentry;
897         struct wim_inode *inode;
898         int ret;
899
900         if (noshare) {
901                 /* File that cannot be hardlinked--- Return a new inode with its
902                  * inode and device numbers left at 0. */
903                 ret = new_dentry_with_timeless_inode(name, &dentry);
904                 if (ret)
905                         return ret;
906                 list_add_tail(&dentry->d_inode->i_list, &table->extra_inodes);
907         } else {
908                 /* File that can be hardlinked--- search the table for an
909                  * existing inode matching the inode number and device;
910                  * otherwise create a new inode. */
911                 ret = new_dentry(name, &dentry);
912                 if (ret)
913                         return ret;
914                 inode = inode_table_get_inode(table, ino, devno);
915                 if (!inode) {
916                         free_dentry(dentry);
917                         return WIMLIB_ERR_NOMEM;
918                 }
919                 /* If using an existing inode, we need to gain a reference to
920                  * each of its streams. */
921                 if (inode->i_nlink > 1)
922                         inode_ref_streams(inode);
923                 dentry->d_inode = inode;
924                 inode_add_dentry(dentry, inode);
925         }
926         *dentry_ret = dentry;
927         return 0;
928 }
929
930
931
932 /* Assign consecutive inode numbers to a new set of inodes from the inode table,
933  * and append the inodes to a single list @head that contains the inodes already
934  * existing in the WIM image.  */
935 void
936 inode_table_prepare_inode_list(struct wim_inode_table *table,
937                                struct list_head *head)
938 {
939         struct wim_inode *inode, *tmp_inode;
940         struct hlist_node *cur, *tmp;
941         u64 cur_ino = 1;
942
943         /* Re-assign inode numbers in the existing list to avoid duplicates. */
944         list_for_each_entry(inode, head, i_list)
945                 inode->i_ino = cur_ino++;
946
947         /* Assign inode numbers to the new inodes and move them to the image's
948          * inode list. */
949         for (size_t i = 0; i < table->capacity; i++) {
950                 hlist_for_each_entry_safe(inode, cur, tmp, &table->array[i], i_hlist)
951                 {
952                         inode->i_ino = cur_ino++;
953                         inode->i_devno = 0;
954                         list_add_tail(&inode->i_list, head);
955                 }
956                 INIT_HLIST_HEAD(&table->array[i]);
957         }
958         list_for_each_entry_safe(inode, tmp_inode, &table->extra_inodes, i_list)
959         {
960                 inode->i_ino = cur_ino++;
961                 inode->i_devno = 0;
962                 list_add_tail(&inode->i_list, head);
963         }
964         INIT_LIST_HEAD(&table->extra_inodes);
965         table->num_entries = 0;
966 }