X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fntfs-3g_apply.c;h=3697b333d4c5b61c33a290e80cb59e7ca7fbb78d;hb=754936f4654fae549d0fb6586c1f4cfea7e732d9;hp=acf1b95485ac61d2132897bd6eb6c7434aefb085;hpb=ba30eb632ad9bd2e008267a10eed3e20e4c94ed2;p=wimlib diff --git a/src/ntfs-3g_apply.c b/src/ntfs-3g_apply.c index acf1b954..3697b333 100644 --- a/src/ntfs-3g_apply.c +++ b/src/ntfs-3g_apply.c @@ -167,7 +167,7 @@ ntfs_3g_restore_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni, ret = -1; } utf16le_put_tstr(dos_name); - if (ret) { + if (unlikely(ret)) { int err = errno; ERROR_WITH_ERRNO("Failed to set DOS name of \"%s\" in NTFS " "volume", dentry_full_path(dentry)); @@ -179,6 +179,19 @@ ntfs_3g_restore_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni, "was fixed in the development version of " "NTFS-3G in June 2016."); } + if (err == EINVAL) { + utf16lechar c = + dentry->d_name[dentry->d_name_nbytes / 2 - 1]; + if (c == cpu_to_le16('.') || c == cpu_to_le16(' ')) { + ERROR("This error was probably caused by a " + "known bug in libntfs-3g where it is " + "unable to set DOS names on files whose " + "long names end with a dot or space " + "character. See " + "https://wimlib.net/forums/viewtopic.php?f=1&t=294 " + "for more information."); + } + } ret = WIMLIB_ERR_SET_SHORT_NAME; goto out_close; } @@ -805,11 +818,14 @@ out: return ret; } -/* Note: contrary to its documentation, ntfs_attr_pwrite() can return a short - * count in non-error cases --- specifically, when writing to a compressed - * attribute and the requested count exceeds the size of an NTFS "compression - * block". Therefore, we must continue calling ntfs_attr_pwrite() until all - * bytes have been written or a real error has occurred. */ +/* + * Note: prior to NTFS-3G version 2016.2.22, ntfs_attr_pwrite() could return a + * short count in non-error cases, contrary to its documentation. Specifically, + * a short count could be returned when writing to a compressed attribute and + * the requested count exceeded the size of an NTFS "compression block". + * Therefore, we must continue calling ntfs_attr_pwrite() until all bytes have + * been written or a real error has occurred. + */ static bool ntfs_3g_full_pwrite(ntfs_attr *na, u64 offset, size_t size, const u8 *data) { @@ -911,6 +927,16 @@ ntfs_3g_extract(struct list_head *dentry_list, struct apply_ctx *_ctx) } ctx->vol = vol; + /* Opening $Secure is required to set security descriptors in NTFS v3.0 + * format, where security descriptors are stored in a per-volume index + * rather than being fully specified for each file. */ + if (ntfs_open_secure(vol) && vol->major_ver >= 3) { + ERROR_WITH_ERRNO("Unable to open security descriptor index of " + "NTFS volume \"%s\"", ctx->common.target); + ret = WIMLIB_ERR_NTFS_3G; + goto out_unmount; + } + /* Create all inodes and aliases, including short names, and set * metadata (attributes, security descriptors, and timestamps). */ @@ -945,6 +971,17 @@ ntfs_3g_extract(struct list_head *dentry_list, struct apply_ctx *_ctx) * ntfs_set_ntfs_dos_name() does, but we handle this elsewhere). */ out_unmount: + if (vol->secure_ni) { + ntfs_index_ctx_put(vol->secure_xsii); + ntfs_index_ctx_put(vol->secure_xsdh); + if (ntfs_inode_close(vol->secure_ni) && !ret) { + ERROR_WITH_ERRNO("Failed to close security descriptor " + "index of NTFS volume \"%s\"", + ctx->common.target); + ret = WIMLIB_ERR_NTFS_3G; + } + vol->secure_ni = NULL; + } if (ntfs_umount(ctx->vol, FALSE) && !ret) { ERROR_WITH_ERRNO("Failed to unmount \"%s\" with NTFS-3G", ctx->common.target);