parse_prs.c

来自「samba-3.0.22.tar.gz 编译smb服务器的源码」· C语言 代码 · 共 1,734 行 · 第 1/4 页

C
1,734
字号
	DEBUG(5,("\n"));	ps->data_offset += (len * sizeof(uint16));	return True;}/****************************************************************** Start using a function for streaming unicode chars. If unmarshalling, output must be little-endian, if marshalling, input must be little-endian. ********************************************************************/static void dbg_rw_punival(BOOL charmode, const char *name, int depth, prs_struct *ps,							char *in_buf, char *out_buf, int len){	int i;	if (UNMARSHALLING(ps)) {		if (ps->bigendian_data) {			for (i = 0; i < len; i++)				SSVAL(out_buf,2*i,RSVAL(in_buf, 2*i));		} else {			for (i = 0; i < len; i++)				SSVAL(out_buf, 2*i, SVAL(in_buf, 2*i));		}	} else {		if (ps->bigendian_data) {			for (i = 0; i < len; i++)				RSSVAL(in_buf, 2*i, SVAL(out_buf,2*i));		} else {			for (i = 0; i < len; i++)				SSVAL(in_buf, 2*i, SVAL(out_buf,2*i));		}	}	DEBUG(5,("%s%04x %s: ", tab_depth(depth), ps->data_offset, name));	if (charmode)		print_asc(5, (unsigned char*)out_buf, 2*len);	else {		for (i = 0; i < len; i++)			DEBUG(5,("%04x ", out_buf[i]));	}	DEBUG(5,("\n"));}/****************************************************************** Stream a unistr. Always little endian. ********************************************************************/BOOL prs_uint16uni(BOOL charmode, const char *name, prs_struct *ps, int depth, uint16 *data16s, int len){	char *q = prs_mem_get(ps, len * sizeof(uint16));	if (q == NULL)		return False;	dbg_rw_punival(charmode, name, depth, ps, q, (char *)data16s, len);	ps->data_offset += (len * sizeof(uint16));	return True;}/****************************************************************** Stream an array of uint32s. Length is number of uint32s. ********************************************************************/BOOL prs_uint32s(BOOL charmode, const char *name, prs_struct *ps, int depth, uint32 *data32s, int len){	int i;	char *q = prs_mem_get(ps, len * sizeof(uint32));	if (q == NULL)		return False;	if (UNMARSHALLING(ps)) {		if (ps->bigendian_data) {			for (i = 0; i < len; i++)				data32s[i] = RIVAL(q, 4*i);		} else {			for (i = 0; i < len; i++)				data32s[i] = IVAL(q, 4*i);		}	} else {		if (ps->bigendian_data) {			for (i = 0; i < len; i++)				RSIVAL(q, 4*i, data32s[i]);		} else {			for (i = 0; i < len; i++)				SIVAL(q, 4*i, data32s[i]);		}	}	DEBUG(5,("%s%04x %s: ", tab_depth(depth), ps->data_offset, name));	if (charmode)		print_asc(5, (unsigned char*)data32s, 4*len);	else {		for (i = 0; i < len; i++)			DEBUG(5,("%08x ", data32s[i]));	}	DEBUG(5,("\n"));	ps->data_offset += (len * sizeof(uint32));	return True;}/****************************************************************** Stream an array of unicode string, length/buffer specified separately, in uint16 chars. The unicode string is already in little-endian format. ********************************************************************/BOOL prs_buffer5(BOOL charmode, const char *name, prs_struct *ps, int depth, BUFFER5 *str){	char *p;	char *q = prs_mem_get(ps, str->buf_len * sizeof(uint16));	if (q == NULL)		return False;	if (UNMARSHALLING(ps)) {		str->buffer = PRS_ALLOC_MEM(ps,uint16,str->buf_len);		if (str->buffer == NULL)			return False;	}	/* If the string is empty, we don't have anything to stream */	if (str->buf_len==0)		return True;	p = (char *)str->buffer;	dbg_rw_punival(charmode, name, depth, ps, q, p, str->buf_len);		ps->data_offset += (str->buf_len * sizeof(uint16));	return True;}/****************************************************************** Stream a "not" unicode string, length/buffer specified separately, in byte chars. String is in little-endian format. ********************************************************************/BOOL prs_regval_buffer(BOOL charmode, const char *name, prs_struct *ps, int depth, REGVAL_BUFFER *buf){	char *p;	char *q = prs_mem_get(ps, buf->buf_len);	if (q == NULL)		return False;	if (UNMARSHALLING(ps)) {		if (buf->buf_len > buf->buf_max_len) {			return False;		}		if ( buf->buf_max_len ) {			buf->buffer = PRS_ALLOC_MEM(ps, uint16, buf->buf_max_len);			if ( buf->buffer == NULL )				return False;		}	}	p = (char *)buf->buffer;	dbg_rw_punival(charmode, name, depth, ps, q, p, buf->buf_len/2);	ps->data_offset += buf->buf_len;	return True;}/****************************************************************** Stream a string, length/buffer specified separately, in uint8 chars. ********************************************************************/BOOL prs_string2(BOOL charmode, const char *name, prs_struct *ps, int depth, STRING2 *str){	unsigned int i;	char *q = prs_mem_get(ps, str->str_str_len);	if (q == NULL)		return False;	if (UNMARSHALLING(ps)) {		if (str->str_str_len > str->str_max_len) {			return False;		}		str->buffer = PRS_ALLOC_MEM(ps,unsigned char, str->str_max_len);		if (str->buffer == NULL)			return False;	}	if (UNMARSHALLING(ps)) {		for (i = 0; i < str->str_str_len; i++)			str->buffer[i] = CVAL(q,i);	} else {		for (i = 0; i < str->str_str_len; i++)			SCVAL(q, i, str->buffer[i]);	}	DEBUG(5,("%s%04x %s: ", tab_depth(depth), ps->data_offset, name));	if (charmode)		print_asc(5, (unsigned char*)str->buffer, str->str_str_len);	else {		for (i = 0; i < str->str_str_len; i++)			DEBUG(5,("%02x ", str->buffer[i]));	}	DEBUG(5,("\n"));	ps->data_offset += str->str_str_len;	return True;}/****************************************************************** Stream a unicode string, length/buffer specified separately, in uint16 chars. The unicode string is already in little-endian format. ********************************************************************/BOOL prs_unistr2(BOOL charmode, const char *name, prs_struct *ps, int depth, UNISTR2 *str){	char *p;	char *q = prs_mem_get(ps, str->uni_str_len * sizeof(uint16));	if (q == NULL)		return False;	/* If the string is empty, we don't have anything to stream */	if (str->uni_str_len==0)		return True;	if (UNMARSHALLING(ps)) {		if (str->uni_str_len > str->uni_max_len) {			return False;		}		str->buffer = PRS_ALLOC_MEM(ps,uint16,str->uni_max_len);		if (str->buffer == NULL)			return False;	}	p = (char *)str->buffer;	dbg_rw_punival(charmode, name, depth, ps, q, p, str->uni_str_len);		ps->data_offset += (str->uni_str_len * sizeof(uint16));	return True;}/****************************************************************** Stream a unicode string, length/buffer specified separately, in uint16 chars. The unicode string is already in little-endian format. ********************************************************************/BOOL prs_unistr3(BOOL charmode, const char *name, UNISTR3 *str, prs_struct *ps, int depth){	char *p;	char *q = prs_mem_get(ps, str->uni_str_len * sizeof(uint16));	if (q == NULL)		return False;	if (UNMARSHALLING(ps)) {		str->str.buffer = PRS_ALLOC_MEM(ps,uint16,str->uni_str_len);		if (str->str.buffer == NULL)			return False;	}	p = (char *)str->str.buffer;	dbg_rw_punival(charmode, name, depth, ps, q, p, str->uni_str_len);	ps->data_offset += (str->uni_str_len * sizeof(uint16));	return True;}/******************************************************************* Stream a unicode  null-terminated string. As the string is already in little-endian format then do it as a stream of bytes. ********************************************************************/BOOL prs_unistr(const char *name, prs_struct *ps, int depth, UNISTR *str){	unsigned int len = 0;	unsigned char *p = (unsigned char *)str->buffer;	uint8 *start;	char *q;	uint32 max_len;	uint16* ptr;	if (MARSHALLING(ps)) {		for(len = 0; str->buffer[len] != 0; len++)			;		q = prs_mem_get(ps, (len+1)*2);		if (q == NULL)			return False;		start = (uint8*)q;		for(len = 0; str->buffer[len] != 0; len++) {			if(ps->bigendian_data) {				/* swap bytes - p is little endian, q is big endian. */				q[0] = (char)p[1];				q[1] = (char)p[0];				p += 2;				q += 2;			} 			else 			{				q[0] = (char)p[0];				q[1] = (char)p[1];				p += 2;				q += 2;			}		}		/*		 * even if the string is 'empty' (only an \0 char)		 * at this point the leading \0 hasn't been parsed.		 * so parse it now		 */		q[0] = 0;		q[1] = 0;		q += 2;		len++;		DEBUG(5,("%s%04x %s: ", tab_depth(depth), ps->data_offset, name));		print_asc(5, (unsigned char*)start, 2*len);			DEBUG(5, ("\n"));	}	else { /* unmarshalling */			uint32 alloc_len = 0;		q = ps->data_p + prs_offset(ps);		/*		 * Work out how much space we need and talloc it.		 */		max_len = (ps->buffer_size - ps->data_offset)/sizeof(uint16);		/* the test of the value of *ptr helps to catch the circumstance		   where we have an emtpty (non-existent) string in the buffer */		for ( ptr = (uint16 *)q; *ptr++ && (alloc_len <= max_len); alloc_len++)			/* do nothing */ 			;		if (alloc_len < max_len)			alloc_len += 1;		/* should we allocate anything at all? */		str->buffer = PRS_ALLOC_MEM(ps,uint16,alloc_len);		if ((str->buffer == NULL) && (alloc_len > 0))			return False;		p = (unsigned char *)str->buffer;		len = 0;		/* the (len < alloc_len) test is to prevent us from overwriting		   memory that is not ours...if we get that far, we have a non-null		   terminated string in the buffer and have messed up somewhere */		while ((len < alloc_len) && (*(uint16 *)q != 0)) {			if(ps->bigendian_data) 			{				/* swap bytes - q is big endian, p is little endian. */				p[0] = (unsigned char)q[1];				p[1] = (unsigned char)q[0];				p += 2;				q += 2;			} else {				p[0] = (unsigned char)q[0];				p[1] = (unsigned char)q[1];				p += 2;				q += 2;			}			len++;		} 		if (len < alloc_len) {			/* NULL terminate the UNISTR */			str->buffer[len++] = '\0';		}		DEBUG(5,("%s%04x %s: ", tab_depth(depth), ps->data_offset, name));		print_asc(5, (unsigned char*)str->buffer, 2*len);			DEBUG(5, ("\n"));	}	/* set the offset in the prs_struct; 'len' points to the	   terminiating NULL in the UNISTR so we need to go one more	   uint16 */	ps->data_offset += (len)*2;		return True;}/******************************************************************* Stream a null-terminated string.  len is strlen, and therefore does not include the null-termination character. ********************************************************************/BOOL prs_string(const char *name, prs_struct *ps, int depth, char *str, int max_buf_size){	char *q;	int i;	int len;	if (UNMARSHALLING(ps))		len = strlen(&ps->data_p[ps->data_offset]);	else		len = strlen(str);	len = MIN(len, (max_buf_size-1));	q = prs_mem_get(ps, len+1);	if (q == NULL)		return False;	for(i = 0; i < len; i++) {		if (UNMARSHALLING(ps))			str[i] = q[i];		else			q[i] = str[i];	}	/* The terminating null. */	str[i] = '\0';	if (MARSHALLING(ps)) {		q[i] = '\0';	}	ps->data_offset += len+1;	dump_data(5+depth, q, len);

⌨️ 快捷键说明

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