summaryrefslogtreecommitdiffstats
path: root/sys/fs/ntfs/ntfs_subr.c
diff options
context:
space:
mode:
authorsemenu <semenu@FreeBSD.org>2001-09-08 23:03:52 +0000
committersemenu <semenu@FreeBSD.org>2001-09-08 23:03:52 +0000
commit8c98d68610fb0ec072a45372df6fae9ec3afd215 (patch)
tree19a136464adf6bfe402fbab8c1d2c88463c6d7e7 /sys/fs/ntfs/ntfs_subr.c
parent22c38894cbd19ca224d48e51045206a9406b5c0f (diff)
downloadFreeBSD-src-8c98d68610fb0ec072a45372df6fae9ec3afd215.zip
FreeBSD-src-8c98d68610fb0ec072a45372df6fae9ec3afd215.tar.gz
Stole unicode translation table from mount_msdos. Add kernel code
to support this translation. MFC after: 2 weeks
Diffstat (limited to 'sys/fs/ntfs/ntfs_subr.c')
-rw-r--r--sys/fs/ntfs/ntfs_subr.c123
1 files changed, 107 insertions, 16 deletions
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]);
}
OpenPOWER on IntegriCloud