From 4449a8d6647cb1b5c251de9b77a0f4230811f09e Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Tue, 18 Dec 2012 14:57:04 -0600 Subject: [PATCH] Use NTFS-3g character conversion functions if available Make utf16_to_utf8() and utf8_to_utf16() call into libntfs-3g if support is compiled in. --- src/ntfs-capture.c | 4 ++-- src/util.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/ntfs-capture.c b/src/ntfs-capture.c index 5b47b564..ae550213 100644 --- a/src/ntfs-capture.c +++ b/src/ntfs-capture.c @@ -515,7 +515,6 @@ static int build_dentry_tree_ntfs_recursive(struct dentry **root_p, u32 attributes; int mrec_flags; int ret; - char dos_name_utf8[64]; struct dentry *root; if (exclude_path(path, config, false)) { @@ -561,8 +560,9 @@ static int build_dentry_tree_ntfs_recursive(struct dentry **root_p, if (dir_ni && (name_type == FILE_NAME_WIN32_AND_DOS || name_type == FILE_NAME_WIN32)) { + char dos_name_utf8[12 * 4 + 1] = {0}; ret = ntfs_get_ntfs_dos_name(ni, dir_ni, dos_name_utf8, - sizeof(dos_name_utf8)); + sizeof(dos_name_utf8) - 1); if (ret > 0) { DEBUG("Changing short name of `%s'", path); ret = change_dentry_short_name(root, dos_name_utf8, diff --git a/src/util.c b/src/util.c index 7858a1c9..bcaefacd 100644 --- a/src/util.c +++ b/src/util.c @@ -36,6 +36,11 @@ #include #include +#ifdef WITH_NTFS_3G +#include +#include +#endif + /* True if wimlib is to print an informational message when an error occurs. * This can be turned off by calling wimlib_set_print_errors(false). */ #ifdef ENABLE_ERROR_MESSAGES @@ -285,6 +290,22 @@ static iconv_t cd_utf16_to_utf8 = (iconv_t)(-1); char *utf16_to_utf8(const char *utf16_str, size_t utf16_len, size_t *utf8_len_ret) { +#ifdef WITH_NTFS_3G + if (utf16_len & 1) { + errno = -EILSEQ; + return NULL; + } + char *outs = NULL; + int outs_len = ntfs_ucstombs((const ntfschar*)utf16_str, + utf16_len >> 1, &outs, 0); + if (outs_len >= 0) { + *utf8_len_ret = outs_len; + } else { + ERROR_WITH_ERRNO("Error converting UTF-16LE string to UTF-8"); + outs = NULL; + } + return outs; +#else if (cd_utf16_to_utf8 == (iconv_t)(-1)) { cd_utf16_to_utf8 = iconv_open("UTF-8", "UTF-16LE"); if (cd_utf16_to_utf8 == (iconv_t)-1) { @@ -317,6 +338,7 @@ char *utf16_to_utf8(const char *utf16_str, size_t utf16_len, *utf8_len_ret = utf8_len; orig_utf8_str[utf8_len] = '\0'; return orig_utf8_str; +#endif } static iconv_t cd_utf8_to_utf16 = (iconv_t)(-1); @@ -326,6 +348,17 @@ static iconv_t cd_utf8_to_utf16 = (iconv_t)(-1); char *utf8_to_utf16(const char *utf8_str, size_t utf8_len, size_t *utf16_len_ret) { +#ifdef WITH_NTFS_3G + char *outs = NULL; + int outs_nchars = ntfs_mbstoucs(utf8_str, (ntfschar**)&outs); + if (outs_nchars >= 0) { + *utf16_len_ret = (size_t)outs_nchars * 2; + } else { + ERROR_WITH_ERRNO("Error converting UTF-8 string to UTF-16LE"); + outs = NULL; + } + return outs; +#else if (cd_utf8_to_utf16 == (iconv_t)(-1)) { cd_utf8_to_utf16 = iconv_open("UTF-16LE", "UTF-8"); if (cd_utf8_to_utf16 == (iconv_t)-1) { @@ -361,6 +394,7 @@ char *utf8_to_utf16(const char *utf8_str, size_t utf8_len, orig_utf16_str[utf16_len] = '\0'; orig_utf16_str[utf16_len + 1] = '\0'; return orig_utf16_str; +#endif } static bool seeded = false; -- 2.43.0