2 * Copyright (C) 2012 Eric Biggers
4 * This file is part of wimlib, a library for working with WIM files.
6 * wimlib is free software; you can redistribute it and/or modify it under the
7 * terms of the GNU Lesser General Public License as published by the Free
8 * Software Foundation; either version 2.1 of the License, or (at your option)
11 * wimlib is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with wimlib; if not, see http://www.gnu.org/licenses/.
21 #include "wimlib_internal.h"
25 #include <ntfs-3g/volume.h>
26 #include <ntfs-3g/security.h>
29 struct ntfs_apply_args {
30 struct SECURITY_API *scapi;
32 const struct wim_security_data *sd;
34 struct ntfs_inode *parent;
37 static int ntfs_apply_dentry(struct dentry *dentry, void *arg)
39 struct ntfs_apply_args *args = arg;
40 struct SECURITY_API *scapi = args->scapi;
41 ntfs_volume *vol = args->vol;
42 const struct wim_security_data *sd = args->sd;
43 int flags = args->flags;
45 ntfs_inode *dir_ni, *ni;
47 if (dentry_is_root(dentry))
50 if (flags & WIMLIB_EXTRACT_FLAG_VERBOSE) {
51 wimlib_assert(dentry->full_path_utf8);
52 puts(dentry->full_path_utf8);
55 char *p = dentry->full_path_utf8 + dentry->full_path_utf8_len;
61 const char *dir_name = dentry->full_path_utf8;
63 dir_ni = ntfs_pathname_to_inode(vol, NULL, dir_name);
65 ret = WIMLIB_ERR_NTFS_3G;
66 ERROR_WITH_ERRNO("Could not find NTFS inode for `%s'",
72 if (dentry_is_regular_file(dentry)) {
73 ni = ntfs_create(dir_ni, 0, (ntfschar*)dentry->file_name,
74 dentry->file_name_len, S_IFREG);
75 } else if (dentry_is_directory(dentry)) {
76 ni = ntfs_create(dir_ni, 0, (ntfschar*)dentry->file_name,
77 dentry->file_name_len, S_IFDIR);
82 ERROR_WITH_ERRNO("Could not create NTFS object for `%s'",
83 dentry->full_path_utf8);
84 ret = WIMLIB_ERR_NTFS_3G;
92 static int do_ntfs_apply(WIMStruct *w, const char *device, int flags)
94 struct SECURITY_API *scapi;
96 scapi = ntfs_initialize_file_security(device, 0);
98 ERROR_WITH_ERRNO("Failed to initialize NTFS file security API "
99 "on NTFS volume `%s'", device);
101 struct ntfs_apply_args args = {
103 .vol = scapi->security.vol,
104 .sd = wim_security_data(w),
107 return for_dentry_in_tree(wim_root_dentry(w), ntfs_apply_dentry,
111 WIMLIBAPI int wimlib_apply_image_to_ntfs_volume(WIMStruct *w, int image,
112 const char *device, int flags)
117 return WIMLIB_ERR_INVALID_PARAM;
118 if (image == WIM_ALL_IMAGES) {
119 ERROR("Can only apply a single image when applying "
120 "directly to a NTFS volume");
121 return WIMLIB_ERR_INVALID_PARAM;
123 if (flags & (WIMLIB_EXTRACT_FLAG_SYMLINK | WIMLIB_EXTRACT_FLAG_HARDLINK)) {
124 ERROR("Cannot specifcy symlink or hardlink flags when applying ");
125 ERROR("directly to a NTFS volume");
126 return WIMLIB_ERR_INVALID_PARAM;
128 ret = wimlib_select_image(w, image);
133 ERROR("We are not root, but NTFS-3g requires root privileges to set arbitrary");
134 ERROR("security data on the NTFS filesystem. Please run this program as root");
135 ERROR("if you want to extract a WIM image while preserving NTFS-specific");
136 ERROR("information.");
138 return WIMLIB_ERR_NOT_ROOT;
140 return do_ntfs_apply(w, device, flags);
143 #else /* WITH_NTFS_3G */
144 WIMLIBAPI int wimlib_apply_image_to_ntfs_volume(WIMStruct *w, int image,
145 const char *device, int flags)
147 ERROR("wimlib was compiled without support for NTFS-3g, so");
148 ERROR("we cannot apply a WIM image directly to a NTFS volume");
149 return WIMLIB_ERR_UNSUPPORTED;
151 #endif /* WITH_NTFS_3G */