--- fs/cifs/cifs_unicode.c.org 2005-04-02 22:16:49.000000000 -0600 +++ fs/cifs/cifs_unicode.c 2005-04-02 22:19:43.000000000 -0600 @@ -30,6 +30,18 @@ * FUNCTION: Convert little-endian unicode string to character string * */ + +/* Windows maps these to the user defined 16 bit Unicode range since they are + reserved symbols (along with \ and /), otherwise illegal to store + in filenames in NTFS */ +#define UNI_ASTERIK cpu_to_le16('*' + 0xF000) +#define UNI_QUESTION cpu_to_le16('?' + 0xF000) +#define UNI_COLON cpu_to_le16(':' + 0xF000) +#define UNI_GRTRTHAN cpu_to_le16('>' + 0xF000) +#define UNI_LESSTHAN cpu_to_le16('<' + 0xF000) +#define UNI_PIPE cpu_to_le16('|' + 0xF000) +#define UNI_SLASH cpu_to_le16('\\' + 0xF000) + int cifs_strfromUCS_le(char *to, const wchar_t * from, /* LITTLE ENDIAN */ int len, const struct nls_table *codepage) @@ -40,8 +52,30 @@ for (i = 0; (i < len) && from[i]; i++) { int charlen; /* 2.4.0 kernel or greater */ - charlen = - codepage->uni2char(le16_to_cpu(from[i]), &to[outlen], + if(from[i] == UNI_ASTERIK) { + to[i] = '*'; + charlen = 1; + } else if (from[i] == UNI_COLON) { + to[i] = ':'; + charlen = 1; + } else if (from[i] == UNI_PIPE) { + to[i] = '|'; + charlen = 1; + } else if (from[i] == UNI_QUESTION) { + to[i] = '?'; + charlen = 1; + } else if (from[i] == UNI_GRTRTHAN) { + to[i] = '>'; + charlen = 1; + } else if (from[i] == UNI_LESSTHAN) { + to[i] = '<'; + charlen = 1; + } else if (from[i] == UNI_SLASH) { + to[i] = '\\'; + charlen = 1; + } else + charlen = + codepage->uni2char(le16_to_cpu(from[i]), &to[outlen], NLS_MAX_CHARSET_SIZE); if (charlen > 0) { outlen += charlen; @@ -68,8 +102,30 @@ for (i = 0; len && *from; i++, from += charlen, len -= charlen) { +/* if(*from == '*') { + to[i] = UNI_ASTERIK; + charlen = 1; + } else*/ if (*from == ':') { + to[i] = UNI_COLON; + charlen = 1; + } else if (*from == '?') { + to[i] = UNI_QUESTION; + charlen = 1; + } else if (*from == '|') { + to[i] = UNI_PIPE; + charlen = 1; + } else if (*from == '>') { + to[i] = UNI_GRTRTHAN; + charlen = 1; + } else if (*from == '<') { + to[i] = UNI_LESSTHAN; + charlen = 1; + } else if (*from == '\\') { + to[i] = UNI_SLASH; + charlen = 1; + } else /* works for 2.4.0 kernel or later */ - charlen = codepage->char2uni(from, len, &to[i]); + charlen = codepage->char2uni(from, len, &to[i]); if (charlen < 1) { cERROR(1, ("cifs_strtoUCS: char2uni returned %d",