X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fntfs-apply.c;h=d9f6d37a5da9445789bd5d7a1453b472a0d19b9b;hp=1a4cb7dd190594546d6406a39d72b6de14d2b60c;hb=fec65d853bbcfdb4639d8446db8d3c681c7ae00d;hpb=e901f5bc2e56a930ac71c545586aaf70b0fd2b56 diff --git a/src/ntfs-apply.c b/src/ntfs-apply.c index 1a4cb7dd..d9f6d37a 100644 --- a/src/ntfs-apply.c +++ b/src/ntfs-apply.c @@ -35,10 +35,9 @@ #include #include #include -#include +#include /* security.h before xattrs.h */ +#include #include -#include -#include #include #include @@ -49,7 +48,7 @@ struct ntfs_apply_args { }; -#ifndef WITH_NEW_NTFS_3G +#if 0 extern int ntfs_set_inode_security(ntfs_inode *ni, u32 selection, const char *attr); extern int ntfs_set_inode_attributes(ntfs_inode *ni, u32 attrib); @@ -235,34 +234,58 @@ static int wim_apply_hardlink_ntfs(const struct dentry *from_dentry, return ret; } +/*#define HAVE_NTFS_INODE_FUNCTIONS*/ + static int apply_file_attributes_and_security_data(ntfs_inode *ni, + ntfs_inode *dir_ni, const struct dentry *dentry, const WIMStruct *w) { DEBUG("Setting NTFS file attributes on `%s' to %#"PRIx32, dentry->full_path_utf8, dentry->attributes); - if (ntfs_set_inode_attributes(ni, dentry->attributes)) { + int ret; +#ifdef HAVE_NTFS_INODE_FUNCTIONS + ret = ntfs_set_inode_attributes(ni, dentry->attributes); +#else + struct SECURITY_CONTEXT ctx; + u32 attributes_le32; + attributes_le32 = cpu_to_le32(dentry->attributes); + memset(&ctx, 0, sizeof(ctx)); + ctx.vol = ni->vol; + ret = ntfs_xattr_system_setxattr(&ctx, XATTR_NTFS_ATTRIB, + ni, dir_ni, + (const char*)&attributes_le32, + sizeof(u32), 0); +#endif + if (ret != 0) { ERROR("Failed to set NTFS file attributes on `%s'", dentry->full_path_utf8); return WIMLIB_ERR_NTFS_3G; } - if (dentry->security_id != -1) { const struct wim_security_data *sd; + const char *descriptor; sd = wim_const_security_data(w); wimlib_assert(dentry->security_id < sd->num_entries); + descriptor = sd->descriptors[dentry->security_id]; DEBUG("Applying security descriptor %d to `%s'", dentry->security_id, dentry->full_path_utf8); + + #ifdef HAVE_NTFS_INODE_FUNCTIONS u32 selection = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION; + ret = ntfs_set_inode_security(ni, selection, descriptor); + #else + ret = ntfs_xattr_system_setxattr(&ctx, XATTR_NTFS_ACL, + ni, dir_ni, descriptor, + sd->sizes[dentry->security_id], 0); + #endif - if (ntfs_set_inode_security(ni, selection, - (const char*)sd->descriptors[dentry->security_id])) - { + if (ret != 0) { ERROR_WITH_ERRNO("Failed to set security data on `%s'", dentry->full_path_utf8); return WIMLIB_ERR_NTFS_3G; @@ -330,13 +353,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) @@ -352,10 +371,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'", @@ -409,9 +431,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 */ @@ -424,19 +449,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; } /* @@ -465,7 +487,7 @@ static int do_wim_apply_dentry_ntfs(struct dentry *dentry, ntfs_inode *dir_ni, } - ret = apply_file_attributes_and_security_data(ni, dentry, w); + ret = apply_file_attributes_and_security_data(ni, dir_ni, dentry, w); if (ret != 0) goto out_close_dir_ni; @@ -575,7 +597,7 @@ static int wim_apply_root_dentry_ntfs(const struct dentry *dentry, ERROR_WITH_ERRNO("Could not find root NTFS inode"); return WIMLIB_ERR_NTFS_3G; } - ret = apply_file_attributes_and_security_data(ni, dentry, w); + ret = apply_file_attributes_and_security_data(ni, ni, dentry, w); if (ntfs_inode_close(ni) != 0) { ERROR_WITH_ERRNO("Failed to close NTFS inode for root " "directory"); @@ -619,8 +641,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'", @@ -669,10 +689,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); @@ -680,22 +710,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", @@ -721,11 +752,18 @@ out: * full filesystem to be applied to the volume. */ WIMLIBAPI int wimlib_apply_image_to_ntfs_volume(WIMStruct *w, int image, - const char *device, int flags) + const char *device, int flags, + WIMStruct **additional_swms, + unsigned num_additional_swms) { + struct lookup_table *joined_tab, *w_tab_save; int ret; - if (!device) + DEBUG("w->filename = %s, image = %d, device = %s, flags = 0x%x, " + "num_additional_swms = %u", + w->filename, image, device, flags, num_additional_swms); + + if (!w || !device) return WIMLIB_ERR_INVALID_PARAM; if (image == WIM_ALL_IMAGES) { ERROR("Can only apply a single image when applying " @@ -737,16 +775,39 @@ WIMLIBAPI int wimlib_apply_image_to_ntfs_volume(WIMStruct *w, int image, ERROR("directly to a NTFS volume"); return WIMLIB_ERR_INVALID_PARAM; } - ret = wimlib_select_image(w, image); + + ret = verify_swm_set(w, additional_swms, num_additional_swms); if (ret != 0) return ret; - return do_wim_apply_image_ntfs(w, device, flags); + if (num_additional_swms) { + ret = new_joined_lookup_table(w, additional_swms, + num_additional_swms, &joined_tab); + if (ret != 0) + return ret; + w_tab_save = w->lookup_table; + w->lookup_table = joined_tab; + } + + ret = wimlib_select_image(w, image); + if (ret != 0) + goto out; + + ret = do_wim_apply_image_ntfs(w, device, flags); + +out: + if (num_additional_swms) { + free_lookup_table(w->lookup_table); + w->lookup_table = w_tab_save; + } + return ret; } #else /* WITH_NTFS_3G */ WIMLIBAPI int wimlib_apply_image_to_ntfs_volume(WIMStruct *w, int image, - const char *device, int flags) + const char *device, int flags, + WIMStruct **additional_swms, + unsigned num_additional_swms) { ERROR("wimlib was compiled without support for NTFS-3g, so"); ERROR("we cannot apply a WIM image directly to a NTFS volume");