2 Unix SMB/Netbios implementation.
4 Samba memory buffer functions
5 Copyright (C) Andrew Tridgell 1992-1999
6 Copyright (C) Luke Kenneth Casson Leighton 1996-1999
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 debug a parse structure
41 ********************************************************************/
42 void prs_debug_out(prs_struct *ps, int level)
44 DEBUG(level,("ps: io %s align %d offset %d err %d data %p len %d\n",
45 BOOLSTR(ps->io), ps->align, ps->offset, ps->error, ps->data,
46 ps->data != NULL ? mem_buf_len(ps->data) : 0));
49 /*******************************************************************
50 initialise a parse structure
51 ********************************************************************/
52 void prs_init(prs_struct *ps, uint32 size,
53 uint8 align, uint32 margin,
62 mem_buf_init(&(ps->data), margin);
66 mem_alloc_data(ps->data, size);
67 ps->data->offset.start = 0;
68 ps->data->offset.end = 0xffffffff;
72 /*******************************************************************
73 initialise a parse structure
74 ********************************************************************/
75 void prs_mem_free(prs_struct *ps)
77 mem_buf_free(&(ps->data));
80 /*******************************************************************
81 link one parsing structure to another
82 ********************************************************************/
83 void prs_link(prs_struct *prev, prs_struct *ps, prs_struct *next)
85 ps->data->offset.start = prev != NULL ? prev->data->offset.end : 0;
86 ps->data->offset.end = ps->data->offset.start + ps->offset;
87 ps->data->next = next != NULL ? next->data : NULL;
90 /*******************************************************************
91 align a pointer to a multiple of align_offset bytes. looks like it
92 will work for offsets of 0, 2 and 4...
93 ********************************************************************/
94 void prs_align(prs_struct *ps)
97 if (ps->error) return;
98 mod = ps->offset & (ps->align-1);
99 if (ps->align != 0 && mod != 0)
101 ps->offset += ps->align - mod;
105 /*******************************************************************
106 attempt, if appropriate, to grow a data buffer.
108 depends on the data stream mode (io)
109 ********************************************************************/
110 BOOL prs_grow(prs_struct *ps)
112 if (ps->error) return False;
113 return mem_grow_data(&(ps->data), ps->io, ps->offset, False);
117 /*******************************************************************
119 ********************************************************************/
120 BOOL _prs_uint8(char *name, prs_struct *ps, int depth, uint8 *data8)
123 if (ps->error) return False;
124 q = mem_data(&(ps->data), ps->offset);
131 DBG_RW_CVAL(name, depth, ps->offset, ps->io, q, *data8)
137 /*******************************************************************
139 ********************************************************************/
140 BOOL _prs_uint16(char *name, prs_struct *ps, int depth, uint16 *data16)
143 if (ps->error) return False;
144 q = mem_data(&(ps->data), ps->offset);
151 DBG_RW_SVAL(name, depth, ps->offset, ps->io, q, *data16)
157 /*******************************************************************
159 ********************************************************************/
160 BOOL _prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16])
163 if (ps->error) return False;
164 q = mem_data(&(ps->data), ps->offset);
171 #ifdef DEBUG_PASSWORD
172 DEBUG(100,("prs_hash1\n"));
173 dump_data(100, sess_key, 16);
174 dump_data(100, q, 68);
176 SamOEMhash((uchar*)q, sess_key, 2);
177 #ifdef DEBUG_PASSWORD
178 dump_data(100, q, 68);
184 /*******************************************************************
186 ********************************************************************/
187 BOOL _prs_uint32(char *name, prs_struct *ps, int depth, uint32 *data32)
190 if (ps->error) return False;
191 q = mem_data(&(ps->data), ps->offset);
198 DBG_RW_IVAL(name, depth, ps->offset, ps->io, q, *data32)
205 /******************************************************************
206 stream an array of uint8s. length is number of uint8s
207 ********************************************************************/
208 BOOL _prs_uint8s(BOOL charmode, char *name, prs_struct *ps, int depth, uint8 *data8s, int len)
213 if (ps->error) return False;
214 q = mem_data(&(ps->data), ps->offset);
215 end_offset = ps->offset + len * sizeof(uint8);
216 e = mem_data(&(ps->data), end_offset-1);
218 if (q == NULL || e == NULL)
224 DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, data8s, len)
225 ps->offset = end_offset;
230 /******************************************************************
231 stream an array of uint16s. length is number of uint16s
232 ********************************************************************/
233 BOOL _prs_uint16s(BOOL charmode, char *name, prs_struct *ps, int depth, uint16 *data16s, int len)
238 if (ps->error) return False;
239 q = mem_data(&(ps->data), ps->offset);
240 end_offset = ps->offset + len * sizeof(uint16);
241 e = mem_data(&(ps->data), end_offset-1);
243 if (q == NULL || e == NULL)
249 DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, data16s, len)
250 ps->offset = end_offset;
255 /******************************************************************
256 stream an array of uint32s. length is number of uint32s
257 ********************************************************************/
258 BOOL _prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth, uint32 *data32s, int len)
263 if (ps->error) return False;
264 q = mem_data(&(ps->data), ps->offset);
265 end_offset = ps->offset + len * sizeof(uint32);
266 e = mem_data(&(ps->data), end_offset-1);
268 if (q == NULL || e == NULL)
274 DBG_RW_PIVAL(charmode, name, depth, ps->offset, ps->io, q, data32s, len)
275 ps->offset = end_offset;
280 /******************************************************************
281 stream a "not" unicode string, length/buffer specified separately,
283 ********************************************************************/
284 BOOL _prs_buffer2(BOOL charmode, char *name, prs_struct *ps, int depth, BUFFER2 *str)
289 if (ps->error) return False;
290 q = mem_data(&(ps->data), ps->offset);
291 end_offset = ps->offset + str->buf_len;
292 e = mem_data(&(ps->data), end_offset-1);
294 if (q == NULL || e == NULL)
300 DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->buf_len)
301 ps->offset = end_offset;
306 /******************************************************************
307 stream a string, length/buffer specified separately,
309 ********************************************************************/
310 BOOL _prs_string2(BOOL charmode, char *name, prs_struct *ps, int depth, STRING2 *str)
315 if (ps->error) return False;
316 q = mem_data(&(ps->data), ps->offset);
317 end_offset = ps->offset + str->str_str_len * sizeof(uint8);
318 e = mem_data(&(ps->data), end_offset-1);
320 if (q == NULL || e == NULL)
326 DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->str_max_len)
327 ps->offset = end_offset;
332 /******************************************************************
333 stream a unicode string, length/buffer specified separately,
335 ********************************************************************/
336 BOOL _prs_unistr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNISTR2 *str)
341 if (ps->error) return False;
342 q = mem_data(&(ps->data), ps->offset);
343 end_offset = ps->offset + str->uni_str_len * sizeof(uint16);
344 e = mem_data(&(ps->data), end_offset-1);
346 if (q == NULL || e == NULL)
352 DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->uni_str_len)
353 ps->offset = end_offset;
358 /******************************************************************
359 stream a unicode string, length/buffer specified separately,
361 ********************************************************************/
362 BOOL _prs_unistr3(BOOL charmode, char *name, UNISTR3 *str, prs_struct *ps, int depth)
367 if (ps->error) return False;
368 q = mem_data(&(ps->data), ps->offset);
369 end_offset = ps->offset + str->uni_str_len * sizeof(uint16);
370 e = mem_data(&(ps->data), end_offset-1);
372 if (q == NULL || e == NULL)
378 DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, str->str.buffer, str->uni_str_len)
379 ps->offset = end_offset;
384 /*******************************************************************
385 stream a unicode null-terminated string
386 ********************************************************************/
387 BOOL _prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str)
391 if (ps->error) return False;
392 start = (uint8*)mem_data(&(ps->data), ps->offset);
398 q = mem_data(&(ps->data), ps->offset + i*2);
404 RW_SVAL(ps->io, q, str->buffer[i],0);
406 while ((((size_t)i) < sizeof(str->buffer) / sizeof(str->buffer[0])) &&
407 (str->buffer[i] != 0));
410 ps->offset += (i+1)*2;
412 dump_data(5+depth, (char *)start, i * 2);
417 /*******************************************************************
418 stream a null-terminated string. len is strlen, and therefore does
419 not include the null-termination character.
421 len == 0 indicates variable length string
422 (up to max size of pstring - 1024 chars).
424 ********************************************************************/
425 BOOL _prs_string(char *name, prs_struct *ps, int depth, char *str, uint16 len, uint16 max_buf_size)
427 int i = -1; /* start off at zero after 1st i++ */
429 if (ps->error) return False;
430 start = (uint8*)mem_data(&(ps->data), ps->offset);
437 q = mem_data(&(ps->data), ps->offset + i);
444 if (i < len || len == 0)
446 RW_CVAL(ps->io, q, str[i],0);
451 RW_CVAL(ps->io, q, dummy,0);
454 } while (i < max_buf_size && (len == 0 ? str[i] != 0 : i < len) );
458 dump_data(5+depth, (char *)start, i);
463 /*******************************************************************
464 prs_uint16 wrapper. call this and it sets up a pointer to where the
465 uint16 should be stored, or gets the size if reading
466 ********************************************************************/
467 BOOL _prs_uint16_pre(char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset)
469 if (ps->error) return False;
470 (*offset) = ps->offset;
474 return _prs_uint16(name, ps, depth, data16);
478 ps->offset += sizeof(uint16);
483 /*******************************************************************
484 prs_uint16 wrapper. call this and it retrospectively stores the size.
485 does nothing on reading, as that is already handled by ...._pre()
486 ********************************************************************/
487 BOOL _prs_uint16_post(char *name, prs_struct *ps, int depth, uint16 *data16,
488 uint32 ptr_uint16, uint32 start_offset)
490 if (ps->error) return False;
493 /* storing: go back and do a retrospective job. i hate this */
494 uint16 data_size = ps->offset - start_offset;
495 uint32 old_offset = ps->offset;
497 ps->offset = ptr_uint16;
498 prs_uint16(name, ps, depth, &data_size);
499 ps->offset = old_offset;
503 ps->offset = start_offset + (*data16);
508 /*******************************************************************
509 prs_uint32 wrapper. call this and it sets up a pointer to where the
510 uint32 should be stored, or gets the size if reading
511 ********************************************************************/
512 BOOL _prs_uint32_pre(char *name, prs_struct *ps, int depth, uint32 *data32, uint32 *offset)
514 if (ps->error) return False;
515 (*offset) = ps->offset;
519 return _prs_uint32(name, ps, depth, data32);
523 ps->offset += sizeof(uint32);
528 /*******************************************************************
529 prs_uint32 wrapper. call this and it retrospectively stores the size.
530 does nothing on reading, as that is already handled by ...._pre()
531 ********************************************************************/
532 BOOL _prs_uint32_post(char *name, prs_struct *ps, int depth, uint32 *data32,
533 uint32 ptr_uint32, uint32 data_size)
535 if (ps->error) return False;
538 /* storing: go back and do a retrospective job. i hate this */
539 uint32 old_offset = ps->offset;
540 ps->offset = ptr_uint32;
541 prs_uint32(name, ps, depth, &data_size);
542 ps->offset = old_offset;