]> wimlib.net Git - wimlib/blobdiff - src/ntfs-apply.c
NTFS test updates and NTFS capture fix
[wimlib] / src / ntfs-apply.c
index d465e576b9d7953547e5e34976a52d6257e6110f..ee1982af7f63d610676f59363fede5d46b94650e 100644 (file)
  * This file is part of wimlib, a library for working with WIM files.
  *
  * wimlib is free software; you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation; either version 2.1 of the License, or (at your option)
+ * terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at your option)
  * any later version.
  *
  * wimlib is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * A PARTICULAR PURPOSE. See the GNU General Public License for more
  * details.
  *
- * You should have received a copy of the GNU Lesser General Public License
+ * You should have received a copy of the GNU General Public License
  * along with wimlib; if not, see http://www.gnu.org/licenses/.
  */
 
@@ -48,9 +48,12 @@ struct ntfs_apply_args {
        WIMStruct *w;
 };
 
-extern int ntfs_inode_set_security(ntfs_inode *ni, u32 selection,
+
+#ifndef WITH_NEW_NTFS_3G
+extern int ntfs_set_inode_security(ntfs_inode *ni, u32 selection,
                                   const char *attr);
-extern int ntfs_inode_set_attributes(ntfs_inode *ni, s32 attrib);
+extern int ntfs_set_inode_attributes(ntfs_inode *ni, u32 attrib);
+#endif
 
 /* 
  * Extracts a WIM resource to a NTFS attribute.
@@ -239,7 +242,7 @@ apply_file_attributes_and_security_data(ntfs_inode *ni,
 {
        DEBUG("Setting NTFS file attributes on `%s' to %#"PRIx32,
              dentry->full_path_utf8, dentry->attributes);
-       if (!ntfs_inode_set_attributes(ni, dentry->attributes)) {
+       if (ntfs_set_inode_attributes(ni, dentry->attributes)) {
                ERROR("Failed to set NTFS file attributes on `%s'",
                       dentry->full_path_utf8);
                return WIMLIB_ERR_NTFS_3G;
@@ -257,8 +260,8 @@ apply_file_attributes_and_security_data(ntfs_inode *ni,
                                DACL_SECURITY_INFORMATION  |
                                SACL_SECURITY_INFORMATION;
                                
-               if (!ntfs_inode_set_security(ni, selection,
-                                            (const char*)sd->descriptors[dentry->security_id]))
+               if (ntfs_set_inode_security(ni, selection,
+                                           (const char*)sd->descriptors[dentry->security_id]))
                {
                        ERROR_WITH_ERRNO("Failed to set security data on `%s'",
                                        dentry->full_path_utf8);
@@ -327,13 +330,9 @@ static int preapply_dentry_with_dos_name(struct dentry *dentry,
                                         ntfs_inode **dir_ni_p,
                                         WIMStruct *w)
 {
-       int ret;
        struct dentry *other;
        struct dentry *dentry_with_dos_name;
 
-       if (dentry->link_group_list.next == &dentry->link_group_list)
-               return 0;
-
        dentry_with_dos_name = NULL;
        list_for_each_entry(other, &dentry->link_group_list,
                            link_group_list)
@@ -349,10 +348,13 @@ static int preapply_dentry_with_dos_name(struct dentry *dentry,
                }
        }
        /* If there's a dentry with a DOS name, extract it first */
-       if (dentry_with_dos_name && !dentry_with_dos_name->extracted_file) {
+       if (dentry_with_dos_name
+           && !dentry_with_dos_name->extracted_file)
+       {
                char *p;
                const char *dir_name;
                char orig;
+               int ret;
                ntfs_volume *vol = (*dir_ni_p)->vol;
 
                DEBUG("pre-applying DOS name `%s'",
@@ -406,9 +408,12 @@ static int do_wim_apply_dentry_ntfs(struct dentry *dentry, ntfs_inode *dir_ni,
 
                /* Apply hard-linked directory in same directory with DOS name
                 * (if there is one) before this dentry */
-               ret = preapply_dentry_with_dos_name(dentry, &dir_ni, w);
-               if (ret != 0)
-                       return ret;
+               if (dentry->short_name_len == 0) {
+                       ret = preapply_dentry_with_dos_name(dentry,
+                                                           &dir_ni, w);
+                       if (ret != 0)
+                               return ret;
+               }
 
                type = S_IFREG;
                /* See if we can make a hard link */
@@ -421,19 +426,16 @@ static int do_wim_apply_dentry_ntfs(struct dentry *dentry, ntfs_inode *dir_ni,
                                ret = wim_apply_hardlink_ntfs(dentry, other,
                                                              dir_ni, &ni);
                                is_hardlink = true;
-                               if (ret != 0)
+                               if (ret) {
                                        goto out_close_dir_ni;
-                               else
+                               } else {
+                                       dentry->extracted_file = dentry->full_path_utf8;
                                        goto out_set_dos_name;
+                               }
                        }
                }
                /* Can't make a hard link; extract the file itself */
-               FREE(dentry->extracted_file);
-               dentry->extracted_file = STRDUP(dentry->full_path_utf8);
-               if (!dentry->extracted_file) {
-                       ERROR("Failed to allocate memory for filename");
-                       return WIMLIB_ERR_NOMEM;
-               }
+               dentry->extracted_file = dentry->full_path_utf8;
        }
 
        /* 
@@ -616,8 +618,6 @@ static int wim_apply_dentry_ntfs(struct dentry *dentry, void *arg)
        dir_name = dentry->full_path_utf8;
 
        dir_ni = ntfs_pathname_to_inode(vol, NULL, dir_name);
-       if (dir_ni)
-               DEBUG("Found NTFS inode for `%s'", dir_name);
        *p = orig;
        if (!dir_ni) {
                ERROR_WITH_ERRNO("Could not find NTFS inode for `%s'",
@@ -666,10 +666,20 @@ static int wim_apply_dentry_timestamps(struct dentry *dentry, void *arg)
        return ret;
 }
 
+static int dentry_clear_extracted_file(struct dentry *dentry, void *ignore)
+{
+       if (dentry->extracted_file != dentry->full_path_utf8)
+               FREE(dentry->extracted_file);
+       dentry->extracted_file = NULL;
+       return 0;
+}
+
 static int do_wim_apply_image_ntfs(WIMStruct *w, const char *device, int extract_flags)
 {
        ntfs_volume *vol;
        int ret;
+       struct dentry *root;
+       struct ntfs_apply_args args;
        
        DEBUG("Mounting NTFS volume `%s'", device);
        vol = ntfs_mount(device, 0);
@@ -677,22 +687,23 @@ static int do_wim_apply_image_ntfs(WIMStruct *w, const char *device, int extract
                ERROR_WITH_ERRNO("Failed to mount NTFS volume `%s'", device);
                return WIMLIB_ERR_NTFS_3G;
        }
-       struct ntfs_apply_args args = {
-               .vol           = vol,
-               .extract_flags = extract_flags,
-               .w             = w,
-       };
-       ret = for_dentry_in_tree(wim_root_dentry(w), wim_apply_dentry_ntfs,
-                                &args);
+       args.vol = vol;
+       args.extract_flags = extract_flags;
+       args.w = w;
+       root = wim_root_dentry(w);
+
+       for_dentry_in_tree(root, dentry_clear_extracted_file, NULL);
 
+       ret = for_dentry_in_tree(root, wim_apply_dentry_ntfs, &args);
        if (ret != 0)
                goto out;
+
        if (extract_flags & WIMLIB_EXTRACT_FLAG_VERBOSE)
                printf("Setting timestamps of extracted files on NTFS "
                       "volume `%s'\n", device);
-       ret = for_dentry_in_tree_depth(wim_root_dentry(w),
-                                      wim_apply_dentry_timestamps,
+       ret = for_dentry_in_tree_depth(root, wim_apply_dentry_timestamps,
                                       &args);
+
        if (ret == 0 && (extract_flags & WIMLIB_EXTRACT_FLAG_VERBOSE))
                printf("Finished applying image %d of %s to NTFS "
                       "volume `%s'\n",