diff options
Diffstat (limited to 'sys/fs')
-rw-r--r-- | sys/fs/ntfs/ntfs.h | 2 | ||||
-rw-r--r-- | sys/fs/ntfs/ntfs_subr.c | 123 | ||||
-rw-r--r-- | sys/fs/ntfs/ntfs_subr.h | 13 | ||||
-rw-r--r-- | sys/fs/ntfs/ntfs_vfsops.c | 13 | ||||
-rw-r--r-- | sys/fs/ntfs/ntfs_vnops.c | 2 | ||||
-rw-r--r-- | sys/fs/ntfs/ntfsmount.h | 2 |
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 */ }; |