dce/rpc
[samba.git] / source3 / rpc_parse / parse_prs.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Samba memory buffer functions
5    Copyright (C) Andrew Tridgell              1992-1997
6    Copyright (C) Luke Kenneth Casson Leighton 1996-1997
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 extern int DEBUGLEVEL;
24
25 #include "includes.h"
26
27
28 /*******************************************************************
29  debug output for parsing info.
30
31  XXXX side-effect of this function is to increase the debug depth XXXX
32
33  ********************************************************************/
34 void prs_debug(prs_struct *ps, int depth, char *desc, char *fn_name)
35 {
36         DEBUG(5+depth, ("%s%06x %s %s\n", tab_depth(depth), ps->offset, fn_name, desc));
37 }
38
39 /*******************************************************************
40  initialise a parse structure
41  ********************************************************************/
42 void prs_init(prs_struct *ps, uint32 size,
43                                 uint8 align, uint32 margin,
44                                 BOOL io)
45 {
46         ps->io = io;
47         ps->align = align;
48         ps->offset = 0;
49
50         ps->data = NULL;
51         mem_buf_init(&(ps->data), margin);
52
53         if (size != 0)
54         {
55                 mem_alloc_data(ps->data, size);
56                 ps->data->offset.start = 0;
57                 ps->data->offset.end   = 0xffffffff;
58         }
59 }
60
61 /*******************************************************************
62  initialise a parse structure
63  ********************************************************************/
64 void prs_mem_free(prs_struct *ps)
65 {
66         mem_buf_free(&(ps->data));
67 }
68
69 /*******************************************************************
70  link one parsing structure to another
71  ********************************************************************/
72 void prs_link(prs_struct *prev, prs_struct *ps, prs_struct *next)
73 {
74         ps->data->offset.start = prev != NULL ? prev->data->offset.end : 0;
75         ps->data->offset.end   = ps->data->offset.start + ps->offset;
76         ps->data->next         = next != NULL ? next->data : NULL;
77 }
78
79 /*******************************************************************
80  align a pointer to a multiple of align_offset bytes.  looks like it
81  will work for offsets of 0, 2 and 4...
82  ********************************************************************/
83 void prs_align(prs_struct *ps)
84 {
85         int mod = ps->offset & (ps->align-1);
86         if (ps->align != 0 && mod != 0)
87         {
88                 ps->offset += ps->align - mod;
89         }
90 }
91
92 /*******************************************************************
93  attempt, if appropriate, to grow a data buffer.
94
95  depends on the data stream mode (io)
96  ********************************************************************/
97 BOOL prs_grow(prs_struct *ps)
98 {
99         return mem_grow_data(&(ps->data), ps->io, ps->offset, False);
100 }
101
102
103 /*******************************************************************
104  stream a uint8
105  ********************************************************************/
106 BOOL prs_uint8(char *name, prs_struct *ps, int depth, uint8 *data8)
107 {
108         char *q = mem_data(&(ps->data), ps->offset);
109         if (q == NULL) return False;
110
111         DBG_RW_CVAL(name, depth, ps->offset, ps->io, q, *data8)
112         ps->offset += 1;
113
114         return True;
115 }
116
117 /*******************************************************************
118  stream a uint16
119  ********************************************************************/
120 BOOL prs_uint16(char *name, prs_struct *ps, int depth, uint16 *data16)
121 {
122         char *q = mem_data(&(ps->data), ps->offset);
123         if (q == NULL) return False;
124
125         DBG_RW_SVAL(name, depth, ps->offset, ps->io, q, *data16)
126         ps->offset += 2;
127
128         return True;
129 }
130
131 /*******************************************************************
132  stream a uint32
133  ********************************************************************/
134 BOOL prs_uint32(char *name, prs_struct *ps, int depth, uint32 *data32)
135 {
136         char *q = mem_data(&(ps->data), ps->offset);
137         if (q == NULL) return False;
138
139         DBG_RW_IVAL(name, depth, ps->offset, ps->io, q, *data32)
140         ps->offset += 4;
141
142         return True;
143 }
144
145
146 /******************************************************************
147  stream an array of uint8s.  length is number of uint8s
148  ********************************************************************/
149 BOOL prs_uint8s(BOOL charmode, char *name, prs_struct *ps, int depth, uint8 *data8s, int len)
150 {
151         char *q = mem_data(&(ps->data), ps->offset);
152         if (q == NULL) return False;
153
154         DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, data8s, len)
155         ps->offset += len;
156
157         return True;
158 }
159
160 /******************************************************************
161  stream an array of uint32s.  length is number of uint32s
162  ********************************************************************/
163 BOOL prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth, uint32 *data32s, int len)
164 {
165         char *q = mem_data(&(ps->data), ps->offset);
166         if (q == NULL) return False;
167
168         DBG_RW_PIVAL(charmode, name, depth, ps->offset, ps->io, q, data32s, len)
169         ps->offset += len * sizeof(uint32);
170
171         return True;
172 }
173
174 /******************************************************************
175  stream a "not" unicode string, length/buffer specified separately,
176  in byte chars
177  ********************************************************************/
178 BOOL prs_uninotstr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNINOTSTR2 *str)
179 {
180         char *q = mem_data(&(ps->data), ps->offset);
181         if (q == NULL) return False;
182
183         DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->uni_max_len)
184         ps->offset += str->uni_buf_len;
185
186         return True;
187 }
188
189 /******************************************************************
190  stream a string, length/buffer specified separately,
191  in uint8 chars.
192  ********************************************************************/
193 BOOL prs_string2(BOOL charmode, char *name, prs_struct *ps, int depth, STRING2 *str)
194 {
195         char *q = mem_data(&(ps->data), ps->offset);
196         if (q == NULL) return False;
197
198         DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->str_max_len)
199         ps->offset += str->str_str_len * sizeof(uint8);
200
201         return True;
202 }
203
204 /******************************************************************
205  stream a unicode string, length/buffer specified separately,
206  in uint16 chars.
207  ********************************************************************/
208 BOOL prs_unistr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNISTR2 *str)
209 {
210         char *q = mem_data(&(ps->data), ps->offset);
211         if (q == NULL) return False;
212
213         DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->uni_max_len)
214         ps->offset += str->uni_str_len * sizeof(uint16);
215
216         return True;
217 }
218
219 /*******************************************************************
220  stream a unicode  null-terminated string
221  ********************************************************************/
222 BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str)
223 {
224         char *q = mem_data(&(ps->data), ps->offset);
225         int i = 0;
226         uint8 *start = (uint8*)q;
227
228         if (q == NULL) return False;
229
230         do 
231         {
232                 RW_SVAL(ps->io, q, str->buffer[i],0);
233                 q += 2;
234                 i++;
235
236         } while ((i < sizeof(str->buffer) / sizeof(str->buffer[0])) &&
237                      (str->buffer[i] != 0));
238
239         ps->offset += i*2;
240
241         dump_data(5+depth, (char *)start, i * 2);
242
243         return True;
244 }
245
246 /*******************************************************************
247  stream a null-terminated string.  len is strlen, and therefore does
248  not include the null-termination character.
249
250  len == 0 indicates variable length string
251  (up to max size of pstring - 1024 chars).
252
253  ********************************************************************/
254 BOOL prs_string(char *name, prs_struct *ps, int depth, char *str, uint16 len, uint16 max_buf_size)
255 {
256         char *q = mem_data(&(ps->data), ps->offset);
257         uint8 *start = (uint8*)q;
258         int i = -1; /* start off at zero after 1st i++ */
259
260         if (q == NULL) return False;
261
262         do
263         {
264                 i++;
265
266                 if (i < len || len == 0)
267                 {
268                         RW_CVAL(ps->io, q, str[i],0);
269                 }
270                 else
271                 {
272                         uint8 dummy = 0;
273                         RW_CVAL(ps->io, q, dummy,0);
274                 }
275
276                 q++;
277
278         } while (i < max_buf_size && (len == 0 ? str[i] != 0 : i < len) );
279
280         ps->offset += i+1;
281
282         dump_data(5+depth, (char *)start, i);
283
284         return True;
285 }
286