From 3423a8a909c9eb431e3638b2d5870e0116345306 Mon Sep 17 00:00:00 2001 From: "cantab.net!aia21" Date: Fri, 14 May 2004 13:02:33 +0000 Subject: [PATCH] Rename uchar_t to ntfschar. (Logical change 1.392) --- ChangeLog | 3 + include/ntfs/attrib.h | 8 +- include/ntfs/dir.h | 6 +- include/ntfs/layout.h | 8 +- include/ntfs/logfile.h | 2 +- include/ntfs/types.h | 2 +- include/ntfs/unistr.h | 32 +- include/ntfs/volume.h | 2 +- libntfs/attrib.c | 32 +- libntfs/dir.c | 22 +- libntfs/gnome-vfs-method.c | 877 +++++++++++++++++++++++++++++++++++++ libntfs/unistr.c | 60 +-- libntfs/volume.c | 10 +- ntfsprogs/mkntfs.c | 66 +-- ntfsprogs/ntfscat.c | 2 +- ntfsprogs/ntfscluster.h | 2 +- ntfsprogs/ntfsinfo.c | 10 +- ntfsprogs/ntfslabel.c | 8 +- ntfsprogs/ntfsls.c | 4 +- ntfsprogs/ntfsmove.c | 2 +- ntfsprogs/ntfsresize.c | 8 +- ntfsprogs/ntfstruncate.c | 10 +- ntfsprogs/ntfsundelete.c | 2 +- ntfsprogs/ntfsundelete.h | 4 +- ntfsprogs/upcase.c | 4 +- ntfsprogs/utils.c | 4 +- 26 files changed, 1035 insertions(+), 155 deletions(-) diff --git a/ChangeLog b/ChangeLog index ab2b2cbd..286c6b31 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,9 @@ xx/xx/2004 - 1.9.3-WIP - Fix access of MFT_RECORD->bytes_in_use to use le32_to_cpu() instead of le16_to_cpu() in libntfs/volume.c. (Pete Curran) + - Rename uchar_t to ntfschar everywhere since uchar_t is already + defined on Solaris to be an unsigned 1-byte character and it is also + defined like this in POSIX. 11/05/2004 - 1.9.2 - Decomrpession bug fixes, ntfsinfo enhancements, updates. - Hopefully fix the autogen.sh problems using the --force and touch diff --git a/include/ntfs/attrib.h b/include/ntfs/attrib.h index 57fcbb69..ca209b13 100644 --- a/include/ntfs/attrib.h +++ b/include/ntfs/attrib.h @@ -31,7 +31,7 @@ typedef struct _ntfs_attr_search_ctx ntfs_attr_search_ctx; #include "runlist.h" #include "volume.h" -extern uchar_t AT_UNNAMED[]; +extern ntfschar AT_UNNAMED[]; /** * ntfs_lcn_special_values - special return values for ntfs_*_vcn_to_lcn() @@ -82,7 +82,7 @@ extern ntfs_attr_search_ctx *ntfs_attr_get_search_ctx(ntfs_inode *ni, MFT_RECORD *mrec); extern void ntfs_attr_put_search_ctx(ntfs_attr_search_ctx *ctx); -extern int ntfs_attr_lookup(const ATTR_TYPES type, const uchar_t *name, +extern int ntfs_attr_lookup(const ATTR_TYPES type, const ntfschar *name, const u32 name_len, const IGNORE_CASE_BOOL ic, const VCN lowest_vcn, const u8 *val, const u32 val_len, ntfs_attr_search_ctx *ctx); @@ -202,7 +202,7 @@ struct _ntfs_attr { runlist_element *rl; ntfs_inode *ni; ATTR_TYPES type; - uchar_t *name; + ntfschar *name; u32 name_len; unsigned long state; s64 allocated_size; @@ -247,7 +247,7 @@ extern void ntfs_attr_init(ntfs_attr *na, const BOOL non_resident, const u8 compression_unit); extern ntfs_attr *ntfs_attr_open(ntfs_inode *ni, const ATTR_TYPES type, - uchar_t *name, const u32 name_len); + ntfschar *name, const u32 name_len); extern void ntfs_attr_close(ntfs_attr *na); extern s64 ntfs_attr_pread(ntfs_attr *na, const s64 pos, s64 count, diff --git a/include/ntfs/dir.h b/include/ntfs/dir.h index e13e3753..035de300 100644 --- a/include/ntfs/dir.h +++ b/include/ntfs/dir.h @@ -25,10 +25,10 @@ #include "types.h" /* The little endian Unicode string $I30 as a global constant. */ -extern uchar_t I30[5]; +extern ntfschar I30[5]; extern u64 ntfs_inode_lookup_by_name(ntfs_inode *dir_ni, - const uchar_t *uname, const int uname_len); + const ntfschar *uname, const int uname_len); /* * File types (adapted from include ) @@ -49,7 +49,7 @@ extern u64 ntfs_inode_lookup_by_name(ntfs_inode *dir_ni, * This allows the caller to read directories into their application or * to have different dirent layouts depending on the binary type. */ -typedef int (*ntfs_filldir_t)(void *dirent, const uchar_t *name, +typedef int (*ntfs_filldir_t)(void *dirent, const ntfschar *name, const int name_len, const int name_type, const s64 pos, const MFT_REF mref, const unsigned dt_type); diff --git a/include/ntfs/layout.h b/include/ntfs/layout.h index 45be461d..26c8f81f 100644 --- a/include/ntfs/layout.h +++ b/include/ntfs/layout.h @@ -568,7 +568,7 @@ typedef enum { */ typedef struct { /*hex ofs*/ -/* 0*/ uchar_t name[0x40]; /* Unicode name of the attribute. Zero +/* 0*/ ntfschar name[0x40]; /* Unicode name of the attribute. Zero terminated. */ /* 80*/ ATTR_TYPES type; /* Type of the attribute. */ /* 84*/ u32 display_rule; /* Default display rule. @@ -969,7 +969,7 @@ typedef struct { attribute value. */ /* 24*/ u16 instance; /* If lowest_vcn = 0, the instance of the attribute being referenced; otherwise 0. */ -/* 26*/ uchar_t name[0]; /* Use when creating only. When reading use +/* 26*/ ntfschar name[0]; /* Use when creating only. When reading use name_offset to determine the location of the name. */ /* sizeof() = 26 + (attribute_name_length * 2) bytes */ @@ -1051,7 +1051,7 @@ typedef struct { /* 40*/ u8 file_name_length; /* Length of file name in (Unicode) characters. */ /* 41*/ FILE_NAME_TYPE_FLAGS file_name_type; /* Namespace of the file name.*/ -/* 42*/ uchar_t file_name[0]; /* File name in Unicode. */ +/* 42*/ ntfschar file_name[0]; /* File name in Unicode. */ } __attribute__ ((__packed__)) FILE_NAME_ATTR; /* @@ -1839,7 +1839,7 @@ typedef struct { * NOTE: Present only in FILE_Volume. */ typedef struct { - uchar_t name[0]; /* The name of the volume in Unicode. */ + ntfschar name[0]; /* The name of the volume in Unicode. */ } __attribute__ ((__packed__)) VOLUME_NAME; /* diff --git a/include/ntfs/logfile.h b/include/ntfs/logfile.h index 4dfb0cfd..d5144d64 100644 --- a/include/ntfs/logfile.h +++ b/include/ntfs/logfile.h @@ -190,7 +190,7 @@ typedef struct { but don't know if this is always the case. */ /* 22*/ u8 reserved[6]; /* Reserved/alignment. */ /* 28*/ u32 client_name_length; /* Length of client name in bytes. = 8 */ -/* 32*/ uchar_t client_name[64];/* Name of the client in Unicode. = NTFS */ +/* 32*/ ntfschar client_name[64];/* Name of the client in Unicode. = NTFS */ /* sizeof() = 160 (0xa0) bytes */ } __attribute__ ((__packed__)) LOG_CLIENT_RECORD; diff --git a/include/ntfs/types.h b/include/ntfs/types.h index 2a399f2d..8b1ac35f 100644 --- a/include/ntfs/types.h +++ b/include/ntfs/types.h @@ -42,7 +42,7 @@ typedef int16_t s16; typedef int32_t s32; typedef int64_t s64; -typedef u16 uchar_t; /* 2-byte Unicode character type. */ +typedef u16 ntfschar; /* 2-byte Unicode character type. */ #define UCHAR_T_SIZE_BITS 1 /* diff --git a/include/ntfs/unistr.h b/include/ntfs/unistr.h index 1119c5ee..5e4a1a56 100644 --- a/include/ntfs/unistr.h +++ b/include/ntfs/unistr.h @@ -28,36 +28,36 @@ extern const u8 legal_ansi_char_array[0x40]; -extern BOOL ntfs_names_are_equal(const uchar_t *s1, size_t s1_len, - const uchar_t *s2, size_t s2_len, const IGNORE_CASE_BOOL ic, - const uchar_t *upcase, const u32 upcase_size); +extern BOOL ntfs_names_are_equal(const ntfschar *s1, size_t s1_len, + const ntfschar *s2, size_t s2_len, const IGNORE_CASE_BOOL ic, + const ntfschar *upcase, const u32 upcase_size); -extern int ntfs_names_collate(const uchar_t *name1, const u32 name1_len, - const uchar_t *name2, const u32 name2_len, +extern int ntfs_names_collate(const ntfschar *name1, const u32 name1_len, + const ntfschar *name2, const u32 name2_len, const int err_val, const IGNORE_CASE_BOOL ic, - const uchar_t *upcase, const u32 upcase_len); + const ntfschar *upcase, const u32 upcase_len); -extern int ntfs_ucsncmp(const uchar_t *s1, const uchar_t *s2, size_t n); +extern int ntfs_ucsncmp(const ntfschar *s1, const ntfschar *s2, size_t n); -extern int ntfs_ucsncasecmp(const uchar_t *s1, const uchar_t *s2, size_t n, - const uchar_t *upcase, const u32 upcase_size); +extern int ntfs_ucsncasecmp(const ntfschar *s1, const ntfschar *s2, size_t n, + const ntfschar *upcase, const u32 upcase_size); -extern u32 ntfs_ucsnlen(const uchar_t *s, u32 maxlen); +extern u32 ntfs_ucsnlen(const ntfschar *s, u32 maxlen); -extern void ntfs_name_upcase(uchar_t *name, u32 name_len, - const uchar_t *upcase, const u32 upcase_len); +extern void ntfs_name_upcase(ntfschar *name, u32 name_len, + const ntfschar *upcase, const u32 upcase_len); extern void ntfs_file_value_upcase(FILE_NAME_ATTR *file_name_attr, - const uchar_t *upcase, const u32 upcase_len); + const ntfschar *upcase, const u32 upcase_len); extern int ntfs_file_values_compare(FILE_NAME_ATTR *file_name_attr1, FILE_NAME_ATTR *file_name_attr2, const int err_val, const IGNORE_CASE_BOOL ic, - const uchar_t *upcase, const u32 upcase_len); + const ntfschar *upcase, const u32 upcase_len); -extern int ntfs_ucstombs(const uchar_t *ins, const int ins_len, char **outs, +extern int ntfs_ucstombs(const ntfschar *ins, const int ins_len, char **outs, int outs_len); -extern int ntfs_mbstoucs(const char *ins, uchar_t **outs, int outs_len); +extern int ntfs_mbstoucs(const char *ins, ntfschar **outs, int outs_len); #endif /* defined _NTFS_UNISTR_H */ diff --git a/include/ntfs/volume.h b/include/ntfs/volume.h index b401362b..205d097d 100644 --- a/include/ntfs/volume.h +++ b/include/ntfs/volume.h @@ -158,7 +158,7 @@ struct _ntfs_volume { ntfs_attr *mftmirr_na; /* ntfs_attr structure for the data attribute of FILE_MFTMirr. */ - uchar_t *upcase; /* Upper case equivalents of all 65536 2-byte + ntfschar *upcase; /* Upper case equivalents of all 65536 2-byte Unicode characters. Obtained from FILE_UpCase. */ u32 upcase_len; /* Length in Unicode characters of the upcase diff --git a/libntfs/attrib.c b/libntfs/attrib.c index 9b1d8d91..81502626 100644 --- a/libntfs/attrib.c +++ b/libntfs/attrib.c @@ -43,7 +43,7 @@ #include "dir.h" #include "compress.h" -uchar_t AT_UNNAMED[] = { const_cpu_to_le16('\0') }; +ntfschar AT_UNNAMED[] = { const_cpu_to_le16('\0') }; /** * ntfs_get_attribute_value_length @@ -246,7 +246,7 @@ s64 ntfs_get_attribute_value(const ntfs_volume *vol, * Initialize the ntfs attribute @na with @ni, @type, @name, and @name_len. */ static __inline__ void __ntfs_attr_init(ntfs_attr *na, ntfs_inode *ni, - const ATTR_TYPES type, uchar_t *name, const u32 name_len) + const ATTR_TYPES type, ntfschar *name, const u32 name_len) { na->rl = NULL; na->ni = ni; @@ -323,7 +323,7 @@ void ntfs_attr_init(ntfs_attr *na, const BOOL non_resident, * both those cases @name_len is not used at all. */ ntfs_attr *ntfs_attr_open(ntfs_inode *ni, const ATTR_TYPES type, - uchar_t *name, const u32 name_len) + ntfschar *name, const u32 name_len) { ntfs_attr_search_ctx *ctx; ntfs_attr *na; @@ -1331,13 +1331,13 @@ s64 ntfs_attr_mst_pwrite(ntfs_attr *na, const s64 pos, s64 bk_cnt, * Warning: Never use @val when looking for attribute types which can be * non-resident as this most likely will result in a crash! */ -static int ntfs_attr_find(const ATTR_TYPES type, const uchar_t *name, +static int ntfs_attr_find(const ATTR_TYPES type, const ntfschar *name, const u32 name_len, const IGNORE_CASE_BOOL ic, const u8 *val, const u32 val_len, ntfs_attr_search_ctx *ctx) { ATTR_RECORD *a; ntfs_volume *vol; - uchar_t *upcase; + ntfschar *upcase; u32 upcase_len; if (!ctx || !ctx->mrec || !ctx->attr) { @@ -1394,12 +1394,12 @@ static int ntfs_attr_find(const ATTR_TYPES type, const uchar_t *name, return -1; } } else if (name && !ntfs_names_are_equal(name, name_len, - (uchar_t*)((char*)a + le16_to_cpu(a->name_offset)), + (ntfschar*)((char*)a + le16_to_cpu(a->name_offset)), a->name_length, ic, upcase, upcase_len)) { register int rc; rc = ntfs_names_collate(name, name_len, - (uchar_t*)((char*)a + + (ntfschar*)((char*)a + le16_to_cpu(a->name_offset)), a->name_length, 1, IGNORE_CASE, upcase, upcase_len); @@ -1415,7 +1415,7 @@ static int ntfs_attr_find(const ATTR_TYPES type, const uchar_t *name, if (rc) continue; rc = ntfs_names_collate(name, name_len, - (uchar_t*)((char*)a + + (ntfschar*)((char*)a + le16_to_cpu(a->name_offset)), a->name_length, 1, CASE_SENSITIVE, upcase, upcase_len); @@ -1536,7 +1536,7 @@ static int ntfs_attr_find(const ATTR_TYPES type, const uchar_t *name, * EIO I/O error or corrupt data structures found. * ENOMEM Not enough memory to allocate necessary buffers. */ -static int ntfs_external_attr_find(ATTR_TYPES type, const uchar_t *name, +static int ntfs_external_attr_find(ATTR_TYPES type, const ntfschar *name, const u32 name_len, const IGNORE_CASE_BOOL ic, const VCN lowest_vcn, const u8 *val, const u32 val_len, ntfs_attr_search_ctx *ctx) @@ -1546,7 +1546,7 @@ static int ntfs_external_attr_find(ATTR_TYPES type, const uchar_t *name, ATTR_LIST_ENTRY *al_entry, *next_al_entry; char *al_start, *al_end; ATTR_RECORD *a; - uchar_t *al_name; + ntfschar *al_name; u32 al_name_len; BOOL is_first_search = FALSE; @@ -1665,7 +1665,7 @@ find_attr_list_attr: continue; } al_name_len = al_entry->name_length; - al_name = (uchar_t*)((char*)al_entry + al_entry->name_offset); + al_name = (ntfschar*)((char*)al_entry + al_entry->name_offset); /* * If !@type we want the attribute represented by this * attribute list entry. @@ -1727,7 +1727,7 @@ find_attr_list_attr: lowest_vcn && next_al_entry->type == al_entry->type && next_al_entry->name_length == al_name_len && - ntfs_names_are_equal((uchar_t*)((char*) + ntfs_names_are_equal((ntfschar*)((char*) next_al_entry + next_al_entry->name_offset), next_al_entry->name_length, @@ -1800,7 +1800,7 @@ do_next_attr_loop: */ if (al_entry->type != a->type) break; - if (!ntfs_names_are_equal((uchar_t*)((char*)a + + if (!ntfs_names_are_equal((ntfschar*)((char*)a + le16_to_cpu(a->name_offset)), a->name_length, al_name, al_name_len, CASE_SENSITIVE, @@ -1948,7 +1948,7 @@ not_found: * EIO I/O error or corrupt data structures found. * ENOMEM Not enough memory to allocate necessary buffers. */ -int ntfs_attr_lookup(const ATTR_TYPES type, const uchar_t *name, +int ntfs_attr_lookup(const ATTR_TYPES type, const ntfschar *name, const u32 name_len, const IGNORE_CASE_BOOL ic, const VCN lowest_vcn, const u8 *val, const u32 val_len, ntfs_attr_search_ctx *ctx) @@ -2474,7 +2474,7 @@ static int ntfs_attr_make_non_resident(ntfs_attr *na, /* Move the attribute name if it exists and update the offset. */ if (a->name_length) memmove((u8*)a + name_ofs, (u8*)a + le16_to_cpu(a->name_offset), - a->name_length * sizeof(uchar_t)); + a->name_length * sizeof(ntfschar)); a->name_offset = cpu_to_le16(name_ofs); /* Update the flags to match the in-memory ones. */ @@ -2748,7 +2748,7 @@ static int ntfs_attr_make_resident(ntfs_attr *na, ntfs_attr_search_ctx *ctx) } memmove((u8*)a + name_ofs, (u8*)a + le16_to_cpu(a->name_offset), - a->name_length * sizeof(uchar_t)); + a->name_length * sizeof(ntfschar)); } a->name_offset = cpu_to_le16(name_ofs); diff --git a/libntfs/dir.c b/libntfs/dir.c index 31796a8d..a1c09b87 100644 --- a/libntfs/dir.c +++ b/libntfs/dir.c @@ -35,7 +35,7 @@ /* * The little endian Unicode string "$I30" as a global constant. */ -uchar_t I30[5] = { const_cpu_to_le16('$'), const_cpu_to_le16('I'), +ntfschar I30[5] = { const_cpu_to_le16('$'), const_cpu_to_le16('I'), const_cpu_to_le16('3'), const_cpu_to_le16('0'), const_cpu_to_le16('\0') }; @@ -64,7 +64,7 @@ uchar_t I30[5] = { const_cpu_to_le16('$'), const_cpu_to_le16('I'), * If the volume is mounted with the case sensitive flag set, then we only * allow exact matches. */ -u64 ntfs_inode_lookup_by_name(ntfs_inode *dir_ni, const uchar_t *uname, +u64 ntfs_inode_lookup_by_name(ntfs_inode *dir_ni, const ntfschar *uname, const int uname_len) { VCN vcn; @@ -137,7 +137,7 @@ u64 ntfs_inode_lookup_by_name(ntfs_inode *dir_ni, const uchar_t *uname, * returning. */ if (ntfs_names_are_equal(uname, uname_len, - (uchar_t*)&ie->key.file_name.file_name, + (ntfschar*)&ie->key.file_name.file_name, ie->key.file_name.file_name_length, CASE_SENSITIVE, vol->upcase, vol->upcase_len)) { found_it: @@ -158,7 +158,7 @@ found_it: if (!NVolCaseSensitive(vol) && ie->key.file_name.file_name_type && ntfs_names_are_equal(uname, uname_len, - (uchar_t*)&ie->key.file_name.file_name, + (ntfschar*)&ie->key.file_name.file_name, ie->key.file_name.file_name_length, IGNORE_CASE, vol->upcase, vol->upcase_len)) { /* Only one case insensitive matching name allowed. */ @@ -178,7 +178,7 @@ found_it: * know which way in the B+tree we have to go. */ rc = ntfs_names_collate(uname, uname_len, - (uchar_t*)&ie->key.file_name.file_name, + (ntfschar*)&ie->key.file_name.file_name, ie->key.file_name.file_name_length, 1, IGNORE_CASE, vol->upcase, vol->upcase_len); /* @@ -197,7 +197,7 @@ found_it: * collation. */ rc = ntfs_names_collate(uname, uname_len, - (uchar_t*)&ie->key.file_name.file_name, + (ntfschar*)&ie->key.file_name.file_name, ie->key.file_name.file_name_length, 1, CASE_SENSITIVE, vol->upcase, vol->upcase_len); if (rc == -1) @@ -329,7 +329,7 @@ descend_into_child_node: * returning. */ if (ntfs_names_are_equal(uname, uname_len, - (uchar_t*)&ie->key.file_name.file_name, + (ntfschar*)&ie->key.file_name.file_name, ie->key.file_name.file_name_length, CASE_SENSITIVE, vol->upcase, vol->upcase_len)) { found_it2: @@ -352,7 +352,7 @@ found_it2: if (!NVolCaseSensitive(vol) && ie->key.file_name.file_name_type && ntfs_names_are_equal(uname, uname_len, - (uchar_t*)&ie->key.file_name.file_name, + (ntfschar*)&ie->key.file_name.file_name, ie->key.file_name.file_name_length, IGNORE_CASE, vol->upcase, vol->upcase_len)) { /* Only one case insensitive matching name allowed. */ @@ -372,7 +372,7 @@ found_it2: * know which way in the B+tree we have to go. */ rc = ntfs_names_collate(uname, uname_len, - (uchar_t*)&ie->key.file_name.file_name, + (ntfschar*)&ie->key.file_name.file_name, ie->key.file_name.file_name_length, 1, IGNORE_CASE, vol->upcase, vol->upcase_len); /* @@ -391,7 +391,7 @@ found_it2: * collation. */ rc = ntfs_names_collate(uname, uname_len, - (uchar_t*)&ie->key.file_name.file_name, + (ntfschar*)&ie->key.file_name.file_name, ie->key.file_name.file_name_length, 1, CASE_SENSITIVE, vol->upcase, vol->upcase_len); if (rc == -1) @@ -456,7 +456,7 @@ close_err_out: /* * The little endian Unicode string ".." for ntfs_readdir(). */ -static const uchar_t dotdot[3] = { const_cpu_to_le16('.'), +static const ntfschar dotdot[3] = { const_cpu_to_le16('.'), const_cpu_to_le16('.'), const_cpu_to_le16('\0') }; diff --git a/libntfs/gnome-vfs-method.c b/libntfs/gnome-vfs-method.c index e69de29b..07844fc7 100644 --- a/libntfs/gnome-vfs-method.c +++ b/libntfs/gnome-vfs-method.c @@ -0,0 +1,877 @@ +/* + * gnome-vfs-method.c - Gnome-VFS init/shutdown implementation of interface to + * libntfs. Part of the Linux-NTFS project. + * + * Copyright (c) 2003 Jan Kratochvil + * Copyright (c) 2003 Anton Altaparmakov + * + * This program/include file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program/include file is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (in the main directory of the Linux-NTFS + * distribution in the file COPYING); if not, write to the Free Software + * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" + +#undef FALSE +#undef TRUE +#include "types.h" /* for 'FALSE'/'TRUE' libntfs definition */ +#define FALSE FALSE +#define TRUE TRUE + +#include "gnome-vfs-method.h" /* self */ +#include +#include +#include "gnome-vfs-module.h" +#include +#include +#include + +#include "volume.h" +#include "dir.h" + +static GnomeVFSMethod GnomeVFSMethod_static; +G_LOCK_DEFINE_STATIC(GnomeVFSMethod_static); + +/* map: (gchar *)method_name -> (struct method_name_info *) */ +static GHashTable *method_name_hash; +G_LOCK_DEFINE_STATIC(method_name_hash); + +struct method_name_info { + gchar *args; +}; + +static void method_name_hash_key_destroy_func(gchar *key) +{ + g_return_if_fail(key != NULL); + + g_free(key); +} + +static void method_name_hash_value_destroy_func(struct method_name_info *value) +{ + g_return_if_fail(value != NULL); + + g_free(value->args); + g_free(value); +} + +static void method_name_hash_init(void) +{ + G_LOCK(method_name_hash); + if (!method_name_hash) { + method_name_hash = g_hash_table_new_full( + g_str_hash, /* hash_func */ + g_str_equal, /* key_equal_func */ + (GDestroyNotify) method_name_hash_key_destroy_func, /* key_destroy_func */ + (GDestroyNotify) method_name_hash_value_destroy_func); /* value_destroy_func */ + } + G_UNLOCK(method_name_hash); +} + +/* + * map: (gchar *)uri_parent_string "method_name:uri_parent" -> (ntfs_volume *) + */ +static GHashTable *uri_parent_string_hash; +G_LOCK_DEFINE_STATIC(uri_parent_string_hash); + +static void uri_parent_string_hash_key_destroy_func(gchar *key) +{ + g_return_if_fail(key != NULL); + + g_free(key); +} + +static void uri_parent_string_hash_value_destroy_func(ntfs_volume *value) +{ + g_return_if_fail(value != NULL); + + ntfs_umount( /* errors ignored */ + value, /* vol */ + TRUE); /* force; possibly loose modifications */ +} + +static void uri_parent_string_hash_init(void) +{ + G_LOCK(uri_parent_string_hash); + if (!uri_parent_string_hash) { + uri_parent_string_hash = g_hash_table_new_full( + g_str_hash, /* hash_func */ + g_str_equal, /* key_equal_func */ + (GDestroyNotify) uri_parent_string_hash_key_destroy_func, /* key_destroy_func */ + (GDestroyNotify) uri_parent_string_hash_value_destroy_func); /* value_destroy_func */ + } + G_UNLOCK(uri_parent_string_hash); +} + +static GnomeVFSResult libntfs_gnomevfs_uri_parent_init( + ntfs_volume **volume_return, GnomeVFSURI *uri) +{ + gchar *uri_parent_string; + gchar *uri_parent_string_parent; + ntfs_volume *volume; + + g_return_val_if_fail(uri != NULL, GNOME_VFS_ERROR_INVALID_URI); + g_return_val_if_fail(volume_return != NULL, + GNOME_VFS_ERROR_BAD_PARAMETERS); + + uri_parent_string_hash_init(); + + if (!uri->parent) + return GNOME_VFS_ERROR_INVALID_URI; + if (!uri->text) /* not needed here but we don't permit non-specific fs-image reference */ + return GNOME_VFS_ERROR_INVALID_URI; + uri_parent_string_parent = gnome_vfs_uri_to_string(uri->parent, + GNOME_VFS_URI_HIDE_NONE); + g_assert(uri_parent_string_parent != NULL); + + uri_parent_string = g_strdup_printf("%s:%s", uri->method_string, + uri_parent_string_parent); + g_assert(uri_parent_string != NULL); + + G_LOCK(uri_parent_string_hash); + volume = g_hash_table_lookup(uri_parent_string_hash, uri_parent_string); + G_UNLOCK(uri_parent_string_hash); + if (!volume) { + struct method_name_info *method_name_info; + + G_LOCK(method_name_hash); + method_name_info = g_hash_table_lookup(method_name_hash, + uri->method_string); + G_UNLOCK(method_name_hash); + if (!method_name_info) { + /* should not happend */ + g_return_val_if_reached(GNOME_VFS_ERROR_INVALID_URI); + } + + /* TODO: Generic GnomeVFS filter. */ + if (strcmp(uri->parent->method_string, "file")) { + g_free(uri_parent_string); + return GNOME_VFS_ERROR_INVALID_URI; + } + + if (!(volume = ntfs_mount(uri->parent->text, MS_RDONLY))) { + g_free(uri_parent_string); + return GNOME_VFS_ERROR_WRONG_FORMAT; + } + + G_LOCK(uri_parent_string_hash); + g_hash_table_insert(uri_parent_string_hash, + g_strdup(uri_parent_string), volume); + G_UNLOCK(uri_parent_string_hash); + } + g_free(uri_parent_string); + + *volume_return = volume; + return GNOME_VFS_OK; +} + +static GnomeVFSResult inode_open_by_pathname(ntfs_inode **inode_return, + ntfs_volume *volume, const gchar *pathname) +{ + MFT_REF mref; + ntfs_inode *inode; + gchar *pathname_parse, *pathname_next; + int errint; + + g_return_val_if_fail(inode_return != NULL, + GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(volume != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(pathname != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + pathname = g_path_skip_root(pathname); + pathname_parse = g_alloca(strlen(pathname) + 1); + strcpy(pathname_parse, pathname); + mref = FILE_root; + for (;;) { + ntfschar *pathname_parse_ucs2; + gchar *pathname_parse_unescaped; + int i; + + G_LOCK(libntfs); + inode = ntfs_inode_open(volume, mref); + G_UNLOCK(libntfs); + if (!inode) + return GNOME_VFS_ERROR_NOT_FOUND; + if (!*pathname_parse) { + *inode_return = inode; + return GNOME_VFS_OK; + } + for (pathname_next = pathname_parse; *pathname_next && + *pathname_next != G_DIR_SEPARATOR; pathname_next++) ; + if (*pathname_next) { + /* terminate current path element */ + *pathname_next++ = '\0'; + } + while (*pathname_next == G_DIR_SEPARATOR) + pathname_next++; + /* FIXME: Is 'pathname' utf8? */ + pathname_parse_unescaped = gnome_vfs_unescape_string( + pathname_parse, NULL); /* illegal_characters */ + libntfs_newn(pathname_parse_ucs2, + strlen(pathname_parse_unescaped) + 1); + for (i = 0; pathname_parse_unescaped[i]; i++) + pathname_parse_ucs2[i] = pathname_parse_unescaped[i]; + pathname_parse_ucs2[i] = 0; + g_free(pathname_parse_unescaped); + G_LOCK(libntfs); + mref = ntfs_inode_lookup_by_name(inode, pathname_parse_ucs2, i); + G_UNLOCK(libntfs); + g_free(pathname_parse_ucs2); + if ((MFT_REF)-1 == mref) + return GNOME_VFS_ERROR_NOT_FOUND; + G_LOCK(libntfs); + errint = ntfs_inode_close(inode); + G_UNLOCK(libntfs); + if (errint) + g_return_val_if_reached(GNOME_VFS_ERROR_INTERNAL); + pathname_parse = pathname_next; + } + /* NOTREACHED */ +} + +struct libntfs_directory { + ntfs_inode *inode; + GList *file_info_list; /* of (GnomeVFSFileInfo *); last item has ->data == NULL */ +}; + +static GnomeVFSResult libntfs_gnomevfs_open_directory(GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, GnomeVFSURI *uri, + GnomeVFSFileInfoOptions options, GnomeVFSContext *context) +{ + GnomeVFSResult errvfsresult; + ntfs_volume *volume; + ntfs_inode *inode; + struct libntfs_directory *libntfs_directory; + + g_return_val_if_fail(method == &GnomeVFSMethod_static, + GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(method_handle != NULL, + GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (GNOME_VFS_OK != (errvfsresult = + libntfs_gnomevfs_uri_parent_init(&volume, uri))) + return errvfsresult; + + if (GNOME_VFS_OK != (errvfsresult = inode_open_by_pathname(&inode, + volume, uri->text))) + return errvfsresult; + + libntfs_new(libntfs_directory); + libntfs_directory->inode = inode; + libntfs_directory->file_info_list = NULL; + + *method_handle = (GnomeVFSMethodHandle *)libntfs_directory; + return errvfsresult; +} + +static GnomeVFSResult libntfs_gnomevfs_close_directory(GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, GnomeVFSContext *context) +{ + struct libntfs_directory *libntfs_directory; + int errint; + + g_return_val_if_fail(method == &GnomeVFSMethod_static, + GNOME_VFS_ERROR_BAD_PARAMETERS); + libntfs_directory = (struct libntfs_directory *)method_handle; + g_return_val_if_fail(libntfs_directory != NULL, + GNOME_VFS_ERROR_BAD_PARAMETERS); + + G_LOCK(libntfs); + errint = ntfs_inode_close(libntfs_directory->inode); + G_UNLOCK(libntfs); + if (errint) + g_return_val_if_reached(GNOME_VFS_ERROR_INTERNAL); + + if (libntfs_directory->file_info_list) { + GList *last_l; + + /* + * Prevent gnome_vfs_file_info_list_free() and its + * gnome_vfs_file_info_unref() on the last 'file_info_list' + * items as it is EOF with NULL '->data'. + */ + last_l = g_list_last(libntfs_directory->file_info_list); + g_assert(last_l->data == NULL); + libntfs_directory->file_info_list = g_list_delete_link( + libntfs_directory->file_info_list, last_l); + gnome_vfs_file_info_list_free( + libntfs_directory->file_info_list); + } + + g_free(libntfs_directory); + + return GNOME_VFS_OK; +} + +static gchar *libntfs_ntfscharo_utf8(const ntfschar *name, const int name_len) +{ + GString *gstring; + int i; + + gstring = g_string_sized_new(name_len); + for (i = 0; i < name_len; i++) + gstring = g_string_append_unichar(gstring, name[i]); + return g_string_free(gstring, /* returns utf8-formatted string */ + FALSE); /* free_segment */ +} + +/* + * Do not lock 'libntfs' here as we are already locked inside ntfs_readdir(). + */ +static int libntfs_gnomevfs_read_directory_filldir( + struct libntfs_directory *libntfs_directory /* dirent */, + const ntfschar *name, const int name_len, const int name_type, + const s64 pos, const MFT_REF mref, const unsigned dt_type) +{ + GnomeVFSFileInfo *file_info; + + g_return_val_if_fail(libntfs_directory != NULL, -1); + g_return_val_if_fail(name != NULL, -1); + g_return_val_if_fail(name_len >= 0, -1); + g_return_val_if_fail(pos >= 0, -1); + + /* system directory; FIXME: What is its proper identification? */ + if (name_len > 0 && name[0] == '$') + return 0; /* continue traversal */ + + file_info = gnome_vfs_file_info_new(); + file_info->name = libntfs_ntfscharo_utf8(name, name_len); + file_info->valid_fields = 0; + + switch (dt_type) { + case NTFS_DT_FIFO: + file_info->type = GNOME_VFS_FILE_TYPE_FIFO; + break; + case NTFS_DT_CHR: + file_info->type = GNOME_VFS_FILE_TYPE_CHARACTER_DEVICE; + break; + case NTFS_DT_DIR: + file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + break; + case NTFS_DT_BLK: + file_info->type = GNOME_VFS_FILE_TYPE_BLOCK_DEVICE; + break; + case NTFS_DT_REG: + file_info->type = GNOME_VFS_FILE_TYPE_REGULAR; + break; + case NTFS_DT_LNK: + file_info->type = GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK; + break; + case NTFS_DT_SOCK: + file_info->type = GNOME_VFS_FILE_TYPE_SOCKET; + break; + /* FIXME: What is 'NTFS_DT_WHT'? */ + default: + file_info->type = GNOME_VFS_FILE_TYPE_UNKNOWN; + } + if (file_info->type != GNOME_VFS_FILE_TYPE_UNKNOWN) + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE; + + /* Detect 'file_info->size': */ + if (file_info->type == GNOME_VFS_FILE_TYPE_REGULAR) { + ntfs_inode *inode; + + inode = ntfs_inode_open(libntfs_directory->inode->vol, mref); + /* FIXME: Check failed 'inode' open. */ + if (inode) { + ntfs_attr *attr; + int errint; + + attr = ntfs_attr_open(inode, /* ni */ + AT_DATA, /* type */ + NULL, /* name */ + 0); /* name_len */ + /* FIXME: Check failed 'attr' open. */ + if (attr) { + /* FIXME: Is 'data_size' the right field? */ + file_info->size = attr->data_size; + file_info->valid_fields |= + GNOME_VFS_FILE_INFO_FIELDS_SIZE; + ntfs_attr_close(attr); + } + errint = ntfs_inode_close(inode); + /* FIXME: Check 'errint'. */ + } + } + + libntfs_directory->file_info_list = g_list_prepend( + libntfs_directory->file_info_list, file_info); + + return 0; /* continue traversal */ +} + +static GnomeVFSResult libntfs_gnomevfs_read_directory(GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, GnomeVFSContext *context) +{ + GnomeVFSResult errvfsresult; + struct libntfs_directory *libntfs_directory; + + g_return_val_if_fail(method == &GnomeVFSMethod_static, + GNOME_VFS_ERROR_BAD_PARAMETERS); + libntfs_directory = (struct libntfs_directory *)method_handle; + g_return_val_if_fail(libntfs_directory != NULL, + GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(file_info != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (!libntfs_directory->file_info_list) { + int errint; + s64 pos; + + pos = 0; /* read from the start; incl. "." and ".." entries */ + G_LOCK(libntfs); + errint = ntfs_readdir(libntfs_directory->inode, /* dir_ni */ + &pos, /* pos */ + libntfs_directory, /* dirent */ + (ntfs_filldir_t)libntfs_gnomevfs_read_directory_filldir); /* filldir */ + G_UNLOCK(libntfs); + if (errint) + return GNOME_VFS_ERROR_INTERNAL; + + libntfs_directory->file_info_list = g_list_prepend( + libntfs_directory->file_info_list, NULL); /* EOF */ + libntfs_directory->file_info_list = g_list_reverse( + libntfs_directory->file_info_list); + } + + if (!libntfs_directory->file_info_list->data) { + g_assert(libntfs_directory->file_info_list->next == NULL); + /* + * Do not clear the list to leave us stuck at EOF - GnomeVFS + * behaves that way. + */ + errvfsresult = GNOME_VFS_ERROR_EOF; + } else { + /* Cut first list item. */ + gnome_vfs_file_info_copy(file_info, /* dest */ + libntfs_directory->file_info_list->data); /* src */ + gnome_vfs_file_info_unref( + libntfs_directory->file_info_list->data); + libntfs_directory->file_info_list = g_list_delete_link( + libntfs_directory->file_info_list, + libntfs_directory->file_info_list); + errvfsresult = GNOME_VFS_OK; + } + return errvfsresult; +} + +struct libntfs_file { + ntfs_inode *inode; + ntfs_attr *attr; + s64 pos; +}; + +static GnomeVFSResult libntfs_open_attr(struct libntfs_file *libntfs_file) +{ + g_return_val_if_fail(libntfs_file != NULL, + GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(libntfs_file->inode != NULL, + GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (!libntfs_file->attr) { + G_LOCK(libntfs); + libntfs_file->attr = ntfs_attr_open( + libntfs_file->inode, /* ni */ + AT_DATA, /* type */ + NULL, /* name */ + 0); /* name_len */ + G_UNLOCK(libntfs); + if (!libntfs_file->attr) + return GNOME_VFS_ERROR_BAD_FILE; + libntfs_file->pos = 0; + } + + return GNOME_VFS_OK; +} + +static GnomeVFSResult libntfs_gnomevfs_open(GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle_return, GnomeVFSURI *uri, + GnomeVFSOpenMode mode, GnomeVFSContext *context) +{ + GnomeVFSResult errvfsresult; + ntfs_volume *volume; + ntfs_inode *inode; + struct libntfs_file *libntfs_file; + + g_return_val_if_fail(method == &GnomeVFSMethod_static, + GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(method_handle_return != NULL, + GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (GNOME_VFS_OK != (errvfsresult = + libntfs_gnomevfs_uri_parent_init(&volume, uri))) + return errvfsresult; + + if (mode & GNOME_VFS_OPEN_WRITE) + return GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM; + + if (GNOME_VFS_OK != (errvfsresult = + inode_open_by_pathname(&inode, volume, uri->text))) + return errvfsresult; + + libntfs_new(libntfs_file); + libntfs_file->inode = inode; + libntfs_file->attr = NULL; + + *method_handle_return = (GnomeVFSMethodHandle *)libntfs_file; + return errvfsresult; +} + +static GnomeVFSResult libntfs_gnomevfs_create(GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle_return, GnomeVFSURI *uri, + GnomeVFSOpenMode mode, gboolean exclusive, guint perm, + GnomeVFSContext *context) +{ + GnomeVFSResult errvfsresult; + ntfs_volume *volume; + + g_return_val_if_fail(method == &GnomeVFSMethod_static, + GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(method_handle_return != NULL, + GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (GNOME_VFS_OK != (errvfsresult = + libntfs_gnomevfs_uri_parent_init(&volume, uri))) + return errvfsresult; + + return GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM; +} + +static GnomeVFSResult libntfs_gnomevfs_close(GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, GnomeVFSContext *context) +{ + struct libntfs_file *libntfs_file; + int errint; + + g_return_val_if_fail(method == &GnomeVFSMethod_static, + GNOME_VFS_ERROR_BAD_PARAMETERS); + libntfs_file = (struct libntfs_file *) method_handle; + g_return_val_if_fail(libntfs_file != NULL, + GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (libntfs_file->attr) { + G_LOCK(libntfs); + ntfs_attr_close(libntfs_file->attr); + G_UNLOCK(libntfs); + } + G_LOCK(libntfs); + errint = ntfs_inode_close(libntfs_file->inode); + G_UNLOCK(libntfs); + if (errint) + g_return_val_if_reached(GNOME_VFS_ERROR_INTERNAL); + + g_free(libntfs_file); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult libntfs_gnomevfs_read(GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, gpointer buffer, + GnomeVFSFileSize num_bytes, GnomeVFSFileSize *bytes_read_return, + GnomeVFSContext *context) +{ + GnomeVFSResult errvfsresult; + struct libntfs_file *libntfs_file; + s64 count_s64, got; + + g_return_val_if_fail(method == &GnomeVFSMethod_static, + GNOME_VFS_ERROR_BAD_PARAMETERS); + libntfs_file = (struct libntfs_file *)method_handle; + g_return_val_if_fail(libntfs_file != NULL, + GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(buffer != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(bytes_read_return != NULL, + GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (GNOME_VFS_OK != (errvfsresult = libntfs_open_attr(libntfs_file))) + return errvfsresult; + + count_s64 = num_bytes; + g_assert((GnomeVFSFileSize)count_s64 == num_bytes); + G_LOCK(libntfs); + got = ntfs_attr_pread(libntfs_file->attr, libntfs_file->pos, count_s64, + buffer); + G_UNLOCK(libntfs); + if (got == -1) + return GNOME_VFS_ERROR_IO; + + libntfs_file->pos += got; + *bytes_read_return = got; + g_assert((s64)*bytes_read_return == got); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult libntfs_gnomevfs_seek(GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSSeekPosition whence, GnomeVFSFileOffset offset, + GnomeVFSContext *context) +{ + GnomeVFSResult errvfsresult; + struct libntfs_file *libntfs_file; + + g_return_val_if_fail(method == &GnomeVFSMethod_static, + GNOME_VFS_ERROR_BAD_PARAMETERS); + libntfs_file = (struct libntfs_file *)method_handle; + g_return_val_if_fail(libntfs_file != NULL, + GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (GNOME_VFS_OK != (errvfsresult = libntfs_open_attr(libntfs_file))) + return errvfsresult; + + switch (whence) { + case GNOME_VFS_SEEK_START: + libntfs_file->pos = offset; + break; + case GNOME_VFS_SEEK_CURRENT: + libntfs_file->pos += offset; + break; + case GNOME_VFS_SEEK_END: + /* FIXME: NOT IMPLEMENTED YET */ + g_return_val_if_reached(GNOME_VFS_ERROR_BAD_PARAMETERS); + default: + g_assert_not_reached(); + } + + return GNOME_VFS_OK; +} + +static GnomeVFSResult libntfs_gnomevfs_tell(GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileOffset *offset_return) +{ + GnomeVFSResult errvfsresult; + struct libntfs_file *libntfs_file; + + g_return_val_if_fail(method == &GnomeVFSMethod_static, + GNOME_VFS_ERROR_BAD_PARAMETERS); + libntfs_file = (struct libntfs_file *)method_handle; + g_return_val_if_fail(libntfs_file != NULL, + GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(offset_return != NULL, + GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (GNOME_VFS_OK != (errvfsresult = libntfs_open_attr(libntfs_file))) + return errvfsresult; + + *offset_return = libntfs_file->pos; + g_assert(*offset_return == libntfs_file->pos); + + return errvfsresult; +} + +static gboolean libntfs_gnomevfs_is_local(GnomeVFSMethod *method, + const GnomeVFSURI *uri) +{ + g_return_val_if_fail(method == &GnomeVFSMethod_static, + GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(uri != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + + return gnome_vfs_uri_is_local(uri->parent); +} + +GnomeVFSResult libntfs_gnomevfs_get_file_info_from_handle( + GnomeVFSMethod *method, GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GnomeVFSResult errvfsresult; + struct libntfs_file *libntfs_file; + + g_return_val_if_fail(method == &GnomeVFSMethod_static, + GNOME_VFS_ERROR_BAD_PARAMETERS); + libntfs_file = (struct libntfs_file *)method_handle; + g_return_val_if_fail(libntfs_file != NULL, + GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(file_info != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + /* handle 'options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE'? */ + + file_info->valid_fields = 0; + /* FIXME: It is complicated to read filename of open 'ntfs_inode'. */ + file_info->name = NULL; + + if (GNOME_VFS_OK != (errvfsresult = libntfs_open_attr(libntfs_file))) { + /* Assume we are directory: */ + file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; + /* + * Do not: file_info->valid_fields |= + * GNOME_VFS_FILE_INFO_FIELDS_TYPE; + * as gnome-vfs-xfer.c/copy_items() does not check + * 'GNOME_VFS_FILE_INFO_FIELDS_TYPE' and we are just bluffing + * we know it. + */ + return GNOME_VFS_OK; + } + + /* FIXME: Is 'data_size' the right field? */ + file_info->size = libntfs_file->attr->data_size; + file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_SIZE; + + /* + * FIXME: We do not really know the type of 'libntfs_file' but + * gnome-vfs-xfer.c/copy_items() requires 'GNOME_VFS_FILE_TYPE_REGULAR' + * to copy it. + */ + file_info->type = GNOME_VFS_FILE_TYPE_REGULAR; + /* + * Do not: file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_TYPE; + * as gnome-vfs-xfer.c/copy_items() does not check + * 'GNOME_VFS_FILE_INFO_FIELDS_TYPE' and we are just bluffing we know + * it. + */ + + return errvfsresult; +} + +static GnomeVFSResult libntfs_gnomevfs_get_file_info(GnomeVFSMethod *method, + GnomeVFSURI *uri, GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, GnomeVFSContext *context) +{ + GnomeVFSResult errvfsresult; + GnomeVFSMethodHandle *method_handle; + + g_return_val_if_fail(method == &GnomeVFSMethod_static, + GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(file_info != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); + /* handle 'options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE'? */ + + if (GNOME_VFS_OK != (errvfsresult = + libntfs_gnomevfs_open(method, &method_handle, uri, + GNOME_VFS_OPEN_READ, context))) + return errvfsresult; + if (GNOME_VFS_OK != (errvfsresult = + libntfs_gnomevfs_get_file_info_from_handle(method, + method_handle, file_info, options, context))) + return errvfsresult; + if (GNOME_VFS_OK != (errvfsresult = + libntfs_gnomevfs_close(method, method_handle, context))) + return errvfsresult; + + return GNOME_VFS_OK; +} + +GnomeVFSResult libntfs_gnomevfs_check_same_fs(GnomeVFSMethod *method, + GnomeVFSURI *a, GnomeVFSURI *b, gboolean *same_fs_return, + GnomeVFSContext *context) +{ + ntfs_volume *volume_a; + ntfs_volume *volume_b; + GnomeVFSResult errvfsresult; + + g_return_val_if_fail(method == &GnomeVFSMethod_static, + GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(same_fs_return != NULL, + GNOME_VFS_ERROR_BAD_PARAMETERS); + + errvfsresult = libntfs_gnomevfs_uri_parent_init(&volume_a, a); + g_return_val_if_fail(errvfsresult == GNOME_VFS_OK, errvfsresult); + + errvfsresult = libntfs_gnomevfs_uri_parent_init(&volume_b, b); + g_return_val_if_fail(errvfsresult == GNOME_VFS_OK, errvfsresult); + + *same_fs_return = (volume_a == volume_b); + + return GNOME_VFS_OK; +} + +/** + * libntfs_gnomevfs_init: + * + * Returns: Initialized structure of #GnomeVFSMethod with static methods of + * libntfs-gnomevfs. + */ +GnomeVFSMethod *libntfs_gnomevfs_method_init(const gchar *method_name, + const gchar *args) +{ + struct method_name_info *method_name_info; + + g_return_val_if_fail(method_name != NULL, NULL); + /* 'args' may be NULL if not supplied. */ + + method_name_hash_init(); + + G_LOCK(method_name_hash); + method_name_info = g_hash_table_lookup(method_name_hash, method_name); + if (method_name_info && strcmp(method_name_info->args, args)) + method_name_info = NULL; + G_UNLOCK(method_name_hash); + if (!method_name_info) { + libntfs_new(method_name_info); + method_name_info->args = g_strdup(args); + G_LOCK(method_name_hash); + g_hash_table_replace(method_name_hash, g_strdup(method_name), + method_name_info); + G_UNLOCK(method_name_hash); + } + + G_LOCK(GnomeVFSMethod_static); + LIBNTFS_MEMZERO(&GnomeVFSMethod_static); + GnomeVFSMethod_static.method_table_size = sizeof(GnomeVFSMethod_static); + GnomeVFSMethod_static.open = libntfs_gnomevfs_open; /* mandatory */ + GnomeVFSMethod_static.create = libntfs_gnomevfs_create; /* mandatory */ + GnomeVFSMethod_static.close = libntfs_gnomevfs_close; + GnomeVFSMethod_static.read = libntfs_gnomevfs_read; + GnomeVFSMethod_static.seek = libntfs_gnomevfs_seek; + GnomeVFSMethod_static.tell = libntfs_gnomevfs_tell; + GnomeVFSMethod_static.open_directory = libntfs_gnomevfs_open_directory; + GnomeVFSMethod_static.close_directory = + libntfs_gnomevfs_close_directory; + GnomeVFSMethod_static.read_directory = libntfs_gnomevfs_read_directory; + GnomeVFSMethod_static.get_file_info = + libntfs_gnomevfs_get_file_info; /* mandatory */ + GnomeVFSMethod_static.get_file_info_from_handle = + libntfs_gnomevfs_get_file_info_from_handle; + GnomeVFSMethod_static.is_local = + libntfs_gnomevfs_is_local; /* mandatory */ + GnomeVFSMethod_static.check_same_fs = libntfs_gnomevfs_check_same_fs; + /* TODO: GnomeVFSMethodFindDirectoryFunc find_directory; */ + /* TODO: GnomeVFSMethodFileControlFunc file_control; */ + /* R/W: GnomeVFSMethodCreateSymbolicLinkFunc create_symbolic_link; */ + /* R/W: GnomeVFSMethodMonitorAddFunc monitor_add; */ + /* R/W: GnomeVFSMethodMonitorCancelFunc monitor_cancel; */ + /* R/W: GnomeVFSMethod_static.write; */ + /* R/W: GnomeVFSMethod_static.truncate_handle; */ + /* R/W: GnomeVFSMethod_static.make_directory; */ + /* R/W: GnomeVFSMethod_static.remove_directory; */ + /* R/W: GnomeVFSMethod_static.move; */ + /* R/W: GnomeVFSMethod_static.unlink; */ + /* R/W: GnomeVFSMethod_static.set_file_info; */ + /* R/W: GnomeVFSMethod_static.truncate; */ + G_UNLOCK(GnomeVFSMethod_static); + + return &GnomeVFSMethod_static; +} + +/** + * libntfs_gnomevfs_method_shutdown: + * + * Shutdowns libntfs-gnomevfs successfuly flushing all caches. + * + * Sad note about gnome-vfs-2.1.5 is that it never calls this function. :-) + */ +void libntfs_gnomevfs_method_shutdown(void) +{ + uri_parent_string_hash_init(); + G_LOCK(uri_parent_string_hash); + g_hash_table_destroy(uri_parent_string_hash); + uri_parent_string_hash = NULL; + G_UNLOCK(uri_parent_string_hash); + + method_name_hash_init(); + G_LOCK(method_name_hash); + g_hash_table_destroy(method_name_hash); + method_name_hash = NULL; + G_UNLOCK(method_name_hash); +} + diff --git a/libntfs/unistr.c b/libntfs/unistr.c index cfb78f24..8122d873 100644 --- a/libntfs/unistr.c +++ b/libntfs/unistr.c @@ -71,10 +71,10 @@ const u8 legal_ansi_char_array[0x40] = { * identical, or FALSE (0) if they are not identical. If @ic is IGNORE_CASE, * the @upcase table is used to performa a case insensitive comparison. */ -BOOL ntfs_names_are_equal(const uchar_t *s1, size_t s1_len, - const uchar_t *s2, size_t s2_len, +BOOL ntfs_names_are_equal(const ntfschar *s1, size_t s1_len, + const ntfschar *s2, size_t s2_len, const IGNORE_CASE_BOOL ic, - const uchar_t *upcase, const u32 upcase_size) + const ntfschar *upcase, const u32 upcase_size) { if (s1_len != s2_len) return FALSE; @@ -104,13 +104,13 @@ BOOL ntfs_names_are_equal(const uchar_t *s1, size_t s1_len, * * The following characters are considered invalid: '"', '*', '<', '>' and '?'. */ -int ntfs_names_collate(const uchar_t *name1, const u32 name1_len, - const uchar_t *name2, const u32 name2_len, +int ntfs_names_collate(const ntfschar *name1, const u32 name1_len, + const ntfschar *name2, const u32 name2_len, const int err_val, const IGNORE_CASE_BOOL ic, - const uchar_t *upcase, const u32 upcase_len) + const ntfschar *upcase, const u32 upcase_len) { u32 cnt; - uchar_t c1, c2; + ntfschar c1, c2; #ifdef DEBUG if (!name1 || !name2 || (ic && !upcase && upcase_len)) { @@ -160,9 +160,9 @@ int ntfs_names_collate(const uchar_t *name1, const u32 name1_len, * if @s1 (or the first @n Unicode characters thereof) is found, respectively, * to be less than, to match, or be greater than @s2. */ -int ntfs_ucsncmp(const uchar_t *s1, const uchar_t *s2, size_t n) +int ntfs_ucsncmp(const ntfschar *s1, const ntfschar *s2, size_t n) { - uchar_t c1, c2; + ntfschar c1, c2; size_t i; #ifdef DEBUG @@ -202,10 +202,10 @@ int ntfs_ucsncmp(const uchar_t *s1, const uchar_t *s2, size_t n) * if @s1 (or the first @n Unicode characters thereof) is found, respectively, * to be less than, to match, or be greater than @s2. */ -int ntfs_ucsncasecmp(const uchar_t *s1, const uchar_t *s2, size_t n, - const uchar_t *upcase, const u32 upcase_size) +int ntfs_ucsncasecmp(const ntfschar *s1, const ntfschar *s2, size_t n, + const ntfschar *upcase, const u32 upcase_size) { - uchar_t c1, c2; + ntfschar c1, c2; size_t i; #ifdef DEBUG @@ -236,12 +236,12 @@ int ntfs_ucsncasecmp(const uchar_t *s1, const uchar_t *s2, size_t n, * * Return the number of Unicode characters in the little endian Unicode * string @s up to a maximum of maxlen Unicode characters, not including - * the terminating (uchar_t)'\0'. If there is no (uchar_t)'\0' between @s + * the terminating (ntfschar)'\0'. If there is no (ntfschar)'\0' between @s * and @s + @maxlen, @maxlen is returned. * * This function never looks beyond @s + @maxlen. */ -u32 ntfs_ucsnlen(const uchar_t *s, u32 maxlen) +u32 ntfs_ucsnlen(const ntfschar *s, u32 maxlen) { u32 i; @@ -255,11 +255,11 @@ u32 ntfs_ucsnlen(const uchar_t *s, u32 maxlen) /** * ntfs_name_upcase */ -void ntfs_name_upcase(uchar_t *name, u32 name_len, const uchar_t *upcase, +void ntfs_name_upcase(ntfschar *name, u32 name_len, const ntfschar *upcase, const u32 upcase_len) { u32 i; - uchar_t u; + ntfschar u; for (i = 0; i < name_len; i++) if ((u = le16_to_cpu(name[i])) < upcase_len) @@ -270,9 +270,9 @@ void ntfs_name_upcase(uchar_t *name, u32 name_len, const uchar_t *upcase, * ntfs_file_value_upcase */ void ntfs_file_value_upcase(FILE_NAME_ATTR *file_name_attr, - const uchar_t *upcase, const u32 upcase_len) + const ntfschar *upcase, const u32 upcase_len) { - ntfs_name_upcase((uchar_t*)&file_name_attr->file_name, + ntfs_name_upcase((ntfschar*)&file_name_attr->file_name, file_name_attr->file_name_length, upcase, upcase_len); } @@ -282,11 +282,11 @@ void ntfs_file_value_upcase(FILE_NAME_ATTR *file_name_attr, int ntfs_file_values_compare(FILE_NAME_ATTR *file_name_attr1, FILE_NAME_ATTR *file_name_attr2, const int err_val, const IGNORE_CASE_BOOL ic, - const uchar_t *upcase, const u32 upcase_len) + const ntfschar *upcase, const u32 upcase_len) { - return ntfs_names_collate((uchar_t*)&file_name_attr1->file_name, + return ntfs_names_collate((ntfschar*)&file_name_attr1->file_name, file_name_attr1->file_name_length, - (uchar_t*)&file_name_attr2->file_name, + (ntfschar*)&file_name_attr2->file_name, file_name_attr2->file_name_length, err_val, ic, upcase, upcase_len); } @@ -316,7 +316,7 @@ int ntfs_file_values_compare(FILE_NAME_ATTR *file_name_attr1, * ENAMETOOLONG Destination buffer is too small for input string. * ENOMEM Not enough memory to allocate destination buffer. */ -int ntfs_ucstombs(const uchar_t *ins, const int ins_len, char **outs, +int ntfs_ucstombs(const ntfschar *ins, const int ins_len, char **outs, int outs_len) { char *mbs; @@ -429,9 +429,9 @@ err_out: * ENAMETOOLONG Destination buffer is too small for input string. * ENOMEM Not enough memory to allocate destination buffer. */ -int ntfs_mbstoucs(const char *ins, uchar_t **outs, int outs_len) +int ntfs_mbstoucs(const char *ins, ntfschar **outs, int outs_len) { - uchar_t *ucs; + ntfschar *ucs; const char *s; wchar_t wc; int i, o, cnt, ins_len, ucs_len; @@ -480,7 +480,7 @@ int ntfs_mbstoucs(const char *ins, uchar_t **outs, int outs_len) ins_len++; if (!ucs) { ucs_len = ins_len; - ucs = (uchar_t*)malloc(ucs_len * sizeof(uchar_t)); + ucs = (ntfschar*)malloc(ucs_len * sizeof(ntfschar)); if (!ucs) return -1; } @@ -492,7 +492,7 @@ int ntfs_mbstoucs(const char *ins, uchar_t **outs, int outs_len) for (i = o = cnt = 0; o < ins_len; i += cnt, o++) { /* Reallocate memory if necessary or abort. */ if (o >= ucs_len) { - uchar_t *tc; + ntfschar *tc; if (ucs == *outs) { errno = ENAMETOOLONG; return -1; @@ -501,12 +501,12 @@ int ntfs_mbstoucs(const char *ins, uchar_t **outs, int outs_len) * We will never get here but hey, it's only a bit of * extra code... */ - ucs_len = (ucs_len * sizeof(uchar_t) + 64) & ~63; - tc = (uchar_t*)realloc(ucs, ucs_len); + ucs_len = (ucs_len * sizeof(ntfschar) + 64) & ~63; + tc = (ntfschar*)realloc(ucs, ucs_len); if (!tc) goto err_out; ucs = tc; - ucs_len /= sizeof(uchar_t); + ucs_len /= sizeof(ntfschar); } /* Convert the multibyte character to a wide character. */ #ifdef HAVE_MBSINIT @@ -525,7 +525,7 @@ int ntfs_mbstoucs(const char *ins, uchar_t **outs, int outs_len) } /* Make sure we are not overflowing the NTFS Unicode set. */ if ((unsigned long)wc >= (unsigned long)(1 << - (8 * sizeof(uchar_t)))) { + (8 * sizeof(ntfschar)))) { errno = EILSEQ; goto err_out; } diff --git a/libntfs/volume.c b/libntfs/volume.c index eb426a86..e82fb056 100644 --- a/libntfs/volume.c +++ b/libntfs/volume.c @@ -594,7 +594,7 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long rwflag) ntfs_attr *na; ATTR_RECORD *a; VOLUME_INFORMATION *vinf; - uchar_t *vname; + ntfschar *vname; int i, j, eo; u32 u; @@ -732,7 +732,7 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long rwflag) goto error_exit; } vol->upcase_len = na->data_size >> 1; - vol->upcase = (uchar_t*)malloc(na->data_size); + vol->upcase = (ntfschar*)malloc(na->data_size); if (!vol->upcase) { Dputs(FAILED); Dputs("Not enough memory to load $UpCase."); @@ -844,7 +844,7 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long rwflag) goto error_exit; } /* Get a pointer to the value of the attribute. */ - vname = (uchar_t*)(le16_to_cpu(a->value_offset) + (char*)a); + vname = (ntfschar*)(le16_to_cpu(a->value_offset) + (char*)a); u = le32_to_cpu(a->value_length) / 2; /* * Convert Unicode volume name to current locale multibyte @@ -864,9 +864,9 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long rwflag) goto error_exit; } for (j = 0; j < (s32)u; j++) { - uchar_t uc = le16_to_cpu(vname[j]); + ntfschar uc = le16_to_cpu(vname[j]); if (uc > 0xff) - uc = (uchar_t)'_'; + uc = (ntfschar)'_'; vol->vol_name[j] = (char)uc; } vol->vol_name[u] = '\0'; diff --git a/ntfsprogs/mkntfs.c b/ntfsprogs/mkntfs.c index 17db6f67..97284d17 100644 --- a/ntfsprogs/mkntfs.c +++ b/ntfsprogs/mkntfs.c @@ -137,7 +137,7 @@ extern const unsigned char attrdef_ntfs12_array[2400]; extern const unsigned char boot_array[3429]; extern void init_system_file_sd(int sys_file_no, char **sd_val, int *sd_val_len); -extern void init_upcase_table(uchar_t *uc, u32 uc_len); +extern void init_upcase_table(ntfschar *uc, u32 uc_len); /* Page size on ia32. Can change to 8192 on Alpha. */ #define NTFS_PAGE_SIZE 4096 @@ -193,7 +193,7 @@ struct { bad clusters from. */ ATTR_DEF *attr_defs; /* filename, attribute defs. */ int attr_defs_len; /* in bytes */ - uchar_t *upcase; /* filename, upcase table. */ + ntfschar *upcase; /* filename, upcase table. */ u32 upcase_len; /* Determined automatically. */ int quiet; /* -q, quiet execution. */ int verbose; /* -v, verbose execution, given twice, @@ -571,9 +571,9 @@ static s64 ntfs_rlwrite(struct ntfs_device *dev, const runlist *rl, * terminating null byte. If a unicode character was encountered which could * not be converted -1 is returned. */ -static int ucstos(char *dest, const uchar_t *src, int maxlen) +static int ucstos(char *dest, const ntfschar *src, int maxlen) { - uchar_t u; + ntfschar u; int i; /* Need one byte for null terminator. */ @@ -603,17 +603,17 @@ static int ucstos(char *dest, const uchar_t *src, int maxlen) * write the terminating null unicode character and hence return -1 with errno * set to EINVAL. */ -static int stoucs(uchar_t *dest, const char *src, int maxlen) +static int stoucs(ntfschar *dest, const char *src, int maxlen) { char c; int i; - if (maxlen < (int)sizeof(uchar_t)) { + if (maxlen < (int)sizeof(ntfschar)) { errno = EINVAL; return -1; } /* Convert maxlen from bytes to unicode characters. */ - maxlen /= sizeof(uchar_t); + maxlen /= sizeof(ntfschar); /* Need space for null terminator. */ maxlen--; for (i = 0; i < maxlen; i++) { @@ -666,7 +666,7 @@ static void dump_resident_attr_val(ATTR_TYPES type, char *val, u32 val_len) if (!buf) err_exit("Failed to allocate internal buffer: " "%s\n", strerror(errno)); - i = ucstos(buf, (uchar_t*)val, val_len); + i = ucstos(buf, (ntfschar*)val, val_len); if (i == -1) printf("Volume name contains non-displayable " "Unicode characters.\n"); @@ -881,7 +881,7 @@ static void dump_attr_record(ATTR_RECORD *a) cpu_to_le16(a->name_offset)); u = a->flags; if (a->name_length) { - if (ucstos(s, (uchar_t*)((char*)a + + if (ucstos(s, (ntfschar*)((char*)a + cpu_to_le16(a->name_offset)), min(sizeof(s), a->name_length + 1U)) == -1) { Eprintf("Could not convert Unicode string to single " @@ -1162,15 +1162,15 @@ static int insert_positioned_attr_in_mft_record(MFT_RECORD *m, int asize, mpa_size, err, i; s64 bw = 0, inited_size; VCN highest_vcn; - uchar_t *uname; + ntfschar *uname; /* if (base record) attr_lookup(); else */ if (name_len) { - i = (name_len + 1) * sizeof(uchar_t); - uname = (uchar_t*)calloc(1, i); + i = (name_len + 1) * sizeof(ntfschar); + uname = (ntfschar*)calloc(1, i); if (!uname) return -errno; name_len = stoucs(uname, name, i); @@ -1347,15 +1347,15 @@ static int insert_non_resident_attr_in_mft_record(MFT_RECORD *m, int asize, mpa_size, err, i; runlist *rl = NULL; s64 bw = 0; - uchar_t *uname; + ntfschar *uname; /* if (base record) attr_lookup(); else */ if (name_len) { - i = (name_len + 1) * sizeof(uchar_t); - uname = (uchar_t*)calloc(1, i); + i = (name_len + 1) * sizeof(ntfschar); + uname = (ntfschar*)calloc(1, i); if (!uname) return -errno; name_len = stoucs(uname, name, i); @@ -1536,15 +1536,15 @@ static int insert_resident_attr_in_mft_record(MFT_RECORD *m, ntfs_attr_search_ctx *ctx; ATTR_RECORD *a; int asize, err, i; - uchar_t *uname; + ntfschar *uname; /* if (base record) ntfs_attr_lookup(); else */ if (name_len) { - i = (name_len + 1) * sizeof(uchar_t); - uname = (uchar_t*)calloc(1, i); + i = (name_len + 1) * sizeof(ntfschar); + uname = (ntfschar*)calloc(1, i); name_len = stoucs(uname, name, i); if (name_len > 0xff) return -ENAMETOOLONG; @@ -1695,7 +1695,7 @@ static int add_attr_file_name(MFT_RECORD *m, const MFT_REF parent_dir, } si = (STANDARD_INFORMATION*)((char*)ctx->attr + le16_to_cpu(ctx->attr->value_offset)); - i = (strlen(file_name) + 1) * sizeof(uchar_t); + i = (strlen(file_name) + 1) * sizeof(ntfschar); fn_size = sizeof(FILE_NAME_ATTR) + i; fn = (FILE_NAME_ATTR*)malloc(fn_size); if (!fn) { @@ -1735,7 +1735,7 @@ static int add_attr_file_name(MFT_RECORD *m, const MFT_REF parent_dir, } /* No terminating null in file names. */ fn->file_name_length = i; - fn_size = sizeof(FILE_NAME_ATTR) + i * sizeof(uchar_t); + fn_size = sizeof(FILE_NAME_ATTR) + i * sizeof(ntfschar); i = insert_resident_attr_in_mft_record(m, AT_FILE_NAME, NULL, 0, 0, 0, RESIDENT_ATTR_IS_INDEXED, (char*)fn, fn_size); free(fn); @@ -1833,7 +1833,7 @@ static int add_attr_data_positioned(MFT_RECORD *m, const char *name, * Create volume name attribute specifying the volume name @vol_name as a null * terminated char string of length @vol_name_len (number of characters not * including the terminating null), which is converted internally to a little - * endian uchar_t string. The name is at least 1 character long and at most + * endian ntfschar string. The name is at least 1 character long and at most * 0xff characters long (not counting the terminating null). * * Return 0 on success or -errno on error. @@ -1841,15 +1841,15 @@ static int add_attr_data_positioned(MFT_RECORD *m, const char *name, static int add_attr_vol_name(MFT_RECORD *m, const char *vol_name, const int vol_name_len) { - uchar_t *uname; + ntfschar *uname; int i, len; if (vol_name_len) { - len = (vol_name_len + 1) * sizeof(uchar_t); + len = (vol_name_len + 1) * sizeof(ntfschar); uname = calloc(1, len); if (!uname) return -errno; - i = (stoucs(uname, vol_name, len) + 1) * sizeof(uchar_t); + i = (stoucs(uname, vol_name, len) + 1) * sizeof(ntfschar); if (!i) { free(uname); return -EINVAL; @@ -2053,14 +2053,14 @@ static int upgrade_to_large_index(MFT_RECORD *m, const char *name, INDEX_ROOT *r; INDEX_ENTRY *re; INDEX_ALLOCATION *ia_val = NULL; - uchar_t *uname; + ntfschar *uname; char bmp[8]; char *re_start, *re_end; int i, err, index_block_size; if (name_len) { - i = (name_len + 1) * sizeof(uchar_t); - uname = (uchar_t*)calloc(1, i); + i = (name_len + 1) * sizeof(ntfschar); + uname = (ntfschar*)calloc(1, i); if (!uname) return -errno; name_len = stoucs(uname, name, i); @@ -2289,7 +2289,7 @@ static int insert_file_link_in_dir_index(INDEX_BLOCK *index, MFT_REF file_ref, if (!__buf) err_exit("Failed to allocate internal buffer: " "%s\n", strerror(errno)); - i = ucstos(__buf, (uchar_t*)&file_name->file_name, + i = ucstos(__buf, (ntfschar*)&file_name->file_name, file_name->file_name_length + 1); if (i == -1) Dprintf("Name contains non-displayable " @@ -2399,7 +2399,7 @@ static int create_hardlink(INDEX_BLOCK *index, const MFT_REF ref_parent, int i, fn_size; /* Create the file_name attribute. */ - i = (strlen(file_name) + 1) * sizeof(uchar_t); + i = (strlen(file_name) + 1) * sizeof(ntfschar); fn_size = sizeof(FILE_NAME_ATTR) + i; fn = (FILE_NAME_ATTR*)malloc(fn_size); if (!fn) @@ -2436,7 +2436,7 @@ static int create_hardlink(INDEX_BLOCK *index, const MFT_REF ref_parent, } /* No terminating null in file names. */ fn->file_name_length = i; - fn_size = sizeof(FILE_NAME_ATTR) + i * sizeof(uchar_t); + fn_size = sizeof(FILE_NAME_ATTR) + i * sizeof(ntfschar); /* Increment the link count of @m_file. */ i = le16_to_cpu(m_file->link_count); if (i == 0xffff) { @@ -3621,10 +3621,10 @@ int main(int argc, char **argv) vol->mft_record_size_bits = 10; /* Length is in unicode characters. */ vol->upcase_len = 65536; - vol->upcase = (uchar_t*)malloc(vol->upcase_len * sizeof(uchar_t)); + vol->upcase = (ntfschar*)malloc(vol->upcase_len * sizeof(ntfschar)); if (!vol->upcase) err_exit("Could not allocate memory for internal buffer.\n"); - init_upcase_table(vol->upcase, vol->upcase_len * sizeof(uchar_t)); + init_upcase_table(vol->upcase, vol->upcase_len * sizeof(ntfschar)); /* Initialize opts to zero / required values. */ init_options(); /* Parse command line options. */ @@ -3666,7 +3666,7 @@ int main(int argc, char **argv) // update during each subsequent c&w of each system file. Vprintf("Syncing root directory index record.\n"); m = (MFT_RECORD*)(buf + 5 * vol->mft_record_size); - i = 5 * sizeof(uchar_t); + i = 5 * sizeof(ntfschar); ctx = ntfs_attr_get_search_ctx(NULL, m); if (!ctx) err_exit("Failed to allocate attribute search context: %s\n", diff --git a/ntfsprogs/ntfscat.c b/ntfsprogs/ntfscat.c index c16c5907..bd2d8834 100644 --- a/ntfsprogs/ntfscat.c +++ b/ntfsprogs/ntfscat.c @@ -210,7 +210,7 @@ static int parse_options (int argc, char **argv) /** * cat */ -static int cat (ntfs_volume *vol, ntfs_inode *inode, ATTR_TYPES type, uchar_t *name, int namelen) +static int cat (ntfs_volume *vol, ntfs_inode *inode, ATTR_TYPES type, ntfschar *name, int namelen) { /* increase 1024 only if you fix partial writes below */ const int bufsize = 1024; diff --git a/ntfsprogs/ntfscluster.h b/ntfsprogs/ntfscluster.h index 1bf31474..afba3f39 100644 --- a/ntfsprogs/ntfscluster.h +++ b/ntfsprogs/ntfscluster.h @@ -53,7 +53,7 @@ struct options { struct match { u64 inum; /* Inode number */ ATTR_TYPES type; /* Attribute type */ - uchar_t *name; /* Attribute name */ + ntfschar *name; /* Attribute name */ int name_len; /* Length of attribute name */ LCN lcn; /* Last cluster in use */ }; diff --git a/ntfsprogs/ntfsinfo.c b/ntfsprogs/ntfsinfo.c index 9c81294a..6b48294d 100644 --- a/ntfsprogs/ntfsinfo.c +++ b/ntfsprogs/ntfsinfo.c @@ -293,12 +293,12 @@ static char *ntfsinfo_time_to_str(const s64 sle_ntfs_clock) */ static char *ntfs_attr_get_name(ATTR_RECORD *attr) { - uchar_t *ucs_attr_name; + ntfschar *ucs_attr_name; char *mbs_attr_name = NULL; int mbs_attr_name_size; /* calculate name position */ - ucs_attr_name = (uchar_t *)((char *)attr + le16_to_cpu(attr->name_offset)); + ucs_attr_name = (ntfschar *)((char *)attr + le16_to_cpu(attr->name_offset)); /* convert unicode to printable format */ mbs_attr_name_size = ntfs_ucstombs(ucs_attr_name,attr->name_length, &mbs_attr_name,0); @@ -692,7 +692,7 @@ static void ntfs_dump_attr_security_descriptor(ATTR_RECORD *attr) */ static void ntfs_dump_attr_volume_name(ATTR_RECORD *attr) { - uchar_t *ucs_vol_name = NULL; + ntfschar *ucs_vol_name = NULL; printf("Dumping attribute $VOLUME_NAME (0x60)\n"); @@ -700,11 +700,11 @@ static void ntfs_dump_attr_volume_name(ATTR_RECORD *attr) char *mbs_vol_name = NULL; int mbs_vol_name_size; /* calculate volume name position */ - ucs_vol_name = (uchar_t*)((u8*)attr + + ucs_vol_name = (ntfschar*)((u8*)attr + le16_to_cpu(attr->value_offset)); /* convert the name to current locale multibyte sequence */ mbs_vol_name_size = ntfs_ucstombs(ucs_vol_name, - le32_to_cpu(attr->value_length)/sizeof(uchar_t), + le32_to_cpu(attr->value_length)/sizeof(ntfschar), &mbs_vol_name,0); if (mbs_vol_name_size>0) { diff --git a/ntfsprogs/ntfslabel.c b/ntfsprogs/ntfslabel.c index 3ad49878..51c5f7ea 100644 --- a/ntfsprogs/ntfslabel.c +++ b/ntfsprogs/ntfslabel.c @@ -249,7 +249,7 @@ static int resize_resident_attribute_value(MFT_RECORD *m, ATTR_RECORD *a, static int change_label(ntfs_volume *vol, unsigned long mnt_flags, char *label, BOOL force) { ntfs_attr_search_ctx *ctx = NULL; - uchar_t *new_label = NULL; + ntfschar *new_label = NULL; MFT_RECORD *mrec = NULL; ATTR_RECORD *a; int label_len; @@ -305,13 +305,13 @@ static int change_label(ntfs_volume *vol, unsigned long mnt_flags, char *label, perror("Unable to convert label string to Unicode"); goto err_out; } - label_len *= sizeof(uchar_t); + label_len *= sizeof(ntfschar); if (label_len > 0x100) { fprintf(stderr, "New label is too long. Maximum %u characters " "allowed. Truncating excess characters.\n", - (unsigned)(0x100 / sizeof(uchar_t))); + (unsigned)(0x100 / sizeof(ntfschar))); label_len = 0x100; - new_label[label_len / sizeof(uchar_t)] = cpu_to_le16(L'\0'); + new_label[label_len / sizeof(ntfschar)] = cpu_to_le16(L'\0'); } if (a) { if (resize_resident_attribute_value(mrec, a, label_len)) { diff --git a/ntfsprogs/ntfsls.c b/ntfsprogs/ntfsls.c index ac1734c0..35072dfb 100644 --- a/ntfsprogs/ntfsls.c +++ b/ntfsprogs/ntfsls.c @@ -226,7 +226,7 @@ typedef struct { * list_entry * FIXME: Should we print errors as we go along? (AIA) */ -static int list_entry(ntfsls_dirent *dirent, const uchar_t *name, +static int list_entry(ntfsls_dirent *dirent, const ntfschar *name, const int name_len, const int name_type, const s64 pos, const MFT_REF mref, const unsigned dt_type) { @@ -379,7 +379,7 @@ int main(int argc, char **argv) FILE_NAME_ATTR *attr; ntfs_attr_search_ctx *ctx; int space = 4; - uchar_t *name = NULL; + ntfschar *name = NULL; int name_len = 0;; ctx = ntfs_attr_get_search_ctx (NULL, ni->mrec); diff --git a/ntfsprogs/ntfsmove.c b/ntfsprogs/ntfsmove.c index f1f600fe..d334b6ee 100644 --- a/ntfsprogs/ntfsmove.c +++ b/ntfsprogs/ntfsmove.c @@ -441,7 +441,7 @@ done: */ static int dont_move (ntfs_inode *ino) { - static const uchar_t ntldr[6] = { + static const ntfschar ntldr[6] = { const_cpu_to_le16('n'), const_cpu_to_le16('t'), const_cpu_to_le16('l'), const_cpu_to_le16('d'), const_cpu_to_le16('r'), const_cpu_to_le16('\0') }; diff --git a/ntfsprogs/ntfsresize.c b/ntfsprogs/ntfsresize.c index 335292c0..689a8b47 100644 --- a/ntfsprogs/ntfsresize.c +++ b/ntfsprogs/ntfsresize.c @@ -560,7 +560,7 @@ static s64 nr_clusters_to_bitmap_byte_size(s64 nr_clusters) return bm_bsize; } -static int str2unicode(const char *aname, uchar_t **ustr, int *len) +static int str2unicode(const char *aname, ntfschar **ustr, int *len) { if (aname && ((*len = ntfs_mbstoucs(aname, ustr, 0)) == -1)) return -1; @@ -576,7 +576,7 @@ static int str2unicode(const char *aname, uchar_t **ustr, int *len) static int has_bad_sectors(ntfs_resize_t *resize) { int len, ret = 0; - uchar_t *ustr = NULL; + ntfschar *ustr = NULL; ATTR_RECORD *a = resize->ctx->attr; if (resize->ni->mft_no != FILE_BadClus) @@ -586,7 +586,7 @@ static int has_bad_sectors(ntfs_resize_t *resize) return -1; if (ustr && ntfs_names_are_equal(ustr, len, - (uchar_t*)((u8*)a + le16_to_cpu(a->name_offset)), + (ntfschar*)((u8*)a + le16_to_cpu(a->name_offset)), a->name_length, 0, NULL, 0)) ret = 1; @@ -1776,7 +1776,7 @@ static void lookup_data_attr(ntfs_volume *vol, ntfs_attr_search_ctx **ctx) { ntfs_inode *ni; - uchar_t *ustr = NULL; + ntfschar *ustr = NULL; int len = 0; if (!(ni = ntfs_inode_open(vol, mref))) diff --git a/ntfsprogs/ntfstruncate.c b/ntfsprogs/ntfstruncate.c index 8a048357..6c4efa31 100644 --- a/ntfsprogs/ntfstruncate.c +++ b/ntfsprogs/ntfstruncate.c @@ -71,7 +71,7 @@ BOOL success = FALSE; char *dev_name; s64 inode; u32 attr_type; -uchar_t *attr_name = NULL; +ntfschar *attr_name = NULL; u32 attr_name_len; s64 new_len; @@ -304,9 +304,9 @@ static void parse_options(int argc, char *argv[]) * terminating null byte. If a unicode character was encountered which could * not be converted -1 is returned. */ -static int ucstos(char *dest, const uchar_t *src, int maxlen) +static int ucstos(char *dest, const ntfschar *src, int maxlen) { - uchar_t u; + ntfschar u; int i; /* Need one byte for null terminator. */ @@ -364,7 +364,7 @@ static void dump_resident_attr_val(ATTR_TYPES type, char *val, u32 val_len) if (!buf) err_exit("Failed to allocate internal buffer: " "%s\n", strerror(errno)); - i = ucstos(buf, (uchar_t*)val, val_len); + i = ucstos(buf, (ntfschar*)val, val_len); if (i == -1) printf("Volume name contains non-displayable " "Unicode characters.\n"); @@ -585,7 +585,7 @@ static void dump_attr_record(MFT_RECORD *m, ATTR_RECORD *a) cpu_to_le16(a->name_offset)); u = a->flags; if (a->name_length) { - if (ucstos(s, (uchar_t*)((char*)a + + if (ucstos(s, (ntfschar*)((char*)a + cpu_to_le16(a->name_offset)), min((int)sizeof(s), a->name_length + 1)) == -1) { diff --git a/ntfsprogs/ntfsundelete.c b/ntfsprogs/ntfsundelete.c index 27384500..8976e64c 100644 --- a/ntfsprogs/ntfsundelete.c +++ b/ntfsprogs/ntfsundelete.c @@ -666,7 +666,7 @@ static int get_data (struct ufile *file, ntfs_volume *vol) data->encrypted = rec->flags & ATTR_IS_ENCRYPTED; if (rec->name_length) { - data->uname = (uchar_t *) ((char *) rec + le16_to_cpu (rec->name_offset)); + data->uname = (ntfschar *) ((char *) rec + le16_to_cpu (rec->name_offset)); data->uname_len = rec->name_length; if (ntfs_ucstombs (data->uname, data->uname_len, &data->name, diff --git a/ntfsprogs/ntfsundelete.h b/ntfsprogs/ntfsundelete.h index 9378229c..d2cb4c66 100644 --- a/ntfsprogs/ntfsundelete.h +++ b/ntfsprogs/ntfsundelete.h @@ -60,7 +60,7 @@ struct filename { struct list_head list; /* Previous/Next links */ char *name; /* Filename in current locale */ FILE_NAME_TYPE_FLAGS name_space; - uchar_t *uname; /* Filename in unicode */ + ntfschar *uname; /* Filename in unicode */ int uname_len; /* and its length */ long long size_alloc; /* Allocated size (multiple of cluster size) */ long long size_data; /* Actual size of data */ @@ -74,7 +74,7 @@ struct filename { struct data { struct list_head list; /* Previous/Next links */ char *name; /* Stream name in current locale */ - uchar_t *uname; /* Unicode stream name */ + ntfschar *uname; /* Unicode stream name */ int uname_len; /* and its length */ int resident; /* Stream is resident */ int compressed; /* Stream is compressed */ diff --git a/ntfsprogs/upcase.c b/ntfsprogs/upcase.c index ae5db1e0..ec02a64b 100644 --- a/ntfsprogs/upcase.c +++ b/ntfsprogs/upcase.c @@ -31,8 +31,8 @@ /** * init_upcase_table */ -void init_upcase_table(uchar_t *uc, u32 uc_len); -void init_upcase_table(uchar_t *uc, u32 uc_len) +void init_upcase_table(ntfschar *uc, u32 uc_len); +void init_upcase_table(ntfschar *uc, u32 uc_len) { static int uc_run_table[][3] = { /* Start, End, Add */ {0x0061, 0x007B, -32}, {0x0451, 0x045D, -80}, {0x1F70, 0x1F72, 74}, diff --git a/ntfsprogs/utils.c b/ntfsprogs/utils.c index 36cbf37e..e96d8a83 100644 --- a/ntfsprogs/utils.c +++ b/ntfsprogs/utils.c @@ -567,7 +567,7 @@ int utils_attr_get_name (ntfs_volume *vol, ATTR_RECORD *attr, char *buffer, int name = NULL; namelen = attr->name_length; - if (ntfs_ucstombs ((uchar_t *)((char *)attr + attr->name_offset), + if (ntfs_ucstombs ((ntfschar *)((char *)attr + attr->name_offset), namelen, &name, namelen) < 0) { Eprintf ("Couldn't translate attribute name to current locale.\n"); // ? @@ -721,7 +721,7 @@ ntfs_inode * utils_pathname_to_inode (ntfs_volume *vol, ntfs_inode *parent, cons char *p, *q; ntfs_inode *ni; ntfs_inode *result = NULL; - uchar_t *unicode = NULL; + ntfschar *unicode = NULL; char *ascii = NULL; if (!vol || !pathname) {