2 Unix SMB/Netbios implementation.
4 Samba memory buffer functions
5 Copyright (C) Andrew Tridgell 1992-1997
6 Copyright (C) Luke Kenneth Casson Leighton 1996-1997
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.
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.
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.
23 extern int DEBUGLEVEL;
28 /*******************************************************************
29 debug output for parsing info.
31 XXXX side-effect of this function is to increase the debug depth XXXX
33 ********************************************************************/
34 void prs_debug(prs_struct *ps, int depth, char *desc, char *fn_name)
36 DEBUG(5+depth, ("%s%06x %s %s\n", tab_depth(depth), ps->offset, fn_name, desc));
39 /*******************************************************************
40 initialise a parse structure
41 ********************************************************************/
42 void prs_init(prs_struct *ps, uint32 size,
43 uint8 align, uint32 margin,
51 mem_buf_init(&(ps->data), margin);
55 mem_alloc_data(ps->data, size);
56 ps->data->offset.start = 0;
57 ps->data->offset.end = 0xffffffff;
61 /*******************************************************************
62 initialise a parse structure
63 ********************************************************************/
64 void prs_mem_free(prs_struct *ps)
66 mem_buf_free(&(ps->data));
69 /*******************************************************************
70 link one parsing structure to another
71 ********************************************************************/
72 void prs_link(prs_struct *prev, prs_struct *ps, prs_struct *next)
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;
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)
85 int mod = ps->offset & (ps->align-1);
86 if (ps->align != 0 && mod != 0)
88 ps->offset += ps->align - mod;
92 /*******************************************************************
93 attempt, if appropriate, to grow a data buffer.
95 depends on the data stream mode (io)
96 ********************************************************************/
97 BOOL prs_grow(prs_struct *ps)
99 return mem_grow_data(&(ps->data), ps->io, ps->offset, False);
103 /*******************************************************************
105 ********************************************************************/
106 BOOL prs_uint8(char *name, prs_struct *ps, int depth, uint8 *data8)
108 char *q = mem_data(&(ps->data), ps->offset);
109 if (q == NULL) return False;
111 DBG_RW_CVAL(name, depth, ps->offset, ps->io, q, *data8)
117 /*******************************************************************
119 ********************************************************************/
120 BOOL prs_uint16(char *name, prs_struct *ps, int depth, uint16 *data16)
122 char *q = mem_data(&(ps->data), ps->offset);
123 if (q == NULL) return False;
125 DBG_RW_SVAL(name, depth, ps->offset, ps->io, q, *data16)
131 /*******************************************************************
133 ********************************************************************/
134 BOOL prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16])
136 char *q = mem_data(&(ps->data), offset);
137 if (q == NULL) return False;
139 #ifdef DEBUG_PASSWORD
140 DEBUG(100,("prs_hash1\n"));
141 dump_data(100, sess_key, 16);
142 dump_data(100, q, 68);
144 SamOEMhash(q, sess_key, 2);
145 #ifdef DEBUG_PASSWORD
146 dump_data(100, q, 68);
152 /*******************************************************************
154 ********************************************************************/
155 BOOL prs_uint32(char *name, prs_struct *ps, int depth, uint32 *data32)
157 char *q = mem_data(&(ps->data), ps->offset);
158 if (q == NULL) return False;
160 DBG_RW_IVAL(name, depth, ps->offset, ps->io, q, *data32)
167 /******************************************************************
168 stream an array of uint8s. length is number of uint8s
169 ********************************************************************/
170 BOOL prs_uint8s(BOOL charmode, char *name, prs_struct *ps, int depth, uint8 *data8s, int len)
172 char *q = mem_data(&(ps->data), ps->offset);
173 int end_offset = ps->offset + len * sizeof(uint8);
174 char *e = mem_data(&(ps->data), end_offset-1);
176 if (q == NULL || e == NULL) return False;
178 DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, data8s, len)
179 ps->offset = end_offset;
184 /******************************************************************
185 stream an array of uint16s. length is number of uint16s
186 ********************************************************************/
187 BOOL prs_uint16s(BOOL charmode, char *name, prs_struct *ps, int depth, uint16 *data16s, int len)
189 char *q = mem_data(&(ps->data), ps->offset);
190 int end_offset = ps->offset + len * sizeof(uint16);
191 char *e = mem_data(&(ps->data), end_offset-1);
193 if (q == NULL || e == NULL) return False;
195 DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, data16s, len)
196 ps->offset = end_offset;
201 /******************************************************************
202 stream an array of uint32s. length is number of uint32s
203 ********************************************************************/
204 BOOL prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth, uint32 *data32s, int len)
206 char *q = mem_data(&(ps->data), ps->offset);
207 int end_offset = ps->offset + len * sizeof(uint32);
208 char *e = mem_data(&(ps->data), end_offset-1);
210 if (q == NULL || e == NULL) return False;
212 DBG_RW_PIVAL(charmode, name, depth, ps->offset, ps->io, q, data32s, len)
213 ps->offset = end_offset;
218 /******************************************************************
219 stream a "not" unicode string, length/buffer specified separately,
221 ********************************************************************/
222 BOOL prs_buffer2(BOOL charmode, char *name, prs_struct *ps, int depth, BUFFER2 *str)
224 char *q = mem_data(&(ps->data), ps->offset);
225 int end_offset = ps->offset + str->buf_len;
226 char *e = mem_data(&(ps->data), end_offset-1);
228 if (q == NULL || e == NULL) return False;
230 DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->buf_len)
231 ps->offset = end_offset;
236 /******************************************************************
237 stream a string, length/buffer specified separately,
239 ********************************************************************/
240 BOOL prs_string2(BOOL charmode, char *name, prs_struct *ps, int depth, STRING2 *str)
242 char *q = mem_data(&(ps->data), ps->offset);
243 int end_offset = ps->offset + str->str_str_len * sizeof(uint8);
244 char *e = mem_data(&(ps->data), end_offset-1);
246 if (q == NULL || e == NULL) return False;
248 DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->str_max_len)
249 ps->offset = end_offset;
254 /******************************************************************
255 stream a unicode string, length/buffer specified separately,
257 ********************************************************************/
258 BOOL prs_unistr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNISTR2 *str)
260 char *q = mem_data(&(ps->data), ps->offset);
261 int end_offset = ps->offset + str->uni_str_len * sizeof(uint16);
262 char *e = mem_data(&(ps->data), end_offset-1);
264 if (q == NULL || e == NULL) return False;
266 DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->uni_str_len)
267 ps->offset = end_offset;
272 /******************************************************************
273 stream a unicode string, length/buffer specified separately,
275 ********************************************************************/
276 BOOL prs_unistr3(BOOL charmode, char *name, UNISTR3 *str, prs_struct *ps, int depth)
278 char *q = mem_data(&(ps->data), ps->offset);
279 int end_offset = ps->offset + str->uni_str_len * sizeof(uint16);
280 char *e = mem_data(&(ps->data), end_offset-1);
282 if (q == NULL || e == NULL) return False;
284 DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, str->str.buffer, str->uni_str_len)
285 ps->offset = end_offset;
290 /*******************************************************************
291 stream a unicode null-terminated string
292 ********************************************************************/
293 BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str)
296 uint8 *start = (uint8*)mem_data(&(ps->data), ps->offset);
302 q = mem_data(&(ps->data), ps->offset + i*2);
303 if (q == NULL) return False;
304 RW_SVAL(ps->io, q, str->buffer[i],0);
306 while ((i < sizeof(str->buffer) / sizeof(str->buffer[0])) &&
307 (str->buffer[i] != 0));
310 ps->offset += (i+1)*2;
312 dump_data(5+depth, (char *)start, i * 2);
317 /*******************************************************************
318 stream a null-terminated string. len is strlen, and therefore does
319 not include the null-termination character.
321 len == 0 indicates variable length string
322 (up to max size of pstring - 1024 chars).
324 ********************************************************************/
325 BOOL prs_string(char *name, prs_struct *ps, int depth, char *str, uint16 len, uint16 max_buf_size)
327 uint8 *start = (uint8*)mem_data(&(ps->data), ps->offset);
328 int i = -1; /* start off at zero after 1st i++ */
335 q = mem_data(&(ps->data), ps->offset + i);
336 if (q == NULL) return False;
338 if (i < len || len == 0)
340 RW_CVAL(ps->io, q, str[i],0);
345 RW_CVAL(ps->io, q, dummy,0);
348 } while (i < max_buf_size && (len == 0 ? str[i] != 0 : i < len) );
352 dump_data(5+depth, (char *)start, i);
357 /*******************************************************************
358 prs_uint16 wrapper. call this and it sets up a pointer to where the
359 uint16 should be stored, or gets the size if reading
360 ********************************************************************/
361 BOOL prs_uint16_pre(char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset)
363 (*offset) = ps->offset;
367 return prs_uint16(name, ps, depth, data16);
371 ps->offset += sizeof(uint16);
376 /*******************************************************************
377 prs_uint16 wrapper. call this and it retrospectively stores the size.
378 does nothing on reading, as that is already handled by ...._pre()
379 ********************************************************************/
380 BOOL prs_uint16_post(char *name, prs_struct *ps, int depth, uint16 *data16,
381 uint32 ptr_uint16, uint32 start_offset)
385 /* storing: go back and do a retrospective job. i hate this */
386 uint16 data_size = ps->offset - start_offset;
387 uint32 old_offset = ps->offset;
389 ps->offset = ptr_uint16;
390 prs_uint16(name, ps, depth, &data_size);
391 ps->offset = old_offset;
395 ps->offset = start_offset + (*data16);
400 /*******************************************************************
401 prs_uint32 wrapper. call this and it sets up a pointer to where the
402 uint32 should be stored, or gets the size if reading
403 ********************************************************************/
404 BOOL prs_uint32_pre(char *name, prs_struct *ps, int depth, uint32 *data32, uint32 *offset)
406 (*offset) = ps->offset;
410 return prs_uint32(name, ps, depth, data32);
414 ps->offset += sizeof(uint32);
419 /*******************************************************************
420 prs_uint32 wrapper. call this and it retrospectively stores the size.
421 does nothing on reading, as that is already handled by ...._pre()
422 ********************************************************************/
423 BOOL prs_uint32_post(char *name, prs_struct *ps, int depth, uint32 *data32,
424 uint32 ptr_uint32, uint32 data_size)
428 /* storing: go back and do a retrospective job. i hate this */
429 uint32 old_offset = ps->offset;
430 ps->offset = ptr_uint32;
431 prs_uint32(name, ps, depth, &data_size);
432 ps->offset = old_offset;