X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fntfs-3g_apply.c;h=4e5926bcc71f21ea0fad433e043b33095b8e0abc;hp=0ec4702fc736f859b2b552641e5e8d3fc64c0ce8;hb=fe328582e4ba43a639944067c3232358069c2e01;hpb=e8c3ca2d1d0cac3d64985b45a9f654d2029a7518;ds=sidebyside diff --git a/src/ntfs-3g_apply.c b/src/ntfs-3g_apply.c index 0ec4702f..4e5926bc 100644 --- a/src/ntfs-3g_apply.c +++ b/src/ntfs-3g_apply.c @@ -43,7 +43,7 @@ #include #include "wimlib/apply.h" -#include "wimlib/buffer_io.h" +#include "wimlib/compiler.h" #include "wimlib/dentry.h" #include "wimlib/encoding.h" #include "wimlib/error.h" @@ -305,7 +305,7 @@ apply_file_attributes_and_security_data(ntfs_inode *ni, { int ret; struct SECURITY_CONTEXT ctx; - u32 attributes_le32; + le32 attributes; const struct wim_inode *inode; inode = dentry->d_inode; @@ -313,13 +313,13 @@ apply_file_attributes_and_security_data(ntfs_inode *ni, DEBUG("Setting NTFS file attributes on `%s' to %#"PRIx32, dentry->_full_path, inode->i_attributes); - attributes_le32 = cpu_to_le32(inode->i_attributes); + attributes = cpu_to_le32(inode->i_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); + (char*)&attributes, + sizeof(attributes), 0); if (ret) { ERROR("Failed to set NTFS file attributes on `%s'", dentry->_full_path); @@ -357,48 +357,25 @@ static int apply_reparse_data(ntfs_inode *ni, struct wim_dentry *dentry, union wimlib_progress_info *progress_info) { - struct wim_lookup_table_entry *lte; int ret; - - lte = inode_unnamed_lte_resolved(dentry->d_inode); + u8 rpbuf[REPARSE_POINT_MAX_SIZE] _aligned_attribute(8); + u16 rpbuflen; DEBUG("Applying reparse data to `%s'", dentry->_full_path); - if (!lte) { - ERROR("Could not find reparse data for `%s'", - dentry->_full_path); - return WIMLIB_ERR_INVALID_DENTRY; - } - - /* "Reparse point data, including the tag and optional GUID, cannot - * exceed 16 kilobytes." - MSDN */ - if (wim_resource_size(lte) > REPARSE_POINT_MAX_SIZE - 8) { - ERROR("Reparse data of `%s' is too long (%"PRIu64" bytes)", - dentry->_full_path, wim_resource_size(lte)); - return WIMLIB_ERR_INVALID_DENTRY; - } - - u8 reparse_data_buf[8 + wim_resource_size(lte)]; - u8 *p = reparse_data_buf; - p = put_u32(p, dentry->d_inode->i_reparse_tag); /* ReparseTag */ - DEBUG("ReparseTag = %#x", dentry->d_inode->i_reparse_tag); - p = put_u16(p, wim_resource_size(lte)); /* ReparseDataLength */ - p = put_u16(p, 0); /* Reserved */ - - ret = read_full_resource_into_buf(lte, p); + ret = wim_inode_get_reparse_data(dentry->d_inode, rpbuf, &rpbuflen); if (ret) return ret; - ret = ntfs_set_ntfs_reparse_data(ni, (char*)reparse_data_buf, - wim_resource_size(lte) + 8, 0); + ret = ntfs_set_ntfs_reparse_data(ni, rpbuf, rpbuflen, 0); if (ret) { ERROR_WITH_ERRNO("Failed to set NTFS reparse data on `%s'", dentry->_full_path); return WIMLIB_ERR_NTFS_3G; - } else { - progress_info->extract.completed_bytes += wim_resource_size(lte); } - return ret; + + progress_info->extract.completed_bytes += rpbuflen - 8; + return 0; } /* @@ -481,7 +458,8 @@ do_apply_dentry_ntfs(struct wim_dentry *dentry, ntfs_inode *dir_ni, } /* Set DOS (short) name if given */ - if (dentry_has_short_name(dentry)) { + if (dentry_has_short_name(dentry) && !dentry->dos_name_invalid) + { char *short_name_mbs; size_t short_name_mbs_nbytes; ret = utf16le_to_tstr(dentry->short_name, @@ -498,9 +476,9 @@ do_apply_dentry_ntfs(struct wim_dentry *dentry, ntfs_inode *dir_ni, short_name_mbs_nbytes, 0); FREE(short_name_mbs); if (ret) { - ERROR_WITH_ERRNO("Could not set DOS (short) name for `%s'", - dentry->_full_path); - ret = WIMLIB_ERR_NTFS_3G; + WARNING_WITH_ERRNO("Could not set DOS (short) name for `%s'", + dentry->_full_path); + ret = 0; } /* inodes have been closed by ntfs_set_ntfs_dos_name(). */ goto out; @@ -535,6 +513,10 @@ apply_root_dentry_ntfs(struct wim_dentry *dentry, ntfs_inode *ni; int ret = 0; + ret = calculate_dentry_full_path(dentry); + if (ret) + return ret; + ni = ntfs_pathname_to_inode(vol, NULL, "/"); if (!ni) { ERROR_WITH_ERRNO("Could not find root NTFS inode"); @@ -616,10 +598,10 @@ apply_dentry_ntfs(struct wim_dentry *dentry, void *arg) again: orig_dentry = NULL; if (!dentry->d_inode->i_dos_name_extracted && - !dentry_has_short_name(dentry)) + (!dentry_has_short_name(dentry) || dentry->dos_name_invalid)) { inode_for_each_dentry(other, dentry->d_inode) { - if (dentry_has_short_name(other)) { + if (dentry_has_short_name(other) && !other->dos_name_invalid) { orig_dentry = dentry; dentry = other; break; @@ -627,6 +609,11 @@ again: } } dentry->d_inode->i_dos_name_extracted = 1; + + ret = calculate_dentry_full_path(dentry); + if (ret) + return ret; + ntfs_inode *dir_ni = dentry_open_parent_ni(dentry, vol); if (dir_ni) { ret = do_apply_dentry_ntfs(dentry, dir_ni, arg); @@ -647,8 +634,7 @@ apply_dentry_timestamps_ntfs(struct wim_dentry *dentry, void *arg) { struct apply_args *args = arg; ntfs_volume *vol = args->vol; - u8 *p; - u8 buf[24]; + u64 ntfs_timestamps[3]; ntfs_inode *ni; int ret; @@ -661,11 +647,13 @@ apply_dentry_timestamps_ntfs(struct wim_dentry *dentry, void *arg) return WIMLIB_ERR_NTFS_3G; } - p = buf; - p = put_u64(p, dentry->d_inode->i_creation_time); - p = put_u64(p, dentry->d_inode->i_last_write_time); - p = put_u64(p, dentry->d_inode->i_last_access_time); - ret = ntfs_inode_set_times(ni, (const char*)buf, 3 * sizeof(u64), 0); + /* Note: ntfs_inode_set_times() expects the times in native byte order, + * not little endian. */ + ntfs_timestamps[0] = dentry->d_inode->i_creation_time; + ntfs_timestamps[1] = dentry->d_inode->i_last_write_time; + ntfs_timestamps[2] = dentry->d_inode->i_last_access_time; + ret = ntfs_inode_set_times(ni, (const char*)ntfs_timestamps, + sizeof(ntfs_timestamps), 0); if (ret != 0) { ERROR_WITH_ERRNO("Failed to set NTFS timestamps on `%s'", dentry->_full_path);