X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fntfs-3g_capture.c;h=978c2b49d8a8ee16d165b6fb4ea5fb462e5eec67;hp=256e249431e32405fc45eaf1ecb58b60e0b0b0cf;hb=ed8c19061f11e8448abd73289e996a0067d9fb71;hpb=e8c3ca2d1d0cac3d64985b45a9f654d2029a7518 diff --git a/src/ntfs-3g_capture.c b/src/ntfs-3g_capture.c index 256e2494..978c2b49 100644 --- a/src/ntfs-3g_capture.c +++ b/src/ntfs-3g_capture.c @@ -53,10 +53,10 @@ #include /* This should be included last as it requires definitions from above not included by itself */ -#include "wimlib/buffer_io.h" #include "wimlib/capture.h" #include "wimlib/dentry.h" #include "wimlib/encoding.h" +#include "wimlib/endianness.h" #include "wimlib/error.h" #include "wimlib/lookup_table.h" #include "wimlib/ntfs_3g.h" @@ -151,7 +151,7 @@ read_reparse_tag(ntfs_inode *ni, struct ntfs_location *loc, u32 *reparse_tag_ret) { int ret; - u8 buf[8]; + le32 reparse_tag; ntfs_attr *na; na = open_ntfs_attr(ni, loc); @@ -160,12 +160,14 @@ read_reparse_tag(ntfs_inode *ni, struct ntfs_location *loc, goto out; } - if (ntfs_attr_pread(na, 0, 8, buf) != 8) { + if (ntfs_attr_pread(na, 0, sizeof(reparse_tag), + &reparse_tag) != sizeof(reparse_tag)) + { ERROR_WITH_ERRNO("Error reading reparse data"); ret = WIMLIB_ERR_NTFS_3G; goto out_close_ntfs_attr; } - *reparse_tag_ret = le32_to_cpu(*(u32*)buf); + *reparse_tag_ret = le32_to_cpu(reparse_tag); DEBUG("ReparseTag = %#x", *reparse_tag_ret); ret = 0; out_close_ntfs_attr: @@ -197,7 +199,7 @@ capture_ntfs_streams(struct wim_inode *inode, actx = ntfs_attr_get_search_ctx(ni, NULL); if (!actx) { ERROR_WITH_ERRNO("Cannot get NTFS attribute search " - "context"); + "context for \"%s\"", path); return WIMLIB_ERR_NTFS_3G; } @@ -220,21 +222,18 @@ capture_ntfs_streams(struct wim_inode *inode, goto out_put_actx; } ntfs_loc->ntfs_vol = vol; - ntfs_loc->path = MALLOC(path_len + 1); + ntfs_loc->path = memdup(path, path_len + 1); if (!ntfs_loc->path) { ret = WIMLIB_ERR_NOMEM; goto out_free_ntfs_loc; } - memcpy(ntfs_loc->path, path, path_len + 1); if (name_length) { - ntfs_loc->stream_name = MALLOC(name_length * 2); + ntfs_loc->stream_name = memdup(attr_record_name(actx->attr), + name_length * 2); if (!ntfs_loc->stream_name) { ret = WIMLIB_ERR_NOMEM; goto out_free_ntfs_loc; } - memcpy(ntfs_loc->stream_name, - attr_record_name(actx->attr), - actx->attr->name_length * 2); ntfs_loc->stream_name_nchars = name_length; } @@ -248,8 +247,8 @@ capture_ntfs_streams(struct wim_inode *inode, ntfs_loc = NULL; if (type == AT_REPARSE_POINT) { if (data_size < 8) { - ERROR("Invalid reparse data (only %u bytes)!", - (unsigned)data_size); + ERROR("Invalid reparse data on \"%s\" " + "(only %u bytes)!", path, (unsigned)data_size); ret = WIMLIB_ERR_NTFS_3G; goto out_free_lte; } @@ -268,13 +267,18 @@ capture_ntfs_streams(struct wim_inode *inode, /* Unnamed data stream. Put the reference to it in the * dentry's inode. */ if (inode->i_lte) { - ERROR("Found two un-named data streams for `%s'", - path); - ret = WIMLIB_ERR_NTFS_3G; - goto out_free_lte; + if (lte) { + ERROR("Found two un-named data streams for \"%s\" " + "(sizes = %"PRIu64", %"PRIu64")", + path, wim_resource_size(inode->i_lte), + wim_resource_size(lte)); + ret = WIMLIB_ERR_NTFS_3G; + goto out_free_lte; + } + } else { + stream_id = 0; + inode->i_lte = lte; } - stream_id = 0; - inode->i_lte = lte; } else { /* Named data stream. Put the reference to it in the * alternate data stream entries */ @@ -299,8 +303,7 @@ capture_ntfs_streams(struct wim_inode *inode, if (errno == ENOENT) { ret = 0; } else { - ERROR_WITH_ERRNO("Error listing NTFS attributes from `%s'", - path); + ERROR_WITH_ERRNO("Error listing NTFS attributes of \"%s\"", path); ret = WIMLIB_ERR_NTFS_3G; } goto out_put_actx; @@ -315,9 +318,9 @@ out_free_ntfs_loc: out_put_actx: ntfs_attr_put_search_ctx(actx); if (ret == 0) - DEBUG2("Successfully captured NTFS streams from `%s'", path); + DEBUG2("Successfully captured NTFS streams from \"%s\"", path); else - ERROR("Failed to capture NTFS streams from `%s'", path); + ERROR("Failed to capture NTFS streams from \"%s\"", path); return ret; } @@ -525,12 +528,14 @@ wim_ntfs_capture_filldir(void *dirent, const ntfschar *name, ret = build_dentry_tree_ntfs_recursive(&child, ctx->dir_ni, ni, ctx->path, path_len, name_type, ctx->vol, ctx->params); + path_len -= mbs_name_nbytes + 1; if (child) dentry_add_child(ctx->parent, child); ntfs_inode_close(ni); out_free_mbs_name: FREE(mbs_name); out: + ctx->path[ctx->path_len] = '\0'; return ret; } @@ -548,7 +553,7 @@ build_dentry_tree_ntfs_recursive(struct wim_dentry **root_ret, ntfs_volume *vol, struct add_image_params *params) { - u32 attributes; + le32 attributes; int ret; struct wim_dentry *root; struct wim_inode *inode; @@ -576,10 +581,9 @@ build_dentry_tree_ntfs_recursive(struct wim_dentry **root_ret, ctx.vol = vol; ret = ntfs_xattr_system_getxattr(&ctx, XATTR_NTFS_ATTRIB, ni, dir_ni, (char *)&attributes, - sizeof(u32)); - if (ret != 4) { - ERROR_WITH_ERRNO("Failed to get NTFS attributes from `%s'", - path); + sizeof(attributes)); + if (ret != sizeof(attributes)) { + ERROR_WITH_ERRNO("Failed to get NTFS attributes from \"%s\"", path); return WIMLIB_ERR_NTFS_3G; } @@ -645,7 +649,7 @@ build_dentry_tree_ntfs_recursive(struct wim_dentry **root_ret, }; ret = ntfs_readdir(ni, &pos, &ctx, wim_ntfs_capture_filldir); if (ret) { - ERROR_WITH_ERRNO("ntfs_readdir()"); + ERROR_WITH_ERRNO("Error reading directory \"%s\"", path); ret = WIMLIB_ERR_NTFS_3G; } else { ret = for_dentry_child(root, set_dentry_dos_name, @@ -725,12 +729,22 @@ build_dentry_tree_ntfs(struct wim_dentry **root_p, DEBUG("Mounting NTFS volume `%s' read-only", device); +/* NTFS-3g 2013 renamed the "read-only" mount flag from MS_RDONLY to + * NTFS_MNT_RDONLY. + * + * Unfortunately we can't check for defined(NTFS_MNT_RDONLY) because + * NTFS_MNT_RDONLY is an enumerated constant. Also, the NTFS-3g headers don't + * seem to contain any explicit version information. So we have to rely on a + * test done at configure time to detect whether NTFS_MNT_RDONLY should be used. + * */ #ifdef HAVE_NTFS_MNT_RDONLY /* NTFS-3g 2013 */ vol = ntfs_mount(device, NTFS_MNT_RDONLY); -#else +#elif defined(MS_RDONLY) /* NTFS-3g 2011, 2012 */ vol = ntfs_mount(device, MS_RDONLY); +#else + #error "Can't find NTFS_MNT_RDONLY or MS_RDONLY flags" #endif if (!vol) { ERROR_WITH_ERRNO("Failed to mount NTFS volume `%s' read-only",