⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ndr_string.c

📁 samba服务器!
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    Unix SMB/CIFS implementation.   routines for marshalling/unmarshalling string types   Copyright (C) Andrew Tridgell 2003      This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.      This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.      You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include "includes.h"/**  pull a general string from the wire*/NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s){	char *as=NULL;	uint32_t len1, ofs, len2;	uint16_t len3;	int ret;	charset_t chset = CH_UTF16LE;	unsigned byte_mul = 2;	unsigned flags = ndr->flags;	unsigned c_len_term = 0;	if (!(ndr_flags & NDR_SCALARS)) {		return NT_STATUS_OK;	}	if (NDR_BE(ndr)) {		chset = CH_UTF16BE;	}	if (flags & LIBNDR_FLAG_STR_ASCII) {		chset = CH_DOS;		byte_mul = 1;		flags &= ~LIBNDR_FLAG_STR_ASCII;	}	if (flags & LIBNDR_FLAG_STR_UTF8) {		chset = CH_UTF8;		byte_mul = 1;		flags &= ~LIBNDR_FLAG_STR_UTF8;	}	flags &= ~LIBNDR_FLAG_STR_CONFORMANT;	if (flags & LIBNDR_FLAG_STR_CHARLEN) {		c_len_term = 1;		flags &= ~LIBNDR_FLAG_STR_CHARLEN;	}	switch (flags & LIBNDR_STRING_FLAGS) {	case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:	case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM:		NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &len1));		NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &ofs));		if (ofs != 0) {			return ndr_pull_error(ndr, NDR_ERR_STRING, "non-zero array offset with string flags 0x%x\n",					      ndr->flags & LIBNDR_STRING_FLAGS);		}		NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &len2));		if (len2 > len1) {			return ndr_pull_error(ndr, NDR_ERR_STRING, 					      "Bad string lengths len1=%u ofs=%u len2=%u\n", 					      len1, ofs, len2);		}		NDR_PULL_NEED_BYTES(ndr, (len2 + c_len_term)*byte_mul);		if (len2 == 0) {			as = talloc_strdup(ndr->current_mem_ctx, "");		} else {			ret = convert_string_talloc(ndr->current_mem_ctx,						    chset, CH_UNIX, 						    ndr->data+ndr->offset, 						    (len2 + c_len_term)*byte_mul,						    &as, True);			if (ret == -1) {				return ndr_pull_error(ndr, NDR_ERR_CHARCNV, 						      "Bad character conversion");			}		}		NDR_CHECK(ndr_pull_advance(ndr, (len2 + c_len_term)*byte_mul));		if (len1 != len2) {			DEBUG(6,("len1[%u] != len2[%u] '%s'\n", len1, len2, as));		}		/* this is a way of detecting if a string is sent with the wrong		   termination */		if (ndr->flags & LIBNDR_FLAG_STR_NOTERM) {			if (strlen(as) < (len2 + c_len_term)) {				DEBUG(6,("short string '%s'\n", as));			}		} else {			if (strlen(as) == (len2 + c_len_term)) {				DEBUG(6,("long string '%s'\n", as));			}		}		*s = as;		break;	case LIBNDR_FLAG_STR_SIZE4:	case LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM:		NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &len1));		NDR_PULL_NEED_BYTES(ndr, (len1 + c_len_term)*byte_mul);		if (len1 == 0) {			as = talloc_strdup(ndr->current_mem_ctx, "");		} else {			ret = convert_string_talloc(ndr->current_mem_ctx,						    chset, CH_UNIX, 						    ndr->data+ndr->offset, 						    (len1 + c_len_term)*byte_mul,						    &as, False);			if (ret == -1) {				return ndr_pull_error(ndr, NDR_ERR_CHARCNV, 						      "Bad character conversion");			}		}		NDR_CHECK(ndr_pull_advance(ndr, (len1 + c_len_term)*byte_mul));		/* this is a way of detecting if a string is sent with the wrong		   termination */		if (ndr->flags & LIBNDR_FLAG_STR_NOTERM) {			if (strlen(as) < (len1 + c_len_term)) {				DEBUG(6,("short string '%s'\n", as));			}		} else {			if (strlen(as) == (len1 + c_len_term)) {				DEBUG(6,("long string '%s'\n", as));			}		}		*s = as;		break;	case LIBNDR_FLAG_STR_LEN4:	case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_NOTERM:		NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &ofs));		if (ofs != 0) {			return ndr_pull_error(ndr, NDR_ERR_STRING, "non-zero array offset with string flags 0x%x\n",					      ndr->flags & LIBNDR_STRING_FLAGS);		}		NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &len1));		NDR_PULL_NEED_BYTES(ndr, (len1 + c_len_term)*byte_mul);		if (len1 == 0) {			as = talloc_strdup(ndr->current_mem_ctx, "");		} else {			ret = convert_string_talloc(ndr->current_mem_ctx,						    chset, CH_UNIX, 						    ndr->data+ndr->offset, 						    (len1 + c_len_term)*byte_mul,						    &as, False);			if (ret == -1) {				return ndr_pull_error(ndr, NDR_ERR_CHARCNV, 						      "Bad character conversion");			}		}		NDR_CHECK(ndr_pull_advance(ndr, (len1 + c_len_term)*byte_mul));		/* this is a way of detecting if a string is sent with the wrong		   termination */		if (ndr->flags & LIBNDR_FLAG_STR_NOTERM) {			if (strlen(as) < (len1 + c_len_term)) {				DEBUG(6,("short string '%s'\n", as));			}		} else {			if (strlen(as) == (len1 + c_len_term)) {				DEBUG(6,("long string '%s'\n", as));			}		}		*s = as;		break;	case LIBNDR_FLAG_STR_SIZE2:	case LIBNDR_FLAG_STR_SIZE2|LIBNDR_FLAG_STR_NOTERM:		NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &len3));		NDR_PULL_NEED_BYTES(ndr, (len3 + c_len_term)*byte_mul);		if (len3 == 0) {			as = talloc_strdup(ndr->current_mem_ctx, "");		} else {			ret = convert_string_talloc(ndr->current_mem_ctx,						    chset, CH_UNIX, 						    ndr->data+ndr->offset, 						    (len3 + c_len_term)*byte_mul,						    &as, False);			if (ret == -1) {				return ndr_pull_error(ndr, NDR_ERR_CHARCNV, 						      "Bad character conversion");			}		}		NDR_CHECK(ndr_pull_advance(ndr, (len3 + c_len_term)*byte_mul));		/* this is a way of detecting if a string is sent with the wrong		   termination */		if (ndr->flags & LIBNDR_FLAG_STR_NOTERM) {			if (strlen(as) < (len3 + c_len_term)) {				DEBUG(6,("short string '%s'\n", as));			}		} else {			if (strlen(as) == (len3 + c_len_term)) {				DEBUG(6,("long string '%s'\n", as));			}		}		*s = as;		break;	case LIBNDR_FLAG_STR_SIZE2|LIBNDR_FLAG_STR_NOTERM|LIBNDR_FLAG_STR_BYTESIZE:		NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &len3));		NDR_PULL_NEED_BYTES(ndr, len3);		if (len3 == 0) {			as = talloc_strdup(ndr->current_mem_ctx, "");		} else {			ret = convert_string_talloc(ndr->current_mem_ctx,						    chset, CH_UNIX, 						    ndr->data+ndr->offset, 						    len3, &as, False);			if (ret == -1) {				return ndr_pull_error(ndr, NDR_ERR_CHARCNV, 						      "Bad character conversion");			}		}		NDR_CHECK(ndr_pull_advance(ndr, len3));		*s = as;		break;	case LIBNDR_FLAG_STR_NULLTERM:		if (byte_mul == 1) {			len1 = ascii_len_n((const char *)(ndr->data+ndr->offset), ndr->data_size - ndr->offset);		} else {			len1 = utf16_len_n(ndr->data+ndr->offset, ndr->data_size - ndr->offset);		}		ret = convert_string_talloc(ndr->current_mem_ctx,					    chset, CH_UNIX, 					    ndr->data+ndr->offset, 					    len1, &as, False);		if (ret == -1) {			return ndr_pull_error(ndr, NDR_ERR_CHARCNV, 					      "Bad character conversion");		}		NDR_CHECK(ndr_pull_advance(ndr, len1));		*s = as;		break;	case LIBNDR_FLAG_STR_FIXLEN15:	case LIBNDR_FLAG_STR_FIXLEN32:		len1 = (flags & LIBNDR_FLAG_STR_FIXLEN32)?32:15;		NDR_PULL_NEED_BYTES(ndr, len1*byte_mul);		ret = convert_string_talloc(ndr->current_mem_ctx,					    chset, CH_UNIX, 					    ndr->data+ndr->offset, 					    len1*byte_mul, &as, False);		if (ret == -1) {			return ndr_pull_error(ndr, NDR_ERR_CHARCNV, 					      "Bad character conversion");		}		NDR_CHECK(ndr_pull_advance(ndr, len1*byte_mul));		*s = as;		break;	default:		return ndr_pull_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",				      ndr->flags & LIBNDR_STRING_FLAGS);	}	return NT_STATUS_OK;}/**  push a general string onto the wire*/NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s){	ssize_t s_len, c_len, d_len;	charset_t chset = CH_UTF16LE;	unsigned flags = ndr->flags;	unsigned byte_mul = 2;	uint8_t *dest = NULL;	if (!(ndr_flags & NDR_SCALARS)) {		return NT_STATUS_OK;	}	if (NDR_BE(ndr)) {		chset = CH_UTF16BE;	}		s_len = s?strlen(s):0;	if (flags & LIBNDR_FLAG_STR_ASCII) {		chset = CH_DOS;		byte_mul = 1;		flags &= ~LIBNDR_FLAG_STR_ASCII;	}	if (flags & LIBNDR_FLAG_STR_UTF8) {		chset = CH_UTF8;		byte_mul = 1;		flags &= ~LIBNDR_FLAG_STR_UTF8;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -