diff options
Diffstat (limited to 'sys/fs/ntfs/ntfs_subr.c')
-rw-r--r-- | sys/fs/ntfs/ntfs_subr.c | 123 |
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]); } |