libntfs: add ntfs_str2ucs and ntfs_freeucs function, and convert
copy-pastes to use themedge.strict_endians
parent
ce894973ed
commit
be823c7a1e
|
@ -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.
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include <errno.h>
|
||||
#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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue