diff options
Diffstat (limited to 'source3/rpc_parse/parse_prs.c')
-rw-r--r-- | source3/rpc_parse/parse_prs.c | 290 |
1 files changed, 290 insertions, 0 deletions
diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c new file mode 100644 index 0000000000..799bd1cc94 --- /dev/null +++ b/source3/rpc_parse/parse_prs.c @@ -0,0 +1,290 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + Samba memory buffer functions + Copyright (C) Andrew Tridgell 1992-1997 + Copyright (C) Luke Kenneth Casson Leighton 1996-1997 + + 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. +*/ + +extern int DEBUGLEVEL; + +#include "includes.h" + + +/******************************************************************* + debug output for parsing info. + + XXXX side-effect of this function is to increase the debug depth XXXX + + ********************************************************************/ +void prs_debug(prs_struct *ps, int depth, char *desc, char *fn_name) +{ + DEBUG(5+depth, ("%s%06x %s %s\n", tab_depth(depth), ps->offset, fn_name, desc)); +} + +/******************************************************************* + initialise a parse structure + ********************************************************************/ +void prs_init(prs_struct *ps, uint32 size, + uint8 align, uint32 margin, + BOOL io) +{ + ps->io = io; + ps->align = align; + ps->offset = 0; + + ps->data = NULL; + mem_buf_init(&(ps->data), margin); + + if (size != 0) + { + mem_alloc_data(ps->data, size); + ps->data->offset.start = 0; + ps->data->offset.end = 0xffffffff; + } +} + +/******************************************************************* + initialise a parse structure + ********************************************************************/ +void prs_mem_free(prs_struct *ps) +{ + mem_buf_free(&(ps->data)); +} + +/******************************************************************* + align a pointer to a multiple of align_offset bytes. looks like it + will work for offsets of 0, 2 and 4... + ********************************************************************/ +void prs_align(prs_struct *ps) +{ + int mod = ps->offset & (ps->align-1); + if (ps->align != 0 && mod != 0) + { + ps->offset += ps->align - mod; + } +} + +/******************************************************************* + attempt, if appropriate, to grow a data buffer. + + depends on the data stream mode (io) + ********************************************************************/ +BOOL prs_grow(prs_struct *ps) +{ + return mem_grow_data(&(ps->data), ps->io, ps->offset); +} + + +/******************************************************************* + stream a uint8 + ********************************************************************/ +BOOL prs_uint8(char *name, prs_struct *ps, int depth, uint8 *data8) +{ + char *q = mem_data(&(ps->data), ps->offset); + if (q == NULL) return False; + + DBG_RW_CVAL(name, depth, ps->offset, ps->io, q, *data8) + ps->offset += 1; + + return True; +} + +/******************************************************************* + stream a uint16 + ********************************************************************/ +BOOL prs_uint16(char *name, prs_struct *ps, int depth, uint16 *data16) +{ + char *q = mem_data(&(ps->data), ps->offset); + if (q == NULL) return False; + + DBG_RW_SVAL(name, depth, ps->offset, ps->io, q, *data16) + ps->offset += 2; + + return True; +} + +/******************************************************************* + stream a uint32 + ********************************************************************/ +BOOL prs_uint32(char *name, prs_struct *ps, int depth, uint32 *data32) +{ + char *q = mem_data(&(ps->data), ps->offset); + if (q == NULL) return False; + + DBG_RW_IVAL(name, depth, ps->offset, ps->io, q, *data32) + ps->offset += 4; + + return True; +} + + +/****************************************************************** + stream an array of uint8s. length is number of uint8s + ********************************************************************/ +BOOL prs_uint8s(BOOL charmode, char *name, prs_struct *ps, int depth, uint8 *data8s, int len) +{ + char *q = mem_data(&(ps->data), ps->offset); + if (q == NULL) return False; + + DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, data8s, len) + ps->offset += len; + + return True; +} + +/****************************************************************** + stream an array of uint16s. length is number of uint16s + ********************************************************************/ +BOOL prs_uint16s(BOOL charmode, char *name, prs_struct *ps, int depth, uint16 *data16s, int len) +{ + char *q = mem_data(&(ps->data), ps->offset); + if (q == NULL) return False; + + DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, data16s, len) + ps->offset += len * sizeof(uint16); + + return True; +} + +/****************************************************************** + stream an array of uint32s. length is number of uint32s + ********************************************************************/ +BOOL prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth, uint32 *data32s, int len) +{ + char *q = mem_data(&(ps->data), ps->offset); + if (q == NULL) return False; + + DBG_RW_PIVAL(charmode, name, depth, ps->offset, ps->io, q, data32s, len) + ps->offset += len * sizeof(uint32); + + return True; +} + +/****************************************************************** + stream a "not" unicode string, length/buffer specified separately, + in byte chars + ********************************************************************/ +BOOL prs_uninotstr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNINOTSTR2 *str) +{ + char *q = mem_data(&(ps->data), ps->offset); + if (q == NULL) return False; + + DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->uni_max_len) + ps->offset += str->uni_buf_len; + + return True; +} + +/****************************************************************** + stream a string, length/buffer specified separately, + in uint8 chars. + ********************************************************************/ +BOOL prs_string2(BOOL charmode, char *name, prs_struct *ps, int depth, STRING2 *str) +{ + char *q = mem_data(&(ps->data), ps->offset); + if (q == NULL) return False; + + DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->str_max_len) + ps->offset += str->str_str_len * sizeof(uint8); + + return True; +} + +/****************************************************************** + stream a unicode string, length/buffer specified separately, + in uint16 chars. + ********************************************************************/ +BOOL prs_unistr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNISTR2 *str) +{ + char *q = mem_data(&(ps->data), ps->offset); + if (q == NULL) return False; + + DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->uni_max_len) + ps->offset += str->uni_str_len * sizeof(uint16); + + return True; +} + +/******************************************************************* + stream a unicode null-terminated string + ********************************************************************/ +BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str) +{ + char *q = mem_data(&(ps->data), ps->offset); + int i = 0; + uint8 *start = (uint8*)q; + + if (q == NULL) return False; + + do + { + RW_SVAL(ps->io, q, str->buffer[i],0); + q += 2; + i++; + + } while ((i < sizeof(str->buffer) / sizeof(str->buffer[0])) && + (str->buffer[i] != 0)); + + ps->offset += i*2; + + dump_data(5+depth, start, ps->offset); + + return True; +} + +/******************************************************************* + stream a null-terminated string. len is strlen, and therefore does + not include the null-termination character. + + len == 0 indicates variable length string + (up to max size of pstring - 1024 chars). + + ********************************************************************/ +BOOL prs_string(char *name, prs_struct *ps, int depth, char *str, uint16 len) +{ + char *q = mem_data(&(ps->data), ps->offset); + uint8 *start = (uint8*)q; + int i = -1; /* start off at zero after 1st i++ */ + + if (q == NULL) return False; + + do + { + i++; + + if (i < len || len == 0) + { + RW_CVAL(ps->io, q, str[i],0); + } + else + { + uint8 dummy = 0; + RW_CVAL(ps->io, q, dummy,0); + } + + q++; + + } while (i < sizeof(pstring) && (len == 0 ? str[i] != 0 : i < len) ); + + ps->offset += i+1; + + dump_data(5+depth, start, ps->offset); + + return True; +} + |