]> wimlib.net Git - wimlib/blob - src/ntfs-3g_apply.c
win32_common.c: add extra error messages if pread() or pwrite() fails
[wimlib] / src / ntfs-3g_apply.c
1 /*
2  * ntfs-3g_apply.c
3  *
4  * Apply a WIM image directly to an NTFS volume using libntfs-3g.  Restore as
5  * much information as possible, including security data, file attributes, DOS
6  * names, and alternate data streams.
7  *
8  * Note: because NTFS-3g offers inode-based interfaces, we actually don't need
9  * to deal with paths at all!  (Other than for error messages.)
10  */
11
12 /*
13  * Copyright (C) 2012, 2013, 2014, 2015 Eric Biggers
14  *
15  * This file is free software; you can redistribute it and/or modify it under
16  * the terms of the GNU Lesser General Public License as published by the Free
17  * Software Foundation; either version 3 of the License, or (at your option) any
18  * later version.
19  *
20  * This file is distributed in the hope that it will be useful, but WITHOUT
21  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
22  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
23  * details.
24  *
25  * You should have received a copy of the GNU Lesser General Public License
26  * along with this file; if not, see http://www.gnu.org/licenses/.
27  */
28
29 #ifdef HAVE_CONFIG_H
30 #  include "config.h"
31 #endif
32
33 #include <errno.h>
34 #include <locale.h>
35 #include <string.h>
36
37 #include <ntfs-3g/attrib.h>
38 #include <ntfs-3g/reparse.h>
39 #include <ntfs-3g/security.h>
40
41 #include "wimlib/assert.h"
42 #include "wimlib/apply.h"
43 #include "wimlib/blob_table.h"
44 #include "wimlib/dentry.h"
45 #include "wimlib/encoding.h"
46 #include "wimlib/error.h"
47 #include "wimlib/metadata.h"
48 #include "wimlib/ntfs_3g.h"
49 #include "wimlib/reparse.h"
50 #include "wimlib/security.h"
51 #include "wimlib/security_descriptor.h"
52
53 static int
54 ntfs_3g_get_supported_features(const char *target,
55                                struct wim_features *supported_features)
56 {
57         supported_features->readonly_files            = 1;
58         supported_features->hidden_files              = 1;
59         supported_features->system_files              = 1;
60         supported_features->archive_files             = 1;
61         supported_features->compressed_files          = 1;
62         supported_features->not_context_indexed_files = 1;
63         supported_features->named_data_streams        = 1;
64         supported_features->hard_links                = 1;
65         supported_features->reparse_points            = 1;
66         supported_features->security_descriptors      = 1;
67         supported_features->short_names               = 1;
68         supported_features->timestamps                = 1;
69         supported_features->case_sensitive_filenames  = 1;
70         return 0;
71 }
72
73 struct ntfs_3g_apply_ctx {
74         /* Extract flags, the pointer to the WIMStruct, etc.  */
75         struct apply_ctx common;
76
77         /* Pointer to the open NTFS volume  */
78         ntfs_volume *vol;
79
80         ntfs_attr *open_attrs[MAX_OPEN_FILES];
81         unsigned num_open_attrs;
82         ntfs_inode *open_inodes[MAX_OPEN_FILES];
83         unsigned num_open_inodes;
84
85         struct reparse_buffer_disk rpbuf;
86         u8 *reparse_ptr;
87
88         /* Offset in the blob currently being read  */
89         u64 offset;
90
91         unsigned num_reparse_inodes;
92         ntfs_inode *ntfs_reparse_inodes[MAX_OPEN_FILES];
93         struct wim_inode *wim_reparse_inodes[MAX_OPEN_FILES];
94 };
95
96 static size_t
97 sid_size(const wimlib_SID *sid)
98 {
99         return offsetof(wimlib_SID, sub_authority) +
100                 sizeof(le32) * sid->sub_authority_count;
101 }
102
103 /*
104  * sd_fixup - Fix up a Windows NT security descriptor for libntfs-3g.
105  *
106  * libntfs-3g validates security descriptors before setting them, but old
107  * versions contain bugs causing it to reject unusual but valid security
108  * descriptors:
109  *
110  * - Versions before 2013.1.13 reject security descriptors ending with an empty
111  *   SACL (System Access Control List).  This bug can be worked around either by
112  *   moving the empty SACL earlier in the security descriptor or by removing the
113  *   SACL entirely.  The latter work-around is valid because an empty SACL is
114  *   equivalent to a "null", or non-existent, SACL.
115  * - Versions before 2014.2.15 reject security descriptors ending with an empty
116  *   DACL (Discretionary Access Control List).  This is very similar to the SACL
117  *   bug.  However, removing the DACL is not a valid workaround because this
118  *   changes the meaning of the security descriptor--- an empty DACL allows no
119  *   access, whereas a "null" DACL allows all access.
120  *
121  * If the security descriptor was fixed, this function returns an allocated
122  * buffer containing the fixed security descriptor, and its size is updated.
123  * Otherwise (or if no memory is available) NULL is returned.
124  */
125 static void *
126 sd_fixup(const void *_desc, size_t *size_p)
127 {
128         u32 owner_offset, group_offset, dacl_offset, sacl_offset;
129         bool owner_valid, group_valid;
130         size_t size = *size_p;
131         const wimlib_SECURITY_DESCRIPTOR_RELATIVE *desc = _desc;
132         wimlib_SECURITY_DESCRIPTOR_RELATIVE *desc_new;
133         const wimlib_SID *owner, *group, *sid;
134
135         /* Don't attempt to fix clearly invalid security descriptors.  */
136         if (size < sizeof(wimlib_SECURITY_DESCRIPTOR_RELATIVE))
137                 return NULL;
138
139         if (le16_to_cpu(desc->control) & wimlib_SE_DACL_PRESENT)
140                 dacl_offset = le32_to_cpu(desc->dacl_offset);
141         else
142                 dacl_offset = 0;
143
144         if (le16_to_cpu(desc->control) & wimlib_SE_SACL_PRESENT)
145                 sacl_offset = le32_to_cpu(desc->sacl_offset);
146         else
147                 sacl_offset = 0;
148
149         /* Check if the security descriptor will be affected by one of the bugs.
150          * If not, do nothing and return.  */
151         if (!((sacl_offset != 0 && sacl_offset == size - sizeof(wimlib_ACL)) ||
152               (dacl_offset != 0 && dacl_offset == size - sizeof(wimlib_ACL))))
153                 return NULL;
154
155         owner_offset = le32_to_cpu(desc->owner_offset);
156         group_offset = le32_to_cpu(desc->group_offset);
157         owner = (const wimlib_SID*)((const u8*)desc + owner_offset);
158         group = (const wimlib_SID*)((const u8*)desc + group_offset);
159
160         /* We'll try to move the owner or group SID to the end of the security
161          * descriptor to avoid the bug.  This is only possible if at least one
162          * is valid.  */
163         owner_valid = (owner_offset != 0) &&
164                         (owner_offset % 4 == 0) &&
165                         (owner_offset <= size - sizeof(SID)) &&
166                         (owner_offset + sid_size(owner) <= size) &&
167                         (owner_offset >= sizeof(wimlib_SECURITY_DESCRIPTOR_RELATIVE));
168         group_valid = (group_offset != 0) &&
169                         (group_offset % 4 == 0) &&
170                         (group_offset <= size - sizeof(SID)) &&
171                         (group_offset + sid_size(group) <= size) &&
172                         (group_offset >= sizeof(wimlib_SECURITY_DESCRIPTOR_RELATIVE));
173         if (owner_valid) {
174                 sid = owner;
175         } else if (group_valid) {
176                 sid = group;
177         } else {
178                 return NULL;
179         }
180
181         desc_new = MALLOC(size + sid_size(sid));
182         if (!desc_new)
183                 return NULL;
184
185         memcpy(desc_new, desc, size);
186         if (owner_valid)
187                 desc_new->owner_offset = cpu_to_le32(size);
188         else if (group_valid)
189                 desc_new->group_offset = cpu_to_le32(size);
190         memcpy((u8*)desc_new + size, sid, sid_size(sid));
191         *size_p = size + sid_size(sid);
192         return desc_new;
193 }
194
195 /* Set the security descriptor @desc of size @desc_size on the NTFS inode @ni.
196   */
197 static int
198 ntfs_3g_set_security_descriptor(ntfs_inode *ni, const void *desc, size_t desc_size)
199 {
200         struct SECURITY_CONTEXT sec_ctx;
201         void *desc_fixed = NULL;
202         int ret = 0;
203
204         memset(&sec_ctx, 0, sizeof(sec_ctx));
205         sec_ctx.vol = ni->vol;
206
207 retry:
208         if (ntfs_set_ntfs_acl(&sec_ctx, ni, desc, desc_size, 0)) {
209                 if (desc_fixed == NULL) {
210                         desc_fixed = sd_fixup(desc, &desc_size);
211                         if (desc_fixed != NULL) {
212                                 desc = desc_fixed;
213                                 goto retry;
214                         }
215                 }
216                 ret = WIMLIB_ERR_SET_SECURITY;
217         }
218
219         FREE(desc_fixed);
220         return ret;
221 }
222
223 static int
224 ntfs_3g_set_timestamps(ntfs_inode *ni, const struct wim_inode *inode)
225 {
226         u64 times[3] = {
227                 inode->i_creation_time,
228                 inode->i_last_write_time,
229                 inode->i_last_access_time,
230         };
231
232         if (ntfs_inode_set_times(ni, (const char *)times, sizeof(times), 0))
233                 return WIMLIB_ERR_SET_TIMESTAMPS;
234         return 0;
235 }
236
237 /* Restore the timestamps on the NTFS inode corresponding to @inode.  */
238 static int
239 ntfs_3g_restore_timestamps(ntfs_volume *vol, const struct wim_inode *inode)
240 {
241         ntfs_inode *ni;
242         int res;
243
244         ni = ntfs_inode_open(vol, inode->i_mft_no);
245         if (!ni)
246                 goto fail;
247
248         res = ntfs_3g_set_timestamps(ni, inode);
249
250         if (ntfs_inode_close(ni) || res)
251                 goto fail;
252
253         return 0;
254
255 fail:
256         ERROR_WITH_ERRNO("Failed to update timestamps of \"%s\" in NTFS volume",
257                          dentry_full_path(inode_first_extraction_dentry(inode)));
258         return WIMLIB_ERR_SET_TIMESTAMPS;
259 }
260
261 /* Restore the DOS name of the @dentry.
262  * This closes both @ni and @dir_ni.
263  * If either is NULL, then they are opened temporarily.  */
264 static int
265 ntfs_3g_restore_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni,
266                          struct wim_dentry *dentry, ntfs_volume *vol)
267 {
268         int ret;
269         const char *dos_name;
270         size_t dos_name_nbytes;
271
272         /* Note: ntfs_set_ntfs_dos_name() closes both inodes (even if it fails).
273          * And it takes in a multibyte string, even though it translates it to
274          * UTF-16LE internally... which is annoying because we currently have
275          * the UTF-16LE string but not the multibyte string.  */
276
277         ret = utf16le_get_tstr(dentry->d_short_name, dentry->d_short_name_nbytes,
278                                &dos_name, &dos_name_nbytes);
279         if (ret)
280                 goto out_close;
281
282         if (!dir_ni)
283                 dir_ni = ntfs_inode_open(vol, dentry->d_parent->d_inode->i_mft_no);
284         if (!ni)
285                 ni = ntfs_inode_open(vol, dentry->d_inode->i_mft_no);
286         if (dir_ni && ni) {
287                 ret = ntfs_set_ntfs_dos_name(ni, dir_ni,
288                                              dos_name, dos_name_nbytes, 0);
289                 dir_ni = NULL;
290                 ni = NULL;
291         } else {
292                 ret = -1;
293         }
294         utf16le_put_tstr(dos_name);
295         if (ret) {
296                 ERROR_WITH_ERRNO("Failed to set DOS name of \"%s\" in NTFS "
297                                  "volume", dentry_full_path(dentry));
298                 ret = WIMLIB_ERR_SET_SHORT_NAME;
299                 goto out_close;
300         }
301
302         /* Unlike most other NTFS-3g functions, ntfs_set_ntfs_dos_name()
303          * changes the directory's last modification timestamp...
304          * Change it back.  */
305         return ntfs_3g_restore_timestamps(vol, dentry->d_parent->d_inode);
306
307 out_close:
308         /* ntfs_inode_close() can take a NULL argument, but it's probably best
309          * not to rely on this behavior.  */
310         if (ni)
311                 ntfs_inode_close(ni);
312         if (dir_ni)
313                 ntfs_inode_close(dir_ni);
314         return ret;
315 }
316
317 static int
318 ntfs_3g_restore_reparse_point(ntfs_inode *ni, const struct wim_inode *inode,
319                               unsigned blob_size, struct ntfs_3g_apply_ctx *ctx)
320 {
321         complete_reparse_point(&ctx->rpbuf, inode, blob_size);
322
323         if (ntfs_set_ntfs_reparse_data(ni, (const char *)&ctx->rpbuf,
324                                        REPARSE_DATA_OFFSET + blob_size, 0))
325         {
326                 int err = errno;
327                 ERROR_WITH_ERRNO("Failed to set reparse data on \"%s\"",
328                                  dentry_full_path(
329                                         inode_first_extraction_dentry(inode)));
330                 if (err == EINVAL && !(inode->i_reparse_tag & 0x80000000)) {
331                         WARNING("This reparse point had a non-Microsoft reparse "
332                                 "tag.  The preceding error may have been caused "
333                                 "by a known bug in libntfs-3g where it does not "
334                                 "correctly validate non-Microsoft reparse "
335                                 "points.  This bug may be fixed in the 2016 "
336                                 "release of libntfs-3g.");
337                 }
338                 return WIMLIB_ERR_SET_REPARSE_DATA;
339         }
340
341         return 0;
342 }
343
344 static bool
345 ntfs_3g_has_empty_attributes(const struct wim_inode *inode)
346 {
347         for (unsigned i = 0; i < inode->i_num_streams; i++) {
348                 const struct wim_inode_stream *strm = &inode->i_streams[i];
349
350                 if (stream_blob_resolved(strm) == NULL &&
351                     (strm->stream_type == STREAM_TYPE_REPARSE_POINT ||
352                      stream_is_named_data_stream(strm)))
353                         return true;
354         }
355         return false;
356 }
357
358 /*
359  * Create empty attributes (named data streams and potentially a reparse point)
360  * for the specified file, if there are any.
361  *
362  * Since these won't have blob descriptors, they won't show up in the call to
363  * extract_blob_list().  Hence the need for the special case.
364  *
365  * Keep this in sync with ntfs_3g_has_empty_attributes()!
366  */
367 static int
368 ntfs_3g_create_empty_attributes(ntfs_inode *ni,
369                                 const struct wim_inode *inode,
370                                 struct ntfs_3g_apply_ctx *ctx)
371 {
372         for (unsigned i = 0; i < inode->i_num_streams; i++) {
373
374                 const struct wim_inode_stream *strm = &inode->i_streams[i];
375                 int ret;
376
377                 if (stream_blob_resolved(strm) != NULL)
378                         continue;
379
380                 if (strm->stream_type == STREAM_TYPE_REPARSE_POINT) {
381                         ret = ntfs_3g_restore_reparse_point(ni, inode, 0, ctx);
382                         if (ret)
383                                 return ret;
384                 } else if (stream_is_named_data_stream(strm)) {
385                         if (ntfs_attr_add(ni, AT_DATA, strm->stream_name,
386                                           utf16le_len_chars(strm->stream_name),
387                                           NULL, 0))
388                         {
389                                 ERROR_WITH_ERRNO("Failed to create named data "
390                                                  "stream of \"%s\"",
391                                                  dentry_full_path(
392                                         inode_first_extraction_dentry(inode)));
393                                 return WIMLIB_ERR_NTFS_3G;
394                         }
395                 }
396         }
397         return 0;
398 }
399
400 /* Set attributes, security descriptor, and timestamps on the NTFS inode @ni.
401  */
402 static int
403 ntfs_3g_set_metadata(ntfs_inode *ni, const struct wim_inode *inode,
404                      const struct ntfs_3g_apply_ctx *ctx)
405 {
406         int extract_flags;
407         const struct wim_security_data *sd;
408         struct wim_dentry *one_dentry;
409         int ret;
410
411         extract_flags = ctx->common.extract_flags;
412         sd = wim_get_current_security_data(ctx->common.wim);
413         one_dentry = inode_first_extraction_dentry(inode);
414
415         /* Attributes  */
416         if (!(extract_flags & WIMLIB_EXTRACT_FLAG_NO_ATTRIBUTES)) {
417                 u32 attrib = inode->i_attributes;
418
419                 attrib &= ~(FILE_ATTRIBUTE_SPARSE_FILE |
420                             FILE_ATTRIBUTE_ENCRYPTED);
421
422                 if (ntfs_set_ntfs_attrib(ni, (const char *)&attrib,
423                                          sizeof(attrib), 0))
424                 {
425                         ERROR_WITH_ERRNO("Failed to set attributes on \"%s\" "
426                                          "in NTFS volume",
427                                          dentry_full_path(one_dentry));
428                         return WIMLIB_ERR_SET_ATTRIBUTES;
429                 }
430         }
431
432         /* Security descriptor  */
433         if (inode_has_security_descriptor(inode)
434             && !(extract_flags & WIMLIB_EXTRACT_FLAG_NO_ACLS))
435         {
436                 const void *desc;
437                 size_t desc_size;
438
439                 desc = sd->descriptors[inode->i_security_id];
440                 desc_size = sd->sizes[inode->i_security_id];
441
442                 ret = ntfs_3g_set_security_descriptor(ni, desc, desc_size);
443
444                 if (unlikely(ret)) {
445                         int err = errno;
446                         ERROR_WITH_ERRNO("Failed to set security descriptor on "
447                                          "\"%s\" in NTFS volume",
448                                          dentry_full_path(one_dentry));
449                         if (err == EINVAL && wimlib_print_errors) {
450                                 fprintf(wimlib_error_file,
451                                         "The security descriptor is: ");
452                                 print_byte_field(desc, desc_size, wimlib_error_file);
453                                 fprintf(wimlib_error_file, "\n");
454                                 fprintf(wimlib_error_file,
455                                         "\nThis error occurred because libntfs-3g thinks "
456                                         "the security descriptor is invalid.  If you "
457                                         "are extracting a Windows 10 image, this may be "
458                                         "caused by a known bug in libntfs-3g.  See: "
459                                         "https://wimlib.net/forums/viewtopic.php?f=1&t=4 "
460                                         "for more information.\n\n");
461                         }
462                         return ret;
463                 }
464         }
465
466         /* Timestamps  */
467         ret = ntfs_3g_set_timestamps(ni, inode);
468         if (ret) {
469                 ERROR_WITH_ERRNO("Failed to set timestamps on \"%s\" "
470                                  "in NTFS volume",
471                                  dentry_full_path(one_dentry));
472                 return ret;
473         }
474         return 0;
475 }
476
477 /* Recursively creates all the subdirectories of @dir, which has been created as
478  * the NTFS inode @dir_ni.  */
479 static int
480 ntfs_3g_create_dirs_recursive(ntfs_inode *dir_ni, struct wim_dentry *dir,
481                               struct ntfs_3g_apply_ctx *ctx)
482 {
483         struct wim_dentry *child;
484
485         for_dentry_child(child, dir) {
486                 ntfs_inode *ni;
487                 int ret;
488
489                 if (!(child->d_inode->i_attributes & FILE_ATTRIBUTE_DIRECTORY))
490                         continue;
491                 if (!will_extract_dentry(child))
492                         continue;
493
494                 ni = ntfs_create(dir_ni, 0, child->d_extraction_name,
495                                  child->d_extraction_name_nchars, S_IFDIR);
496                 if (!ni) {
497                         ERROR_WITH_ERRNO("Error creating \"%s\" in NTFS volume",
498                                          dentry_full_path(child));
499                         return WIMLIB_ERR_NTFS_3G;
500                 }
501
502                 child->d_inode->i_mft_no = ni->mft_no;
503
504                 ret = report_file_created(&ctx->common);
505                 if (!ret)
506                         ret = ntfs_3g_set_metadata(ni, child->d_inode, ctx);
507                 if (!ret)
508                         ret = ntfs_3g_create_dirs_recursive(ni, child, ctx);
509
510                 if (ntfs_inode_close_in_dir(ni, dir_ni) && !ret) {
511                         ERROR_WITH_ERRNO("Error closing \"%s\" in NTFS volume",
512                                          dentry_full_path(child));
513                         ret = WIMLIB_ERR_NTFS_3G;
514                 }
515                 if (ret)
516                         return ret;
517         }
518         return 0;
519 }
520
521 /* For each WIM dentry in the @root tree that represents a directory, create the
522  * corresponding directory in the NTFS volume @ctx->vol.  */
523 static int
524 ntfs_3g_create_directories(struct wim_dentry *root,
525                            struct list_head *dentry_list,
526                            struct ntfs_3g_apply_ctx *ctx)
527 {
528         ntfs_inode *root_ni;
529         int ret;
530         struct wim_dentry *dentry;
531
532         /* Create the directories using POSIX names.  */
533
534         root_ni = ntfs_inode_open(ctx->vol, FILE_root);
535         if (!root_ni) {
536                 ERROR_WITH_ERRNO("Can't open root of NTFS volume");
537                 return WIMLIB_ERR_NTFS_3G;
538         }
539
540         root->d_inode->i_mft_no = FILE_root;
541
542         ret = ntfs_3g_set_metadata(root_ni, root->d_inode, ctx);
543         if (!ret)
544                 ret = ntfs_3g_create_dirs_recursive(root_ni, root, ctx);
545
546         if (ntfs_inode_close(root_ni) && !ret) {
547                 ERROR_WITH_ERRNO("Error closing root of NTFS volume");
548                 ret = WIMLIB_ERR_NTFS_3G;
549         }
550         if (ret)
551                 return ret;
552
553         /* Set the DOS name of any directory that has one.  In addition, create
554          * empty attributes for directories that have them.  Note that creating
555          * an empty reparse point attribute must happen *after* setting the
556          * DOS name in order to work around a case where
557          * ntfs_set_ntfs_dos_name() fails with EOPNOTSUPP.  */
558         list_for_each_entry(dentry, dentry_list, d_extraction_list_node) {
559                 const struct wim_inode *inode = dentry->d_inode;
560
561                 if (!(inode->i_attributes & FILE_ATTRIBUTE_DIRECTORY))
562                         continue;
563                 if (dentry_has_short_name(dentry)) {
564                         ret = ntfs_3g_restore_dos_name(NULL, NULL, dentry,
565                                                        ctx->vol);
566                         if (ret)
567                                 return ret;
568                         ret = report_file_created(&ctx->common);
569                         if (ret)
570                                 return ret;
571                 }
572                 if (ntfs_3g_has_empty_attributes(inode)) {
573                         ntfs_inode *ni;
574
575                         ret = WIMLIB_ERR_NTFS_3G;
576                         ni = ntfs_inode_open(ctx->vol, inode->i_mft_no);
577                         if (ni) {
578                                 ret = ntfs_3g_create_empty_attributes(ni, inode,
579                                                                       ctx);
580                                 if (ntfs_inode_close(ni) && !ret)
581                                         ret = WIMLIB_ERR_NTFS_3G;
582                         }
583                         if (ret) {
584                                 ERROR_WITH_ERRNO("Failed to create empty "
585                                                  "attributes of directory "
586                                                  "\"%s\" in NTFS volume",
587                                                  dentry_full_path(dentry));
588                                 return ret;
589                         }
590                 }
591         }
592         return 0;
593 }
594
595 /* When creating an inode that will have a short (DOS) name, we create it using
596  * the long name associated with the short name.  This ensures that the short
597  * name gets associated with the correct long name.  */
598 static struct wim_dentry *
599 ntfs_3g_first_extraction_alias(struct wim_inode *inode)
600 {
601         struct wim_dentry *dentry;
602
603         inode_for_each_extraction_alias(dentry, inode)
604                 if (dentry_has_short_name(dentry))
605                         return dentry;
606         return inode_first_extraction_dentry(inode);
607 }
608
609 /*
610  * Add a hard link for the NTFS inode @ni at the location corresponding to the
611  * WIM dentry @dentry.
612  *
613  * The parent directory must have already been created on the NTFS volume.
614  *
615  * Returns 0 on success; returns WIMLIB_ERR_NTFS_3G and sets errno on failure.
616  */
617 static int
618 ntfs_3g_add_link(ntfs_inode *ni, struct wim_dentry *dentry)
619 {
620         ntfs_inode *dir_ni;
621         int res;
622
623         /* Open the inode of the parent directory.  */
624         dir_ni = ntfs_inode_open(ni->vol, dentry->d_parent->d_inode->i_mft_no);
625         if (!dir_ni)
626                 goto fail;
627
628         /* Create the link.  */
629         res = ntfs_link(ni, dir_ni, dentry->d_extraction_name,
630                         dentry->d_extraction_name_nchars);
631
632         /* Close the parent directory.  */
633         if (ntfs_inode_close(dir_ni) || res)
634                 goto fail;
635
636         return 0;
637
638 fail:
639         ERROR_WITH_ERRNO("Can't create link \"%s\" in NTFS volume",
640                          dentry_full_path(dentry));
641         return WIMLIB_ERR_NTFS_3G;
642 }
643
644 static int
645 ntfs_3g_create_nondirectory(struct wim_inode *inode,
646                             struct ntfs_3g_apply_ctx *ctx)
647 {
648         struct wim_dentry *first_dentry;
649         ntfs_inode *dir_ni;
650         ntfs_inode *ni;
651         struct wim_dentry *dentry;
652         int ret;
653
654         first_dentry = ntfs_3g_first_extraction_alias(inode);
655
656         /* Create first link.  */
657
658         dir_ni = ntfs_inode_open(ctx->vol, first_dentry->d_parent->d_inode->i_mft_no);
659         if (!dir_ni) {
660                 ERROR_WITH_ERRNO("Can't open \"%s\" in NTFS volume",
661                                  dentry_full_path(first_dentry->d_parent));
662                 return WIMLIB_ERR_NTFS_3G;
663         }
664
665         ni = ntfs_create(dir_ni, 0, first_dentry->d_extraction_name,
666                          first_dentry->d_extraction_name_nchars, S_IFREG);
667
668         if (!ni) {
669                 ERROR_WITH_ERRNO("Can't create \"%s\" in NTFS volume",
670                                  dentry_full_path(first_dentry));
671                 ntfs_inode_close(dir_ni);
672                 return WIMLIB_ERR_NTFS_3G;
673         }
674
675         inode->i_mft_no = ni->mft_no;
676
677         /* Set short name if present.  */
678         if (dentry_has_short_name(first_dentry)) {
679
680                 ret = ntfs_3g_restore_dos_name(ni, dir_ni, first_dentry, ctx->vol);
681
682                 /* ntfs_3g_restore_dos_name() closed both 'ni' and 'dir_ni'.  */
683
684                 if (ret)
685                         return ret;
686
687                 /* Reopen the inode.  */
688                 ni = ntfs_inode_open(ctx->vol, inode->i_mft_no);
689                 if (!ni) {
690                         ERROR_WITH_ERRNO("Failed to reopen \"%s\" "
691                                          "in NTFS volume",
692                                          dentry_full_path(first_dentry));
693                         return WIMLIB_ERR_NTFS_3G;
694                 }
695         } else {
696                 /* Close the directory in which the first link was created.  */
697                 if (ntfs_inode_close(dir_ni)) {
698                         ERROR_WITH_ERRNO("Failed to close \"%s\" in NTFS volume",
699                                          dentry_full_path(first_dentry->d_parent));
700                         ret = WIMLIB_ERR_NTFS_3G;
701                         goto out_close_ni;
702                 }
703         }
704
705         /* Create additional links if present.  */
706         inode_for_each_extraction_alias(dentry, inode) {
707                 if (dentry != first_dentry) {
708                         ret = ntfs_3g_add_link(ni, dentry);
709                         if (ret)
710                                 goto out_close_ni;
711                 }
712         }
713
714         /* Set metadata.  */
715         ret = ntfs_3g_set_metadata(ni, inode, ctx);
716         if (ret)
717                 goto out_close_ni;
718
719         ret = ntfs_3g_create_empty_attributes(ni, inode, ctx);
720
721 out_close_ni:
722         /* Close the inode.  */
723         if (ntfs_inode_close(ni) && !ret) {
724                 ERROR_WITH_ERRNO("Error closing \"%s\" in NTFS volume",
725                                  dentry_full_path(first_dentry));
726                 ret = WIMLIB_ERR_NTFS_3G;
727         }
728         return ret;
729 }
730
731 /* For each WIM dentry in the @dentry_list that represents a nondirectory file,
732  * create the corresponding nondirectory file in the NTFS volume.
733  *
734  * Directories must have already been created.  */
735 static int
736 ntfs_3g_create_nondirectories(struct list_head *dentry_list,
737                               struct ntfs_3g_apply_ctx *ctx)
738 {
739         struct wim_dentry *dentry;
740         struct wim_inode *inode;
741         int ret;
742
743         list_for_each_entry(dentry, dentry_list, d_extraction_list_node) {
744                 inode = dentry->d_inode;
745                 if (inode->i_attributes & FILE_ATTRIBUTE_DIRECTORY)
746                         continue;
747                 if (dentry == inode_first_extraction_dentry(inode)) {
748                         ret = ntfs_3g_create_nondirectory(inode, ctx);
749                         if (ret)
750                                 return ret;
751                 }
752                 ret = report_file_created(&ctx->common);
753                 if (ret)
754                         return ret;
755         }
756         return 0;
757 }
758
759 static int
760 ntfs_3g_begin_extract_blob_instance(struct blob_descriptor *blob,
761                                     ntfs_inode *ni,
762                                     struct wim_inode *inode,
763                                     const struct wim_inode_stream *strm,
764                                     struct ntfs_3g_apply_ctx *ctx)
765 {
766         struct wim_dentry *one_dentry = inode_first_extraction_dentry(inode);
767         ntfschar *stream_name;
768         size_t stream_name_nchars;
769         ntfs_attr *attr;
770
771         if (unlikely(strm->stream_type == STREAM_TYPE_REPARSE_POINT)) {
772
773                 if (blob->size > REPARSE_DATA_MAX_SIZE) {
774                         ERROR("Reparse data of \"%s\" has size "
775                               "%"PRIu64" bytes (exceeds %u bytes)",
776                               dentry_full_path(one_dentry),
777                               blob->size, REPARSE_DATA_MAX_SIZE);
778                         return WIMLIB_ERR_INVALID_REPARSE_DATA;
779                 }
780                 ctx->reparse_ptr = ctx->rpbuf.rpdata;
781                 ctx->ntfs_reparse_inodes[ctx->num_reparse_inodes] = ni;
782                 ctx->wim_reparse_inodes[ctx->num_reparse_inodes] = inode;
783                 ctx->num_reparse_inodes++;
784                 return 0;
785         }
786
787         /* It's a data stream (may be unnamed or named).  */
788         wimlib_assert(strm->stream_type == STREAM_TYPE_DATA);
789
790         if (unlikely(stream_is_named(strm))) {
791                 stream_name = strm->stream_name;
792                 stream_name_nchars = utf16le_len_chars(stream_name);
793
794                 if (ntfs_attr_add(ni, AT_DATA, stream_name,
795                                   stream_name_nchars, NULL, 0))
796                 {
797                         ERROR_WITH_ERRNO("Failed to create named data stream of \"%s\"",
798                                          dentry_full_path(one_dentry));
799                         return WIMLIB_ERR_NTFS_3G;
800                 }
801         } else {
802                 /* Don't pass an empty string other than AT_UNNAMED to
803                  * ntfs_attr_open() --- it violates assumptions made by
804                  * libntfs-3g.  */
805                 stream_name = AT_UNNAMED;
806                 stream_name_nchars = 0;
807         }
808
809         /* This should be ensured by extract_blob_list()  */
810         wimlib_assert(ctx->num_open_attrs < MAX_OPEN_FILES);
811
812         attr = ntfs_attr_open(ni, AT_DATA, stream_name, stream_name_nchars);
813         if (!attr) {
814                 ERROR_WITH_ERRNO("Failed to open data stream of \"%s\"",
815                                  dentry_full_path(one_dentry));
816                 return WIMLIB_ERR_NTFS_3G;
817         }
818         ctx->open_attrs[ctx->num_open_attrs++] = attr;
819         ntfs_attr_truncate_solid(attr, blob->size);
820         return 0;
821 }
822
823 static int
824 ntfs_3g_cleanup_blob_extract(struct ntfs_3g_apply_ctx *ctx)
825 {
826         int ret = 0;
827
828         for (unsigned i = 0; i < ctx->num_open_attrs; i++) {
829                 if (ntfs_attr_pclose(ctx->open_attrs[i]))
830                         ret = -1;
831                 ntfs_attr_close(ctx->open_attrs[i]);
832         }
833
834         ctx->num_open_attrs = 0;
835
836         for (unsigned i = 0; i < ctx->num_open_inodes; i++) {
837                 if (ntfs_inode_close(ctx->open_inodes[i]))
838                         ret = -1;
839         }
840         ctx->num_open_inodes = 0;
841
842         ctx->offset = 0;
843         ctx->reparse_ptr = NULL;
844         ctx->num_reparse_inodes = 0;
845         return ret;
846 }
847
848 static ntfs_inode *
849 ntfs_3g_open_inode(struct wim_inode *inode, struct ntfs_3g_apply_ctx *ctx)
850 {
851         ntfs_inode *ni;
852
853         /* If the same blob is being extracted to multiple streams of the same
854          * inode, then we must only open the inode once.  */
855         if (unlikely(inode->i_num_streams > 1)) {
856                 for (unsigned i = 0; i < ctx->num_open_inodes; i++) {
857                         if (ctx->open_inodes[i]->mft_no == inode->i_mft_no) {
858                                 return ctx->open_inodes[i];
859                         }
860                 }
861         }
862
863         ni = ntfs_inode_open(ctx->vol, inode->i_mft_no);
864         if (unlikely(!ni)) {
865                 ERROR_WITH_ERRNO("Can't open \"%s\" in NTFS volume",
866                                  dentry_full_path(
867                                         inode_first_extraction_dentry(inode)));
868                 return NULL;
869         }
870
871         ctx->open_inodes[ctx->num_open_inodes++] = ni;
872         return ni;
873 }
874
875 static int
876 ntfs_3g_begin_extract_blob(struct blob_descriptor *blob, void *_ctx)
877 {
878         struct ntfs_3g_apply_ctx *ctx = _ctx;
879         const struct blob_extraction_target *targets = blob_extraction_targets(blob);
880         int ret;
881         ntfs_inode *ni;
882
883         for (u32 i = 0; i < blob->out_refcnt; i++) {
884                 ret = WIMLIB_ERR_NTFS_3G;
885                 ni = ntfs_3g_open_inode(targets[i].inode, ctx);
886                 if (!ni)
887                         goto out_cleanup;
888
889                 ret = ntfs_3g_begin_extract_blob_instance(blob, ni,
890                                                           targets[i].inode,
891                                                           targets[i].stream, ctx);
892                 if (ret)
893                         goto out_cleanup;
894         }
895         ret = 0;
896         goto out;
897
898 out_cleanup:
899         ntfs_3g_cleanup_blob_extract(ctx);
900 out:
901         return ret;
902 }
903
904 /* Note: contrary to its documentation, ntfs_attr_pwrite() can return a short
905  * count in non-error cases --- specifically, when writing to a compressed
906  * attribute and the requested count exceeds the size of an NTFS "compression
907  * block".  Therefore, we must continue calling ntfs_attr_pwrite() until all
908  * bytes have been written or a real error has occurred.  */
909 static bool
910 ntfs_3g_full_pwrite(ntfs_attr *na, u64 offset, size_t size, const u8 *data)
911 {
912         while (size) {
913                 s64 res = ntfs_attr_pwrite(na, offset, size, data);
914                 if (unlikely(res <= 0))
915                         return false;
916                 wimlib_assert(res <= size);
917                 offset += res;
918                 size -= res;
919                 data += res;
920         }
921         return true;
922 }
923
924 static int
925 ntfs_3g_extract_chunk(const void *chunk, size_t size, void *_ctx)
926 {
927         struct ntfs_3g_apply_ctx *ctx = _ctx;
928
929         for (unsigned i = 0; i < ctx->num_open_attrs; i++) {
930                 if (!ntfs_3g_full_pwrite(ctx->open_attrs[i],
931                                          ctx->offset, size, chunk))
932                 {
933                         ERROR_WITH_ERRNO("Error writing data to NTFS volume");
934                         return WIMLIB_ERR_NTFS_3G;
935                 }
936         }
937         if (ctx->reparse_ptr)
938                 ctx->reparse_ptr = mempcpy(ctx->reparse_ptr, chunk, size);
939         ctx->offset += size;
940         return 0;
941 }
942
943 static int
944 ntfs_3g_end_extract_blob(struct blob_descriptor *blob, int status, void *_ctx)
945 {
946         struct ntfs_3g_apply_ctx *ctx = _ctx;
947         int ret;
948
949         if (status) {
950                 ret = status;
951                 goto out;
952         }
953
954         for (u32 i = 0; i < ctx->num_reparse_inodes; i++) {
955                 ret = ntfs_3g_restore_reparse_point(ctx->ntfs_reparse_inodes[i],
956                                                     ctx->wim_reparse_inodes[i],
957                                                     blob->size, ctx);
958                 if (ret)
959                         goto out;
960         }
961         ret = 0;
962 out:
963         if (ntfs_3g_cleanup_blob_extract(ctx) && !ret) {
964                 ERROR_WITH_ERRNO("Error writing data to NTFS volume");
965                 ret = WIMLIB_ERR_NTFS_3G;
966         }
967         return ret;
968 }
969
970 static u64
971 ntfs_3g_count_dentries(const struct list_head *dentry_list)
972 {
973         const struct wim_dentry *dentry;
974         u64 count = 0;
975
976         list_for_each_entry(dentry, dentry_list, d_extraction_list_node) {
977                 count++;
978                 if ((dentry->d_inode->i_attributes & FILE_ATTRIBUTE_DIRECTORY) &&
979                     dentry_has_short_name(dentry))
980                 {
981                         count++;
982                 }
983         }
984
985         return count;
986 }
987
988 static int
989 ntfs_3g_extract(struct list_head *dentry_list, struct apply_ctx *_ctx)
990 {
991         struct ntfs_3g_apply_ctx *ctx = (struct ntfs_3g_apply_ctx *)_ctx;
992         ntfs_volume *vol;
993         struct wim_dentry *root;
994         int ret;
995
996         /* For NTFS-3g extraction mode we require that the dentries to extract
997          * form a single tree.  */
998         root = list_first_entry(dentry_list, struct wim_dentry,
999                                 d_extraction_list_node);
1000
1001         /* Mount the NTFS volume.  */
1002         vol = ntfs_mount(ctx->common.target, 0);
1003         if (!vol) {
1004                 ERROR_WITH_ERRNO("Failed to mount \"%s\" with NTFS-3g",
1005                                  ctx->common.target);
1006                 return WIMLIB_ERR_NTFS_3G;
1007         }
1008         ctx->vol = vol;
1009
1010         /* Create all inodes and aliases, including short names, and set
1011          * metadata (attributes, security descriptors, and timestamps).  */
1012
1013         ret = start_file_structure_phase(&ctx->common,
1014                                          ntfs_3g_count_dentries(dentry_list));
1015         if (ret)
1016                 goto out_unmount;
1017
1018         ret = ntfs_3g_create_directories(root, dentry_list, ctx);
1019         if (ret)
1020                 goto out_unmount;
1021
1022         ret = ntfs_3g_create_nondirectories(dentry_list, ctx);
1023         if (ret)
1024                 goto out_unmount;
1025
1026         ret = end_file_structure_phase(&ctx->common);
1027         if (ret)
1028                 goto out_unmount;
1029
1030         /* Extract blobs.  */
1031         struct read_blob_callbacks cbs = {
1032                 .begin_blob     = ntfs_3g_begin_extract_blob,
1033                 .consume_chunk  = ntfs_3g_extract_chunk,
1034                 .end_blob       = ntfs_3g_end_extract_blob,
1035                 .ctx            = ctx,
1036         };
1037         ret = extract_blob_list(&ctx->common, &cbs);
1038
1039         /* We do not need a final pass to set timestamps because libntfs-3g does
1040          * not update timestamps automatically (exception:
1041          * ntfs_set_ntfs_dos_name() does, but we handle this elsewhere).  */
1042
1043 out_unmount:
1044         if (ntfs_umount(ctx->vol, FALSE) && !ret) {
1045                 ERROR_WITH_ERRNO("Failed to unmount \"%s\" with NTFS-3g",
1046                                  ctx->common.target);
1047                 ret = WIMLIB_ERR_NTFS_3G;
1048         }
1049         return ret;
1050 }
1051
1052 const struct apply_operations ntfs_3g_apply_ops = {
1053         .name                   = "NTFS-3g",
1054         .get_supported_features = ntfs_3g_get_supported_features,
1055         .extract                = ntfs_3g_extract,
1056         .context_size           = sizeof(struct ntfs_3g_apply_ctx),
1057         .single_tree_only       = true,
1058 };
1059
1060 void
1061 libntfs3g_global_init(void)
1062 {
1063        ntfs_set_char_encoding(setlocale(LC_ALL, ""));
1064 }