From be823c7a1ea18d8b17bd14614748d7cbdd420731 Mon Sep 17 00:00:00 2001 From: szaka Date: Wed, 5 Apr 2006 02:45:55 +0000 Subject: [PATCH] libntfs: add ntfs_str2ucs and ntfs_freeucs function, and convert copy-pastes to use them --- ChangeLog | 2 ++ include/ntfs/unistr.h | 4 +++ libntfs/unistr.c | 53 ++++++++++++++++++++++++++++ ntfsprogs/mkntfs.c | 75 ++++++++++++++-------------------------- ntfsprogs/ntfsclone.c | 25 +++----------- ntfsprogs/ntfscp.c | 20 +++++------ ntfsprogs/ntfsresize.c | 33 ++++++------------ ntfsprogs/ntfstruncate.c | 6 ++-- 8 files changed, 109 insertions(+), 109 deletions(-) diff --git a/ChangeLog b/ChangeLog index e0a7f69d..1a46320c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -32,6 +32,8 @@ xx/xx/2006 - 1.13.1-WIP - ntfsinfo: dump either a minimal (default) or the entire attribute header (--verbose) for all attributes types. Also removed a lot of redundant code and made some formatting corrections. (Szaka) + - libntfs: add ntfs_str2ucs and ntfs_freeucs function, and convert + copy-pastes to use them. (Szaka) 27/02/2006 - 1.13.0 - Lots and lots and lots of fixes and enhancements. diff --git a/include/ntfs/unistr.h b/include/ntfs/unistr.h index d5b22627..81450f89 100644 --- a/include/ntfs/unistr.h +++ b/include/ntfs/unistr.h @@ -61,5 +61,9 @@ extern int ntfs_mbstoucs(const char *ins, ntfschar **outs, int outs_len); extern void ntfs_upcase_table_build(ntfschar *uc, u32 uc_len); +extern ntfschar *ntfs_str2ucs(const char *s, int *len); + +extern void ntfs_ucsfree(ntfschar *ucs); + #endif /* defined _NTFS_UNISTR_H */ diff --git a/libntfs/unistr.c b/libntfs/unistr.c index ed4adf80..906a850d 100644 --- a/libntfs/unistr.c +++ b/libntfs/unistr.c @@ -39,6 +39,7 @@ #include #endif +#include "attrib.h" #include "types.h" #include "unistr.h" #include "debug.h" @@ -700,3 +701,55 @@ void ntfs_upcase_table_build(ntfschar *uc, u32 uc_len) for (r = 0; uc_byte_table[r][0]; r++) uc[uc_byte_table[r][0]] = uc_byte_table[r][1]; } + +/** + * ntfs_str2ucs - convert a string to a valid NTFS file name + * @s: input string + * @len: length of output buffer in Unicode characters + * + * Convert the input @s string into the corresponding little endian, + * 2-byte Unicode string. The length of the converted string is less + * or equal to the maximum length allowed by the NTFS format (255). + * + * If @s is NULL then return AT_UNNAMED. + * + * On success the function returns the Unicode string in an allocated + * buffer and the caller is responsible to free it when it's not needed + * anymore. + * + * On error NULL is returned and errno is set to the error code. + */ +ntfschar *ntfs_str2ucs(const char *s, int *len) +{ + ntfschar *ucs = NULL; + + if (s && ((*len = ntfs_mbstoucs(s, &ucs, 0)) == -1)) { + ntfs_log_perror("Couldn't convert '%s' to Unicode", s); + return NULL; + } + if (*len > 0xff) { + free(ucs); + errno = ENAMETOOLONG; + return NULL; + } + if (!ucs || !*len) { + ucs = AT_UNNAMED; + *len = 0; + } + return ucs; +} + +/** + * ntfs_ucsfree - free memory allocated by ntfs_str2ucs() + * @ucs input string to be freed + * + * Free memory at @ucs and which was allocated by ntfs_str2ucs. + * + * Return value: none. + */ +void ntfs_ucsfree(ntfschar *ucs) +{ + if (ucs && (ucs != AT_UNNAMED)) + free(ucs); +} + diff --git a/ntfsprogs/mkntfs.c b/ntfsprogs/mkntfs.c index 1eb2f867..5a688788 100644 --- a/ntfsprogs/mkntfs.c +++ b/ntfsprogs/mkntfs.c @@ -1515,15 +1515,11 @@ static int insert_positioned_attr_in_mft_record(MFT_RECORD *m, attr_lookup(); else */ - if (name) { - uname_len = ntfs_mbstoucs(name, &uname, 0); - if (uname_len < 0) - return -errno; - if (uname_len > 0xff) { - free(uname); - return -ENAMETOOLONG; - } - } + + uname = ntfs_str2ucs(name, &uname_len); + if (!uname) + return -errno; + /* Check if the attribute is already there. */ ctx = ntfs_attr_get_search_ctx(NULL, m); if (!ctx) { @@ -1674,7 +1670,7 @@ static int insert_positioned_attr_in_mft_record(MFT_RECORD *m, err_out: if (ctx) ntfs_attr_put_search_ctx(ctx); - free(uname); + ntfs_ucsfree(uname); return err; } @@ -1701,17 +1697,11 @@ static int insert_non_resident_attr_in_mft_record(MFT_RECORD *m, attr_lookup(); else */ - if (name) { - uname_len = ntfs_mbstoucs(name, &uname, 0); - if (uname_len < 0) - return -errno; - if (uname_len > 0xff) { - free(uname); - return -ENAMETOOLONG; - } - } else { - uname = AT_UNNAMED; - } + + uname = ntfs_str2ucs(name, &uname_len); + if (!uname) + return -errno; + /* Check if the attribute is already there. */ ctx = ntfs_attr_get_search_ctx(NULL, m); if (!ctx) { @@ -1866,8 +1856,7 @@ static int insert_non_resident_attr_in_mft_record(MFT_RECORD *m, err_out: if (ctx) ntfs_attr_put_search_ctx(ctx); - if (uname && (uname != AT_UNNAMED)) - free(uname); + ntfs_ucsfree(uname); free(rl); return err; } @@ -1893,17 +1882,11 @@ static int insert_resident_attr_in_mft_record(MFT_RECORD *m, mkntfs_attr_lookup(); else */ - if (name) { - uname_len = ntfs_mbstoucs(name, &uname, 0); - if (uname_len < 0) - return -errno; - if (uname_len > 0xff) { - free(uname); - return -ENAMETOOLONG; - } - } else { - uname = AT_UNNAMED; - } + + uname = ntfs_str2ucs(name, &uname_len); + if (!uname) + return -errno; + /* Check if the attribute is already there. */ ctx = ntfs_attr_get_search_ctx(NULL, m); if (!ctx) { @@ -1978,8 +1961,7 @@ static int insert_resident_attr_in_mft_record(MFT_RECORD *m, err_out: if (ctx) ntfs_attr_put_search_ctx(ctx); - if (uname && (uname != AT_UNNAMED)) - free(uname); + ntfs_ucsfree(uname); return err; } @@ -2426,33 +2408,26 @@ static int upgrade_to_large_index(MFT_RECORD *m, const char *name, char *re_start, *re_end; int i, err, index_block_size; - if (name) { - uname_len = ntfs_mbstoucs(name, &uname, 0); - if (uname_len < 0) - return -errno; - if (uname_len > 0xff) { - free(uname); - return -ENAMETOOLONG; - } - } else { - uname = NULL; - } + uname = ntfs_str2ucs(name, &uname_len); + if (!uname) + return -errno; + /* Find the index root attribute. */ ctx = ntfs_attr_get_search_ctx(NULL, m); if (!ctx) { ntfs_log_error("Failed to allocate attribute search context.\n"); - free(uname); + ntfs_ucsfree(uname); return -ENOMEM; } if (ic == IGNORE_CASE) { ntfs_log_error("FIXME: Hit unimplemented code path #4.\n"); err = -EOPNOTSUPP; - free(uname); + ntfs_ucsfree(uname); goto err_out; } err = mkntfs_attr_lookup(AT_INDEX_ROOT, uname, uname_len, ic, 0, NULL, 0, ctx); - free(uname); + ntfs_ucsfree(uname); if (err) { err = -ENOTDIR; goto err_out; diff --git a/ntfsprogs/ntfsclone.c b/ntfsprogs/ntfsclone.c index b38c3ed2..8aa18281 100644 --- a/ntfsprogs/ntfsclone.c +++ b/ntfsprogs/ntfsclone.c @@ -1539,21 +1539,6 @@ static ntfs_attr_search_ctx *attr_get_search_ctx(ntfs_inode *ni) return ret; } -static int str2unicode(const char *aname, ntfschar **ustr, int *len) -{ - if (aname && ((*len = ntfs_mbstoucs(aname, ustr, 0)) == -1)) { - perr_printf("Unable to convert '%s' to Unicode", aname); - return -1; - } - - if (!*ustr || !*len) { - *ustr = AT_UNNAMED; - *len = 0; - } - - return 0; -} - /** * lookup_data_attr * @@ -1562,22 +1547,22 @@ static int str2unicode(const char *aname, ntfschar **ustr, int *len) static ntfs_attr_search_ctx *lookup_data_attr(ntfs_inode *ni, const char *aname) { ntfs_attr_search_ctx *ctx; - ntfschar *ustr = NULL; + ntfschar *ustr; int len = 0; if ((ctx = attr_get_search_ctx(ni)) == NULL) return NULL; - if (str2unicode(aname, &ustr, &len) == -1) + if ((ustr = ntfs_str2ucs(aname, &len)) == NULL) { + perr_printf("Couldn't convert '%s' to Unicode", aname); goto error_out; + } if (ntfs_attr_lookup(AT_DATA, ustr, len, 0, 0, NULL, 0, ctx)) { perr_printf("ntfs_attr_lookup"); goto error_out; } - if (ustr != AT_UNNAMED) - free(ustr); - + ntfs_ucsfree(ustr); return ctx; error_out: ntfs_attr_put_search_ctx(ctx); diff --git a/ntfsprogs/ntfscp.c b/ntfsprogs/ntfscp.c index 6b852e39..97bd0156 100644 --- a/ntfsprogs/ntfscp.c +++ b/ntfsprogs/ntfscp.c @@ -393,16 +393,13 @@ int main(int argc, char *argv[]) } } - if (opts.attr_name) { - attr_name = NULL; - attr_name_len = ntfs_mbstoucs(opts.attr_name, &attr_name, 0); - if (attr_name_len == -1) { - ntfs_log_perror("ERROR: Failed to parse attribute " - "name"); - goto close_dst; - } - } else - attr_name = AT_UNNAMED; + attr_name = ntfs_str2ucs(opts.attr_name, &attr_name_len); + if (!attr_name) { + ntfs_log_perror("ERROR: Failed to parse attribute name '%s'", + opts.attr_name); + goto close_dst; + } + na = ntfs_attr_open(out, opts.attribute, attr_name, attr_name_len); if (!na) { if (errno != ENOENT) { @@ -423,8 +420,7 @@ int main(int argc, char *argv[]) goto close_dst; } } - if (attr_name != AT_UNNAMED) - free(attr_name); + ntfs_ucsfree(attr_name); ntfs_log_verbose("Old file size: %lld\n", na->data_size); if (na->data_size != new_size) { diff --git a/ntfsprogs/ntfsresize.c b/ntfsprogs/ntfsresize.c index 75bf4b87..62e5657f 100644 --- a/ntfsprogs/ntfsresize.c +++ b/ntfsprogs/ntfsresize.c @@ -638,39 +638,25 @@ static s64 nr_clusters_to_bitmap_byte_size(s64 nr_clusters) return bm_bsize; } -static int str2unicode(const char *aname, ntfschar **ustr, int *len) -{ - if (aname && ((*len = ntfs_mbstoucs(aname, ustr, 0)) == -1)) { - perr_printf("Couldn't convert string to Unicode"); - return -1; - } - - if (!*ustr || !*len) { - *ustr = AT_UNNAMED; - *len = 0; - } - - return 0; -} - static int is_badclus_bad(u64 mft_no, ATTR_RECORD *a) { int len, ret = 0; - ntfschar *ustr = NULL; + ntfschar *ustr; if (mft_no != FILE_BadClus) return 0; - if (str2unicode("$Bad", &ustr, &len) == -1) + if ((ustr = ntfs_str2ucs("$Bad", &len)) == NULL) { + perr_printf("Couldn't convert '$Bad' to Unicode"); return -1; + } if (ustr && ntfs_names_are_equal(ustr, len, (ntfschar *)((u8 *)a + le16_to_cpu(a->name_offset)), a->name_length, 0, NULL, 0)) ret = 1; - if (ustr != AT_UNNAMED) - free(ustr); + ntfs_ucsfree(ustr); return ret; } @@ -2013,7 +1999,7 @@ static void lookup_data_attr(ntfs_volume *vol, ntfs_attr_search_ctx **ctx) { ntfs_inode *ni; - ntfschar *ustr = NULL; + ntfschar *ustr; int len = 0; if (!(ni = ntfs_inode_open(vol, mref))) @@ -2022,14 +2008,15 @@ static void lookup_data_attr(ntfs_volume *vol, if (!(*ctx = attr_get_search_ctx(ni, NULL))) exit(1); - if (str2unicode(aname, &ustr, &len) == -1) + if ((ustr = ntfs_str2ucs(aname, &len)) == NULL) { + perr_printf("Couldn't convert '%s' to Unicode", aname); exit(1); + } if (ntfs_attr_lookup(AT_DATA, ustr, len, 0, 0, NULL, 0, *ctx)) perr_exit("ntfs_lookup_attr"); - if (ustr != AT_UNNAMED) - free(ustr); + ntfs_ucsfree(ustr); } static int check_bad_sectors(ntfs_volume *vol) diff --git a/ntfsprogs/ntfstruncate.c b/ntfsprogs/ntfstruncate.c index 531c366f..c771c04c 100644 --- a/ntfsprogs/ntfstruncate.c +++ b/ntfsprogs/ntfstruncate.c @@ -696,8 +696,7 @@ static void ntfstruncate_exit(void) if (err == -1) ntfs_log_perror("Warning: Could not umount %s", dev_name); /* Free the attribute name if it exists. */ - if (attr_name && attr_name != AT_UNNAMED) - free(attr_name); + ntfs_ucsfree(attr_name); } /** @@ -801,8 +800,7 @@ int main(int argc, char **argv) ntfs_log_perror("Warning: Failed to umount %s", dev_name); /* Free the attribute name if it exists. */ - if (attr_name && attr_name != AT_UNNAMED) - free(attr_name); + ntfs_ucsfree(attr_name); /* Finally, disable our ntfstruncate_exit() handler. */ success = TRUE;