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 initialise a parse structure
41 ********************************************************************/
42 void prs_init(prs_struct *ps, uint32 size,
43 uint8 align, uint32 margin,
52 mem_buf_init(&(ps->data), margin);
56 mem_alloc_data(ps->data, size);
57 ps->data->offset.start = 0;
58 ps->data->offset.end = 0xffffffff;
62 /*******************************************************************
63 initialise a parse structure
64 ********************************************************************/
65 void prs_mem_free(prs_struct *ps)
67 mem_buf_free(&(ps->data));
70 /*******************************************************************
71 link one parsing structure to another
72 ********************************************************************/
73 void prs_link(prs_struct *prev, prs_struct *ps, prs_struct *next)
75 ps->data->offset.start = prev != NULL ? prev->data->offset.end : 0;
76 ps->data->offset.end = ps->data->offset.start + ps->offset;
77 ps->data->next = next != NULL ? next->data : NULL;
80 /*******************************************************************
81 align a pointer to a multiple of align_offset bytes. looks like it
82 will work for offsets of 0, 2 and 4...
83 ********************************************************************/
84 void prs_align(prs_struct *ps)
87 if (ps->error) return;
88 mod = ps->offset & (ps->align-1);
89 if (ps->align != 0 && mod != 0)
91 ps->offset += ps->align - mod;
95 /*******************************************************************
96 attempt, if appropriate, to grow a data buffer.
98 depends on the data stream mode (io)
99 ********************************************************************/
100 BOOL prs_grow(prs_struct *ps)
102 if (ps->error) return False;
103 return mem_grow_data(&(ps->data), ps->io, ps->offset, False);
107 /*******************************************************************
109 ********************************************************************/
110 BOOL _prs_uint8(char *name, prs_struct *ps, int depth, uint8 *data8)
113 if (ps->error) return False;
114 q = mem_data(&(ps->data), ps->offset);
121 DBG_RW_CVAL(name, depth, ps->offset, ps->io, q, *data8)
127 /*******************************************************************
129 ********************************************************************/
130 BOOL _prs_uint16(char *name, prs_struct *ps, int depth, uint16 *data16)
133 if (ps->error) return False;
134 q = mem_data(&(ps->data), ps->offset);
141 DBG_RW_SVAL(name, depth, ps->offset, ps->io, q, *data16)
147 /*******************************************************************
149 ********************************************************************/
150 BOOL _prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16])
153 if (ps->error) return False;
154 q = mem_data(&(ps->data), ps->offset);
161 #ifdef DEBUG_PASSWORD
162 DEBUG(100,("prs_hash1\n"));
163 dump_data(100, sess_key, 16);
164 dump_data(100, q, 68);
166 SamOEMhash(q, sess_key, 2);
167 #ifdef DEBUG_PASSWORD
168 dump_data(100, q, 68);
174 /*******************************************************************
176 ********************************************************************/
177 BOOL _prs_uint32(char *name, prs_struct *ps, int depth, uint32 *data32)
180 if (ps->error) return False;
181 q = mem_data(&(ps->data), ps->offset);
188 DBG_RW_IVAL(name, depth, ps->offset, ps->io, q, *data32)
195 /******************************************************************
196 stream an array of uint8s. length is number of uint8s
197 ********************************************************************/
198 BOOL _prs_uint8s(BOOL charmode, char *name, prs_struct *ps, int depth, uint8 *data8s, int len)
203 if (ps->error) return False;
204 q = mem_data(&(ps->data), ps->offset);
205 end_offset = ps->offset + len * sizeof(uint8);
206 e = mem_data(&(ps->data), end_offset-1);
208 if (q == NULL || e == NULL)
214 DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, data8s, len)
215 ps->offset = end_offset;
220 /******************************************************************
221 stream an array of uint16s. length is number of uint16s
222 ********************************************************************/
223 BOOL _prs_uint16s(BOOL charmode, char *name, prs_struct *ps, int depth, uint16 *data16s, int len)
228 if (ps->error) return False;
229 q = mem_data(&(ps->data), ps->offset);
230 end_offset = ps->offset + len * sizeof(uint16);
231 e = mem_data(&(ps->data), end_offset-1);
233 if (q == NULL || e == NULL)
239 DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, data16s, len)
240 ps->offset = end_offset;
245 /******************************************************************
246 stream an array of uint32s. length is number of uint32s
247 ********************************************************************/
248 BOOL _prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth, uint32 *data32s, int len)
253 if (ps->error) return False;
254 q = mem_data(&(ps->data), ps->offset);
255 end_offset = ps->offset + len * sizeof(uint32);
256 e = mem_data(&(ps->data), end_offset-1);
258 if (q == NULL || e == NULL)
264 DBG_RW_PIVAL(charmode, name, depth, ps->offset, ps->io, q, data32s, len)
265 ps->offset = end_offset;
270 /******************************************************************
271 stream a "not" unicode string, length/buffer specified separately,
273 ********************************************************************/
274 BOOL _prs_buffer2(BOOL charmode, char *name, prs_struct *ps, int depth, BUFFER2 *str)
279 if (ps->error) return False;
280 q = mem_data(&(ps->data), ps->offset);
281 end_offset = ps->offset + str->buf_len;
282 e = mem_data(&(ps->data), end_offset-1);
284 if (q == NULL || e == NULL)
290 DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->buf_len)
291 ps->offset = end_offset;
296 /******************************************************************
297 stream a string, length/buffer specified separately,
299 ********************************************************************/
300 BOOL _prs_string2(BOOL charmode, char *name, prs_struct *ps, int depth, STRING2 *str)
305 if (ps->error) return False;
306 q = mem_data(&(ps->data), ps->offset);
307 end_offset = ps->offset + str->str_str_len * sizeof(uint8);
308 e = mem_data(&(ps->data), end_offset-1);
310 if (q == NULL || e == NULL)
316 DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->str_max_len)
317 ps->offset = end_offset;
322 /******************************************************************
323 stream a unicode string, length/buffer specified separately,
325 ********************************************************************/
326 BOOL _prs_unistr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNISTR2 *str)
331 if (ps->error) return False;
332 q = mem_data(&(ps->data), ps->offset);
333 end_offset = ps->offset + str->uni_str_len * sizeof(uint16);
334 e = mem_data(&(ps->data), end_offset-1);
336 if (q == NULL || e == NULL)
342 DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->uni_str_len)
343 ps->offset = end_offset;
348 /******************************************************************
349 stream a unicode string, length/buffer specified separately,
351 ********************************************************************/
352 BOOL _prs_unistr3(BOOL charmode, char *name, UNISTR3 *str, prs_struct *ps, int depth)
357 if (ps->error) return False;
358 q = mem_data(&(ps->data), ps->offset);
359 end_offset = ps->offset + str->uni_str_len * sizeof(uint16);
360 e = mem_data(&(ps->data), end_offset-1);
362 if (q == NULL || e == NULL)
368 DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, str->str.buffer, str->uni_str_len)
369 ps->offset = end_offset;
374 /*******************************************************************
375 stream a unicode null-terminated string
376 ********************************************************************/
377 BOOL _prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str)
381 if (ps->error) return False;
382 start = (uint8*)mem_data(&(ps->data), ps->offset);
388 q = mem_data(&(ps->data), ps->offset + i*2);
394 RW_SVAL(ps->io, q, str->buffer[i],0);
396 while ((i < sizeof(str->buffer) / sizeof(str->buffer[0])) &&
397 (str->buffer[i] != 0));
400 ps->offset += (i+1)*2;
402 dump_data(5+depth, (char *)start, i * 2);
407 /*******************************************************************
408 stream a null-terminated string. len is strlen, and therefore does
409 not include the null-termination character.
411 len == 0 indicates variable length string
412 (up to max size of pstring - 1024 chars).
414 ********************************************************************/
415 BOOL _prs_string(char *name, prs_struct *ps, int depth, char *str, uint16 len, uint16 max_buf_size)
417 int i = -1; /* start off at zero after 1st i++ */
419 if (ps->error) return False;
420 start = (uint8*)mem_data(&(ps->data), ps->offset);
427 q = mem_data(&(ps->data), ps->offset + i);
434 if (i < len || len == 0)
436 RW_CVAL(ps->io, q, str[i],0);
441 RW_CVAL(ps->io, q, dummy,0);
444 } while (i < max_buf_size && (len == 0 ? str[i] != 0 : i < len) );
448 dump_data(5+depth, (char *)start, i);
453 /*******************************************************************
454 prs_uint16 wrapper. call this and it sets up a pointer to where the
455 uint16 should be stored, or gets the size if reading
456 ********************************************************************/
457 BOOL _prs_uint16_pre(char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset)
459 if (ps->error) return False;
460 (*offset) = ps->offset;
464 return _prs_uint16(name, ps, depth, data16);
468 ps->offset += sizeof(uint16);
473 /*******************************************************************
474 prs_uint16 wrapper. call this and it retrospectively stores the size.
475 does nothing on reading, as that is already handled by ...._pre()
476 ********************************************************************/
477 BOOL _prs_uint16_post(char *name, prs_struct *ps, int depth, uint16 *data16,
478 uint32 ptr_uint16, uint32 start_offset)
480 if (ps->error) return False;
483 /* storing: go back and do a retrospective job. i hate this */
484 uint16 data_size = ps->offset - start_offset;
485 uint32 old_offset = ps->offset;
487 ps->offset = ptr_uint16;
488 prs_uint16(name, ps, depth, &data_size);
489 ps->offset = old_offset;
493 ps->offset = start_offset + (*data16);
498 /*******************************************************************
499 prs_uint32 wrapper. call this and it sets up a pointer to where the
500 uint32 should be stored, or gets the size if reading
501 ********************************************************************/
502 BOOL _prs_uint32_pre(char *name, prs_struct *ps, int depth, uint32 *data32, uint32 *offset)
504 if (ps->error) return False;
505 (*offset) = ps->offset;
509 return _prs_uint32(name, ps, depth, data32);
513 ps->offset += sizeof(uint32);
518 /*******************************************************************
519 prs_uint32 wrapper. call this and it retrospectively stores the size.
520 does nothing on reading, as that is already handled by ...._pre()
521 ********************************************************************/
522 BOOL _prs_uint32_post(char *name, prs_struct *ps, int depth, uint32 *data32,
523 uint32 ptr_uint32, uint32 data_size)
525 if (ps->error) return False;
528 /* storing: go back and do a retrospective job. i hate this */
529 uint32 old_offset = ps->offset;
530 ps->offset = ptr_uint32;
531 prs_uint32(name, ps, depth, &data_size);
532 ps->offset = old_offset;