From patchwork Mon Mar 7 15:07:52 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve French X-Patchwork-Id: 615841 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p27F8nRR010451 for ; Mon, 7 Mar 2011 15:08:49 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751366Ab1CGPIt (ORCPT ); Mon, 7 Mar 2011 10:08:49 -0500 Received: from mail-iy0-f174.google.com ([209.85.210.174]:47020 "EHLO mail-iy0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751160Ab1CGPIt convert rfc822-to-8bit (ORCPT ); Mon, 7 Mar 2011 10:08:49 -0500 Received: by iyb26 with SMTP id 26so3972501iyb.19 for ; Mon, 07 Mar 2011 07:08:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type :content-transfer-encoding; bh=0nI91NatmVXeJxASuENILUNDVv8juVCPWb9+3/t7C4c=; b=SS6CNVrJ6WWZVX8OzB5jnmgdraJa/e6e20W2KsaAPiaw6h/9A/LsLc+vusktRZeIka fAE/CQ3JGGA0HSEnKDM10tqZd1KpfMO6NsuitPWkFafBdR4P4ZKc4AAejqVpIUiTHVI9 Tgp31CV/52wkr5IjWrTJgWz6iDzzlo+Ob7vvc= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type:content-transfer-encoding; b=rJuKk8ytZ9peZSBJ8syoXK/zYSk/nW6nTyIPAOOO/3AE/ucDEiHZ/afh0cheZ9Oyx1 r7W9pOwBf3PJ1BUojDejAZZIFQyS2T3NRuvaMqiT1sVGDCuN//6luVEuGSVQfSNwliCB 4bDsW5nxgyYvgwd8zkHw9qQdDEuZWL49NK9Vw= MIME-Version: 1.0 Received: by 10.43.61.138 with SMTP id ww10mr4435288icb.180.1299510472489; Mon, 07 Mar 2011 07:07:52 -0800 (PST) Received: by 10.42.148.195 with HTTP; Mon, 7 Mar 2011 07:07:52 -0800 (PST) In-Reply-To: <20110307094123.065e59c6@tlielax.poochiereds.net> References: <20110307094123.065e59c6@tlielax.poochiereds.net> Date: Mon, 7 Mar 2011 09:07:52 -0600 Message-ID: Subject: Re: [PATCH] cifs: add missing unicode handling routines needed for smb2 From: Steve French To: Jeff Layton Cc: linux-cifs@vger.kernel.org Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Mon, 07 Mar 2011 15:08:50 +0000 (UTC) diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c index fc0fd4f..9dd2682 100644 --- a/fs/cifs/cifs_unicode.c +++ b/fs/cifs/cifs_unicode.c @@ -333,3 +333,64 @@ ctoUCS_out: return i; } +#ifdef CONFIG_CIFS_SMB2 +/* + * smb2_local_to_ucs2_bytes - how long will a string be after conversion? + * @from - pointer to input string + * @maxbytes - don't go past this many bytes of input string + * @codepage - source codepage + * + * Walk a string and return the number of bytes that the string will + * be after being converted to the given charset, not including any null + * termination required. Don't walk past maxbytes in the source buffer. + */ + +int +smb2_local_to_ucs2_bytes(const char *from, int len, + const struct nls_table *codepage) +{ + int charlen; + int i; + wchar_t wchar_to; + + if (from == NULL) + return 0; + for (i = 0; len && *from; i++, from += charlen, len -= charlen) { + charlen = codepage->char2uni(from, len, &wchar_to); + /* Failed conversion defaults to a question mark */ + if (charlen < 1) + charlen = 1; + } + return 2 * i; /* UCS characters are two bytes */ +} + +/* + * smb2_strndup_to_ucs - copy a string to wire format from the local codepage + * @src - source string + * @maxlen - don't walk past this many bytes in the source string + * @ucslen - the length of the allocated string in bytes (including null) + * @codepage - source codepage + * + * Take a string convert it from the local codepage to UCS2 and + * put it in a new buffer. Returns a pointer to the new string or NULL on + * error. + */ +__le16 * +smb2_strndup_to_ucs(const char *src, const int maxlen, int *ucs_len, + const struct nls_table *codepage) +{ + int len; + __le16 *dst; + + len = smb2_local_to_ucs2_bytes(src, maxlen, codepage); + len += 2; /* NULL */ + dst = kmalloc(len, GFP_KERNEL); + if (!dst) { + *ucs_len = 0; + return NULL; + } + cifs_strtoUCS(dst, src, maxlen, codepage); + *ucs_len = len; + return dst; +} +#endif /* CONFIG_CIFS_SMB2 */ diff --git a/fs/cifs/cifs_unicode.h b/fs/cifs/cifs_unicode.h index 7fe6b52..a56dfbc 100644 --- a/fs/cifs/cifs_unicode.h +++ b/fs/cifs/cifs_unicode.h @@ -377,4 +377,11 @@ UniStrlwr(register wchar_t *upin) #endif +#ifdef CONFIG_CIFS_SMB2 +extern int smb2_local_to_ucs2_bytes(const char *from, int len, + const struct nls_table *codepage); +extern __le16 *smb2_strndup_to_ucs(const char *src, const int maxlen, + int *ucs_len, const struct nls_table *cp); +#endif /* CONFIG_CIFS_SMB2 */ + #endif /* _CIFS_UNICODE_H */