summaryrefslogtreecommitdiffstats
path: root/sys/fs
diff options
context:
space:
mode:
Diffstat (limited to 'sys/fs')
-rw-r--r--sys/fs/ntfs/ntfs.h2
-rw-r--r--sys/fs/ntfs/ntfs_subr.c123
-rw-r--r--sys/fs/ntfs/ntfs_subr.h13
-rw-r--r--sys/fs/ntfs/ntfs_vfsops.c13
-rw-r--r--sys/fs/ntfs/ntfs_vnops.c2
-rw-r--r--sys/fs/ntfs/ntfsmount.h2
6 files changed, 137 insertions, 18 deletions
diff --git a/sys/fs/ntfs/ntfs.h b/sys/fs/ntfs/ntfs.h
index d74fe6f..f5e9125 100644
--- a/sys/fs/ntfs/ntfs.h
+++ b/sys/fs/ntfs/ntfs.h
@@ -258,6 +258,8 @@ struct ntfsmount {
#if !defined(__FreeBSD__)
struct netexport ntm_export; /* export information */
#endif
+ wchar * ntm_82u; /* 8bit to Unicode */
+ char ** ntm_u28; /* Unicode to 8 bit */
};
#define ntm_mftcn ntm_bootfile.bf_mftcn
diff --git a/sys/fs/ntfs/ntfs_subr.c b/sys/fs/ntfs/ntfs_subr.c
index 7b9ae76..e1e6006 100644
--- a/sys/fs/ntfs/ntfs_subr.c
+++ b/sys/fs/ntfs/ntfs_subr.c
@@ -63,21 +63,20 @@ MALLOC_DEFINE(M_NTFSDECOMP, "NTFS decomp", "NTFS decompression temporary");
static int ntfs_ntlookupattr __P((struct ntfsmount *, const char *, int, int *, char **));
static int ntfs_findvattr __P((struct ntfsmount *, struct ntnode *, struct ntvattr **, struct ntvattr **, u_int32_t, const char *, size_t, cn_t));
-static int ntfs_uastricmp __P((const wchar *, size_t, const char *, size_t));
-static int ntfs_uastrcmp __P((const wchar *, size_t, const char *, size_t));
+static int ntfs_uastricmp __P((struct ntfsmount *, const wchar *, size_t, const char *, size_t));
+static int ntfs_uastrcmp __P((struct ntfsmount *, const wchar *, size_t, const char *, size_t));
/* table for mapping Unicode chars into uppercase; it's filled upon first
* ntfs mount, freed upon last ntfs umount */
static wchar *ntfs_toupper_tab;
-#define NTFS_U28(ch) ((((ch) & 0xFF) == 0) ? '_' : (ch) & 0xFF)
-#define NTFS_TOUPPER(ch) (ntfs_toupper_tab[(unsigned char)(ch)])
+#define NTFS_TOUPPER(ch) (ntfs_toupper_tab[(ch)])
static struct lock ntfs_toupper_lock;
static signed int ntfs_toupper_usecount;
/* support macro for ntfs_ntvattrget() */
#define NTFS_AALPCMP(aalp,type,name,namelen) ( \
(aalp->al_type == type) && (aalp->al_namelen == namelen) && \
- !ntfs_uastrcmp(aalp->al_name,aalp->al_namelen,name,namelen) )
+ !NTFS_UASTRCMP(aalp->al_name,aalp->al_namelen,name,namelen) )
/*
*
@@ -662,7 +661,8 @@ ntfs_runtovrun(
* Compare unicode and ascii string case insens.
*/
static int
-ntfs_uastricmp(ustr, ustrlen, astr, astrlen)
+ntfs_uastricmp(ntmp, ustr, ustrlen, astr, astrlen)
+ struct ntfsmount *ntmp;
const wchar *ustr;
size_t ustrlen;
const char *astr;
@@ -671,9 +671,13 @@ ntfs_uastricmp(ustr, ustrlen, astr, astrlen)
size_t i;
int res;
+ /*
+ * XXX We use NTFS_82U(NTFS_U28(c)) to get rid of unicode
+ * symbols not covered by translation table
+ */
for (i = 0; i < ustrlen && i < astrlen; i++) {
- res = ((int) NTFS_TOUPPER(NTFS_U28(ustr[i]))) -
- ((int)NTFS_TOUPPER(astr[i]));
+ res = ((int) NTFS_TOUPPER(NTFS_82U(NTFS_U28(ustr[i])))) -
+ ((int)NTFS_TOUPPER(NTFS_82U(astr[i])));
if (res)
return res;
}
@@ -684,7 +688,8 @@ ntfs_uastricmp(ustr, ustrlen, astr, astrlen)
* Compare unicode and ascii string case sens.
*/
static int
-ntfs_uastrcmp(ustr, ustrlen, astr, astrlen)
+ntfs_uastrcmp(ntmp, ustr, ustrlen, astr, astrlen)
+ struct ntfsmount *ntmp;
const wchar *ustr;
size_t ustrlen;
const char *astr;
@@ -918,7 +923,7 @@ ntfs_ntlookupfile(
/* check the name - the case-insensitible check
* has to come first, to break from this for loop
* if needed, so we can dive correctly */
- res = ntfs_uastricmp(iep->ie_fname, iep->ie_fnamelen,
+ res = NTFS_UASTRICMP(iep->ie_fname, iep->ie_fnamelen,
fname, fnamelen);
if (res > 0) break;
if (res < 0) continue;
@@ -926,7 +931,7 @@ ntfs_ntlookupfile(
if (iep->ie_fnametype == 0 ||
!(ntmp->ntm_flag & NTFS_MFLAG_CASEINS))
{
- res = ntfs_uastrcmp(iep->ie_fname,
+ res = NTFS_UASTRCMP(iep->ie_fname,
iep->ie_fnamelen, fname, fnamelen);
if (res != 0) continue;
}
@@ -1956,13 +1961,13 @@ ntfs_toupper_use(mp, ntmp)
* XXX for now, just the first 256 entries are used anyway,
* so don't bother reading more
*/
- MALLOC(ntfs_toupper_tab, wchar *, 256 * sizeof(wchar),
+ MALLOC(ntfs_toupper_tab, wchar *, 65536 * sizeof(wchar),
M_NTFSRDATA, M_WAITOK);
if ((error = VFS_VGET(mp, NTFS_UPCASEINO, &vp)))
goto out;
error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL,
- 0, 256*sizeof(wchar), (char *) ntfs_toupper_tab, NULL);
+ 0, 65536*sizeof(wchar), (char *) ntfs_toupper_tab, NULL);
vput(vp);
out:
@@ -1997,6 +2002,86 @@ ntfs_toupper_unuse()
LOCKMGR(&ntfs_toupper_lock, LK_RELEASE, NULL);
}
+int
+ntfs_u28_init(
+ struct ntfsmount *ntmp,
+ wchar *u2w)
+{
+ char ** u28;
+ int i, j, h, l;
+
+ MALLOC(u28, char **, 256 * sizeof(char*), M_TEMP, M_WAITOK | M_ZERO);
+
+ for (i=0; i<256; i++) {
+ h = (u2w[i] >> 8) & 0xFF;
+ l = (u2w[i]) &0xFF;
+
+ if (u28[h] == NULL) {
+ MALLOC(u28[h], char *, 256 * sizeof(char), M_TEMP, M_WAITOK);
+ for (j=0; j<256; j++)
+ u28[h][j] = '_';
+ }
+
+ u28[h][l] = i & 0xFF;
+ }
+
+ ntmp->ntm_u28 = u28;
+
+ return (0);
+}
+
+int
+ntfs_u28_uninit(struct ntfsmount *ntmp)
+{
+ char ** u28;
+ int i;
+
+ if (ntmp->ntm_u28 == NULL)
+ return (0);
+
+ u28 = ntmp->ntm_u28;
+
+ for (i=0; i<256; i++)
+ if (u28[i] != NULL)
+ FREE(u28[i], M_TEMP);
+
+ FREE(u28, M_TEMP);
+
+ return (0);
+}
+
+int
+ntfs_82u_init(
+ struct ntfsmount *ntmp,
+ u_int16_t *u2w)
+{
+ wchar * _82u;
+ int i;
+
+ MALLOC(_82u, wchar *, 256 * sizeof(wchar), M_TEMP, M_WAITOK);
+
+ if (u2w == NULL) {
+ for (i=0; i<256; i++)
+ _82u[i] = i;
+ } else {
+ for (i=0; i<128; i++)
+ _82u[i] = i;
+ for (i=0; i<128; i++)
+ _82u[i+128] = u2w[i];
+ }
+
+ ntmp->ntm_82u = _82u;
+
+ return (0);
+}
+
+int
+ntfs_82u_uninit(struct ntfsmount *ntmp)
+{
+ FREE(ntmp->ntm_82u, M_TEMP);
+ return (0);
+}
+
/*
* maps the Unicode char to 8bit equivalent
* XXX currently only gets lower 8bit from the Unicode char
@@ -2004,9 +2089,15 @@ ntfs_toupper_unuse()
* something better has to be definitely though out
*/
char
-ntfs_u28(unichar)
- wchar unichar;
+ntfs_u28(
+ struct ntfsmount *ntmp,
+ wchar wc)
{
- return (char) NTFS_U28(unichar);
+ char * p;
+
+ p = ntmp->ntm_u28[(wc>>8)&0xFF];
+ if (p == NULL)
+ return ('_');
+ return (p[wc&0xFF]);
}
diff --git a/sys/fs/ntfs/ntfs_subr.h b/sys/fs/ntfs/ntfs_subr.h
index 8f1480a..41a2dc7 100644
--- a/sys/fs/ntfs/ntfs_subr.h
+++ b/sys/fs/ntfs/ntfs_subr.h
@@ -84,7 +84,6 @@ int ntfs_filesize __P(( struct ntfsmount *, struct fnode *, u_int64_t *, u_int64
int ntfs_times __P(( struct ntfsmount *, struct ntnode *, ntfs_times_t *));
struct timespec ntfs_nttimetounix __P(( u_int64_t ));
int ntfs_ntreaddir __P(( struct ntfsmount *, struct fnode *, u_int32_t, struct attr_indexentry **));
-char ntfs_u28 __P((wchar));
int ntfs_runtovrun __P(( cn_t **, cn_t **, u_long *, u_int8_t *));
int ntfs_attrtontvattr __P(( struct ntfsmount *, struct ntvattr **, struct attr * ));
void ntfs_freentvattr __P(( struct ntvattr * ));
@@ -108,3 +107,15 @@ int ntfs_toupper_use __P((struct mount *, struct ntfsmount *));
void ntfs_toupper_unuse __P((void));
int ntfs_fget __P((struct ntfsmount *, struct ntnode *, int, char *, struct fnode **));
void ntfs_frele __P((struct fnode *));
+
+int ntfs_u28_init(struct ntfsmount *ntmp, wchar *u2w);
+int ntfs_u28_uninit(struct ntfsmount *ntmp);
+int ntfs_82u_init(struct ntfsmount *ntmp, u_int16_t *u2w);
+int ntfs_82u_uninit(struct ntfsmount *ntmp);
+char ntfs_u28(struct ntfsmount *ntmp, wchar wc);
+#define NTFS_U28(ch) ntfs_u28(ntmp, (ch))
+#define NTFS_82U(ch) (ntmp->ntm_82u[(ch)&0xFF])
+#define NTFS_UASTRCMP(ustr, ustrlen, astr, astrlen) \
+ ntfs_uastrcmp(ntmp, (ustr), (ustrlen), (astr), (astrlen))
+#define NTFS_UASTRICMP(ustr, ustrlen, astr, astrlen) \
+ ntfs_uastricmp(ntmp, (ustr), (ustrlen), (astr), (astrlen))
diff --git a/sys/fs/ntfs/ntfs_vfsops.c b/sys/fs/ntfs/ntfs_vfsops.c
index 94af95b..26a09b8 100644
--- a/sys/fs/ntfs/ntfs_vfsops.c
+++ b/sys/fs/ntfs/ntfs_vfsops.c
@@ -501,6 +501,17 @@ ntfs_mountfs(devvp, mp, argsp, p)
ntmp->ntm_gid = argsp->gid;
ntmp->ntm_mode = argsp->mode;
ntmp->ntm_flag = argsp->flag;
+
+ /* Copy in the 8-bit to Unicode conversion table */
+ if (argsp->flag & NTFSMNT_U2WTABLE) {
+ ntfs_82u_init(ntmp, argsp->u2w);
+ } else {
+ ntfs_82u_init(ntmp, NULL);
+ }
+
+ /* Initialize Unicode to 8-bit table from 8toU table */
+ ntfs_u28_init(ntmp, ntmp->ntm_82u);
+
mp->mnt_data = (qaddr_t)ntmp;
dprintf(("ntfs_mountfs(): case-%s,%s uid: %d, gid: %d, mode: %o\n",
@@ -697,6 +708,8 @@ ntfs_unmount(
ntfs_toupper_unuse();
dprintf(("ntfs_umount: freeing memory...\n"));
+ ntfs_u28_uninit(ntmp);
+ ntfs_82u_uninit(ntmp);
mp->mnt_data = (qaddr_t)0;
mp->mnt_flag &= ~MNT_LOCAL;
FREE(ntmp->ntm_ad, M_NTFSMNT);
diff --git a/sys/fs/ntfs/ntfs_vnops.c b/sys/fs/ntfs/ntfs_vnops.c
index be192a1..5c2297f 100644
--- a/sys/fs/ntfs/ntfs_vnops.c
+++ b/sys/fs/ntfs/ntfs_vnops.c
@@ -586,7 +586,7 @@ ntfs_readdir(ap)
continue;
for(i=0; i<iep->ie_fnamelen; i++) {
- cde.d_name[i] = ntfs_u28(iep->ie_fname[i]);
+ cde.d_name[i] = NTFS_U28(iep->ie_fname[i]);
}
cde.d_name[i] = '\0';
dprintf(("ntfs_readdir: elem: %d, fname:[%s] type: %d, flag: %d, ",
diff --git a/sys/fs/ntfs/ntfsmount.h b/sys/fs/ntfs/ntfsmount.h
index f3a6d25..0c143ed 100644
--- a/sys/fs/ntfs/ntfsmount.h
+++ b/sys/fs/ntfs/ntfsmount.h
@@ -30,6 +30,7 @@
#define NTFS_MFLAG_CASEINS 0x00000001
#define NTFS_MFLAG_ALLNAMES 0x00000002
+#define NTFSMNT_U2WTABLE 0x00000004
struct ntfs_args {
char *fspec; /* block special device to mount */
@@ -38,4 +39,5 @@ struct ntfs_args {
gid_t gid; /* gid that owns ntfs files */
mode_t mode; /* mask to be applied for ntfs perms */
u_long flag; /* additional flags */
+ u_int16_t u2w[256]; /* Unix to Wchar */
};
OpenPOWER on IntegriCloud