- got fed up of vuser_db spewing 150 lines of trash, made it possible
[Samba.git] / source / rpc_parse / parse_prs.c
blobf642cacfb32c6b23816d5efa18c3187248283f9e
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
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;
25 #include "includes.h"
28 /*******************************************************************
29 debug output for parsing info.
30 ********************************************************************/
31 void prs_debug(prs_struct *ps, int depth, const char *desc,
32 const char *fn_name)
34 CHECK_STRUCT(ps);
35 DEBUG(5 + depth,
36 ("%s%06x %s %s\n", tab_depth(depth), ps->offset, fn_name,
37 desc));
40 /*******************************************************************
41 debug a parse structure
42 ********************************************************************/
43 void prs_debug_out(const prs_struct *ps, char *msg, int level)
45 CHECK_STRUCT(ps);
46 DEBUG(level, ("%s ps: io %s align %d offset %d err %d data %p\n",
47 msg, BOOLSTR(ps->io), ps->align, ps->offset, ps->error,
48 ps->data));
50 if (ps->data != NULL)
52 dump_data(level, ps->data, prs_buf_len(ps));
56 /*******************************************************************
57 initialise a parse structure
58 ********************************************************************/
59 BOOL prs_init(prs_struct *ps, uint32 size, uint8 align, BOOL io)
61 ps->struct_start = 0xfefefefe;
62 ps->io = io;
63 ps->align = align;
64 ps->offset = 0;
65 ps->error = False;
66 ps->bigendian = False;
68 ps->data = NULL;
69 ps->data_size = 0;
71 ps->start = 0;
72 ps->end = 0;
74 ps->next = NULL;
76 ps->struct_end = 0xdcdcdcdc;
78 if (size != 0)
80 prs_realloc_data(ps, size);
81 ps->end = 0xffffffff;
84 CHECK_STRUCT(ps);
85 return True;
88 /*******************************************************************
89 set the packed data representation type in a parse structure
90 ********************************************************************/
91 void prs_set_packtype(prs_struct *ps, const uint8 *pack_type)
93 CHECK_STRUCT(ps);
94 ps->bigendian = pack_type[0] == 0x0;
95 DEBUG(10,
96 ("prs_set_packtype: bigendian: %s\n", BOOLSTR(ps->bigendian)));
99 /*******************************************************************
100 create a parse structure
101 ********************************************************************/
102 void prs_create(prs_struct *ps, char *data, uint32 size, uint8 align, BOOL io)
104 DEBUG(200, ("prs_create: data:%p size:%d align:%d io:%s\n",
105 data, size, align, BOOLSTR(io)));
107 prs_init(ps, 0, align, io);
108 ps->data = data;
109 ps->data_size = size;
110 ps->end = size;
112 CHECK_STRUCT(ps);
115 /*******************************************************************
116 copy a parse structure
117 ********************************************************************/
118 BOOL prs_copy(prs_struct *ps, const prs_struct *from)
120 int len = prs_buf_len(from);
121 CHECK_STRUCT(ps);
122 CHECK_STRUCT(from);
123 prs_init(ps, len, from->align, from->io);
124 ps->bigendian = from->bigendian;
125 if (len != 0)
127 if (ps->data == NULL)
129 return False;
131 if (!prs_buf_copy(ps->data, from, 0, len))
133 return False;
136 ps->offset = len;
137 prs_link(NULL, ps, NULL);
138 return True;
141 /*******************************************************************
142 allocate a memory buffer. assume it's empty
143 ********************************************************************/
144 BOOL prs_alloc_data(prs_struct *buf, int size)
146 CHECK_STRUCT(buf);
148 buf->data_size = size;
149 buf->data = (char *)malloc(buf->data_size);
151 if (buf->data == NULL && size != 0)
153 DEBUG(3, ("prs_alloc: could not malloc size %d\n",
154 buf->data_size));
155 buf->data_size = 0;
157 return False;
160 memset(buf->data, 0, buf->data_size);
161 buf->end = buf->start + size;
163 CHECK_STRUCT(buf);
164 return True;
167 /*******************************************************************
168 search for a memory buffer that falls within the specified offset
169 ********************************************************************/
170 static const prs_struct *prs_find(const prs_struct *buf, uint32 offset)
172 const prs_struct *f;
173 if (buf == NULL)
174 return False;
176 f = buf;
178 CHECK_STRUCT(f);
179 DEBUG(200, ("prs_find: data[%d..%d] offset: %d\n",
180 f->start, f->end, offset));
182 while (f != NULL && offset >= f->end)
184 DEBUG(200, ("prs_find: next[%d..%d]\n", f->start, f->end));
186 f = f->next;
189 if (f != NULL)
191 DEBUG(200,
192 ("prs_find: found data[%d..%d]\n", f->start, f->end));
195 return f;
198 /*******************************************************************
199 allocates a memory buffer structure
200 ********************************************************************/
201 BOOL prs_buf_copy(char *copy_into, const prs_struct *buf,
202 uint32 offset, uint32 len)
204 uint32 end = offset + len;
205 char *q = NULL;
206 uint32 start_offset = offset;
207 const prs_struct *bcp = buf;
209 if (buf == NULL || copy_into == NULL)
210 return False;
212 CHECK_STRUCT(buf);
213 if (DEBUGLVL(200))
215 DEBUG(200, ("prs_struct_copy: data[%d..%d] offset %d len %d\n",
216 buf->start, prs_buf_len(buf), offset, len));
219 prs_debug_out(bcp, "prs_struct_copy", 200);
221 while (offset < end && ((q = prs_data(bcp, offset)) != NULL))
223 uint32 copy_len;
224 bcp = prs_find(bcp, offset);
225 copy_len = bcp->end - offset;
227 DEBUG(200, ("\tdata[%d..%d] - offset %d len %d\n",
228 bcp->start, bcp->end, offset, copy_len));
230 memcpy(copy_into, q, copy_len);
232 offset += copy_len;
233 copy_into += copy_len;
236 if (bcp != NULL)
238 DEBUG(200,
239 ("prs_struct_copy: copied %d bytes\n",
240 offset - start_offset));
242 else
244 DEBUG(200, ("prs_struct_copy: failed\n"));
247 return buf != NULL;
250 /*******************************************************************
251 frees up a memory buffer.
252 ********************************************************************/
253 void prs_struct_free(prs_struct **buf)
255 if (buf == NULL)
256 return;
257 if ((*buf) == NULL)
258 return;
260 CHECK_STRUCT(*buf);
261 prs_free_data(*buf); /* delete memory data */
262 free(*buf); /* delete item */
263 (*buf) = NULL;
266 /*******************************************************************
267 frees a memory buffer chain. assumes that all items are malloced.
268 ********************************************************************/
269 static void prs_free_chain(prs_struct **buf)
271 if (buf == NULL)
272 return;
273 if ((*buf) == NULL)
274 return;
276 CHECK_STRUCT(*buf);
277 if ((*buf)->next != NULL)
279 prs_free_chain(&((*buf)->next)); /* delete all other items in chain */
281 prs_struct_free(buf);
284 /*******************************************************************
285 frees a memory buffer.
286 ********************************************************************/
287 void prs_free_data(prs_struct *buf)
289 if (buf == NULL)
290 return;
292 if (buf->data != NULL)
294 CHECK_STRUCT(buf);
295 safe_free(buf->data); /* delete data in this structure */
296 buf->data = NULL;
298 buf->data_size = 0;
301 /*******************************************************************
302 reallocate a memory buffer
303 ********************************************************************/
304 BOOL prs_realloc_data(prs_struct *buf, size_t new_size)
306 char *new_data;
308 CHECK_STRUCT(buf);
310 prs_debug_out(buf, "prs_realloc_data - before", 200);
312 if (new_size == 0)
314 prs_free_data(buf);
315 return True;
318 new_data = (char *)Realloc(buf->data, new_size);
320 if (new_data != NULL)
322 if (new_size > buf->data_size)
324 memset(&new_data[buf->data_size], 0,
325 new_size - buf->data_size);
327 buf->data = new_data;
328 buf->data_size = new_size;
330 else if (buf->data_size >= new_size)
332 DEBUG(3,
333 ("prs_realloc_data: warning - could not realloc to %d\n",
334 new_size));
336 else
338 DEBUG(3,
339 ("prs_realloc_data: error - could not realloc to %d\n",
340 new_size));
342 prs_free_data(buf);
343 buf->error = True;
344 return False;
347 buf->end = buf->start + new_size;
349 prs_debug_out(buf, "prs_realloc_data - after", 200);
350 return True;
353 /*******************************************************************
354 reallocate a memory buffer, retrospectively :-)
355 ********************************************************************/
356 BOOL prs_grow_data(prs_struct *buf, BOOL io, int new_size, BOOL force_grow)
358 if (buf == NULL)
360 return False;
363 CHECK_STRUCT(buf);
365 if (new_size > buf->data_size)
367 if (!io || force_grow)
369 /* writing or forge realloc */
370 return prs_realloc_data(buf, new_size);
372 else
375 * reading, there is just not that much
376 * data in the buffer
378 DEBUG(1, ("prs_grow_data: %d > %d\n",
379 new_size, buf->data_size));
380 return False;
383 return True;
387 /*******************************************************************
388 add up the lengths of all sections.
389 ********************************************************************/
390 uint32 prs_buf_len(const prs_struct *buf)
392 int len = 0;
393 CHECK_STRUCT(buf);
394 while (buf != NULL)
396 len += buf->end - buf->start;
397 buf = buf->next;
399 return len;
402 /*******************************************************************
403 return the memory location specified by may return NULL.
404 ********************************************************************/
405 char *prs_data(const prs_struct *buf, uint32 offset)
407 CHECK_STRUCT(buf);
408 buf = prs_find(buf, offset);
409 if (buf != NULL)
411 return &(buf->data[offset - buf->start]);
413 return NULL;
417 /*******************************************************************
418 link one parsing structure to another
419 ********************************************************************/
420 void prs_link(prs_struct *prev, prs_struct *ps, prs_struct *next)
422 CHECK_STRUCT(ps);
423 if (next != NULL)
425 CHECK_STRUCT(next);
427 if (prev != NULL)
429 CHECK_STRUCT(prev);
431 ps->start = prev != NULL ? prev->end : 0;
432 ps->end = ps->start + ps->offset;
434 ps->next = next;
436 DEBUG(150, ("prs_link: start %d end %d\n", ps->start, ps->end));
439 /*******************************************************************
440 align a pointer to a multiple of align_offset bytes. looks like it
441 will work for offsets of 0, 2 and 4...
442 ********************************************************************/
443 BOOL prs_align(prs_struct *ps)
445 int mod;
446 CHECK_STRUCT(ps);
447 if (ps->error)
448 return False;
449 mod = ps->offset & (ps->align - 1);
450 if (ps->align != 0 && mod != 0)
452 ps->offset += ps->align - mod;
453 if (!prs_grow(ps, ps->offset))
455 return False;
458 return True;
461 /*******************************************************************
462 attempt, if appropriate, to grow a data buffer.
464 depends on the data stream mode (io)
465 ********************************************************************/
466 BOOL prs_grow(prs_struct *ps, uint32 new_size)
468 CHECK_STRUCT(ps);
469 if (ps->error)
470 return False;
471 return prs_grow_data(ps, ps->io, new_size, False);
474 /*******************************************************************
475 lengthens a buffer by len bytes and copies data into it.
476 ********************************************************************/
477 BOOL prs_append_data(prs_struct *ps, const char *data, int len)
479 int prev_size = ps->data_size;
480 int new_size = prev_size + len;
481 char *to;
483 DEBUG(200, ("prs_append_data: prev_size: %d new_size: %d\n",
484 prev_size, new_size));
486 CHECK_STRUCT(ps);
487 prs_realloc_data(ps, new_size);
488 to = prs_data(ps, prev_size);
490 if (to == NULL || ps->data_size != new_size)
492 return False;
494 memcpy(to, data, len);
496 return True;
499 BOOL prs_add_data(prs_struct *ps, const char *data, int len)
501 int prev_size;
502 int new_size;
503 char *to = NULL;
505 ps->offset = 0;
507 if (ps->data == NULL)
509 DEBUG(10, ("prs_add_data: new_size: %d\n", len));
510 prs_init(ps, len, 4, True);
511 prev_size = 0;
512 new_size = len;
513 if (ps->data == NULL)
515 return False;
518 else
520 prev_size = ps->data_size;
521 new_size = prev_size + len;
522 DEBUG(10, ("prs_add_data: prev_size: %d new_size: %d\n",
523 prev_size, new_size));
524 if (!prs_realloc_data(ps, new_size))
526 return False;
530 DEBUG(10, ("ps->start: %d\n", ps->start));
531 ps->start = 0x0;
533 to = prs_data(ps, prev_size);
534 if (to == NULL)
536 DEBUG(10, ("prs_add_data: data could not be found\n"));
537 return False;
539 if (ps->data_size != new_size)
541 DEBUG(10, ("prs_add_data: ERROR: data used %d new_size %d\n",
542 ps->data_size, new_size));
543 return False;
545 memcpy(to, data, len);
546 return True;
549 /*******************************************************************
550 Change the struct type.
551 ********************************************************************/
553 void prs_switch_type(prs_struct *ps, BOOL io)
555 if ((ps->io ^ io) == True)
556 ps->io = io;
559 /*******************************************************************
560 Force a prs_struct to be dynamic even when its size is 0.
561 ********************************************************************/
563 void prs_force_dynamic(prs_struct *ps)
567 /*******************************************************************
568 Fetch the current offset (external interface).
569 ********************************************************************/
570 uint32 prs_data_size(prs_struct *ps)
572 return ps->data_size;
575 /*******************************************************************
576 Fetch the current offset (external interface).
577 ********************************************************************/
578 uint32 prs_offset(prs_struct *ps)
580 return ps->offset;
583 /*******************************************************************
584 Set the current offset (external interface).
585 ********************************************************************/
586 BOOL prs_set_offset(prs_struct *ps, uint32 offset)
588 if (offset <= ps->offset)
590 ps->offset = offset;
591 return True;
594 if (!prs_grow(ps, offset))
596 return False;
599 ps->offset = offset;
600 return True;
603 /*******************************************************************
604 Delete the memory in a parse structure - if we own it.
605 ********************************************************************/
607 void prs_mem_free(prs_struct *ps)
609 safe_free(ps->data);
610 ps->data = NULL;
611 ps->offset = 0;
615 /*******************************************************************
616 Append some data from one parse_struct into another.
617 ********************************************************************/
619 BOOL prs_append_some_prs_data(prs_struct *dst, prs_struct *src, int32 start,
620 uint32 len)
624 * JFM:
625 * ok, it looks like shit. It smells like shit.
626 * summary: it's shit.
628 * I'm not proud of that code. I mae that ugly hack to
629 * a) not change luke's prs memory managment
630 * b) not change the spoolss parsing code
632 * mail me, call me, hit me before changing that piece of code.
635 if (start == 0)
636 prs_add_data(dst, src->data, len);
637 else
639 dst->data_size = 0;
640 prs_add_data(dst, src->data + start, len);
643 dst->offset = dst->data_size;
644 return True;
647 /*******************************************************************
648 stream a uint8
649 ********************************************************************/
650 BOOL _prs_uint8(char *name, prs_struct *ps, int depth, uint8 *data8)
652 char *q;
653 CHECK_STRUCT(ps);
654 if (ps->error)
655 return False;
656 if (!prs_grow(ps, ps->offset + 1))
658 return False;
660 q = prs_data(ps, ps->offset);
661 if (q == NULL)
663 ps->error = True;
664 prs_debug_out(ps, "_prs_uint8 error", 5);
665 return False;
668 DBG_RW_CVAL(name, depth, ps->offset, ps->io, q, *data8);
669 ps->offset += 1;
671 return True;
674 /*******************************************************************
675 stream a uint16
676 ********************************************************************/
677 BOOL _prs_uint16(char *name, prs_struct *ps, int depth, uint16 *data16)
679 char *q;
680 CHECK_STRUCT(ps);
681 if (ps->error)
682 return False;
683 if (!prs_grow(ps, ps->offset + 2))
685 return False;
687 q = prs_data(ps, ps->offset);
688 if (q == NULL)
690 ps->error = True;
691 prs_debug_out(ps, "_prs_uint16 error", 5);
692 return False;
695 DBG_RW_SVAL(name, depth, ps->offset, ps->io, ps->bigendian, q,
696 *data16);
697 ps->offset += 2;
699 return True;
702 /*******************************************************************
703 hash a stream.
704 ********************************************************************/
705 BOOL _prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16])
707 char *q;
708 CHECK_STRUCT(ps);
709 if (ps->error)
710 return False;
711 q = prs_data(ps, ps->offset);
712 if (q == NULL)
714 ps->error = True;
715 prs_debug_out(ps, "_prs_hash1 error", 5);
716 return False;
719 #ifdef DEBUG_PASSWORD
720 DEBUG(100, ("prs_hash1\n"));
721 dump_data(100, sess_key, 16);
722 dump_data(100, q, 68);
723 #endif
724 SamOEMhash((uchar *) q, sess_key, 2);
725 #ifdef DEBUG_PASSWORD
726 dump_data(100, q, 68);
727 #endif
729 return True;
732 /*******************************************************************
733 stream a uint32
734 ********************************************************************/
735 BOOL _prs_uint32(char *name, prs_struct *ps, int depth, uint32 *data32)
737 char *q;
738 CHECK_STRUCT(ps);
739 if (ps->error)
740 return False;
741 if (!prs_grow(ps, ps->offset + 4))
743 return False;
745 q = prs_data(ps, ps->offset);
746 if (q == NULL)
748 fstring str;
749 slprintf(str, sizeof(str) - 1, "_prs_uint32 error (%s)",
750 name);
751 ps->error = True;
752 prs_debug_out(ps, str, 5);
753 return False;
756 DBG_RW_IVAL(name, depth, ps->offset, ps->io, ps->bigendian, q,
757 *data32);
758 ps->offset += 4;
760 return True;
764 /******************************************************************
765 stream an array of uint8s. length is number of uint8s
766 ********************************************************************/
767 BOOL _prs_uint8s(BOOL charmode, char *name, prs_struct *ps, int depth,
768 uint8 *data8s, int len)
770 char *q;
771 int end_offset;
772 char *e;
773 CHECK_STRUCT(ps);
775 if (len == 0)
777 return True;
780 if (ps->error)
781 return False;
782 end_offset = ps->offset + len * sizeof(uint8);
783 if (!prs_grow(ps, end_offset))
785 return False;
787 q = prs_data(ps, ps->offset);
788 e = prs_data(ps, end_offset - 1);
790 if (q == NULL || e == NULL)
792 ps->error = True;
793 prs_debug_out(ps, "_prs_uint8s error", 5);
794 return False;
797 DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, data8s,
798 len);
799 ps->offset = end_offset;
801 return True;
804 /******************************************************************
805 stream an array of uint16s. length is number of uint16s
806 ********************************************************************/
807 BOOL _prs_uint16s(BOOL charmode, char *name, prs_struct *ps, int depth,
808 uint16 *data16s, int len)
810 char *q;
811 int end_offset;
812 char *e;
813 CHECK_STRUCT(ps);
814 if (ps->error)
815 return False;
817 if (len == 0)
819 return True;
822 end_offset = ps->offset + len * sizeof(uint16);
823 if (!prs_grow(ps, end_offset))
825 return False;
827 q = prs_data(ps, ps->offset);
828 e = prs_data(ps, end_offset - 1);
830 if (q == NULL || e == NULL)
832 ps->error = True;
833 prs_debug_out(ps, "_prs_uint16s error", 5);
834 return False;
837 DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, ps->bigendian,
838 q, data16s, len);
839 ps->offset = end_offset;
841 return True;
844 /******************************************************************
845 stream an array of uint32s. length is number of uint32s
846 ********************************************************************/
847 BOOL _prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth,
848 uint32 *data32s, int len)
850 char *q;
851 int end_offset;
852 char *e;
853 CHECK_STRUCT(ps);
854 if (ps->error)
855 return False;
857 if (len == 0)
859 return True;
862 end_offset = ps->offset + len * sizeof(uint32);
863 if (!prs_grow(ps, end_offset))
865 return False;
867 q = prs_data(ps, ps->offset);
868 e = prs_data(ps, end_offset - 1);
870 if (q == NULL || e == NULL)
872 ps->error = True;
873 prs_debug_out(ps, "_prs_uint32s error", 5);
874 return False;
877 DBG_RW_PIVAL(charmode, name, depth, ps->offset, ps->io, ps->bigendian,
878 q, data32s, len);
879 ps->offset = end_offset;
881 return True;
884 /******************************************************************
885 stream a "not" unicode string, length/buffer specified separately,
886 in byte chars
887 ********************************************************************/
888 BOOL _prs_buffer2(BOOL charmode, char *name, prs_struct *ps, int depth,
889 BUFFER2 * str)
891 char *q;
892 int end_offset;
893 char *e;
894 CHECK_STRUCT(ps);
895 if (ps->error)
896 return False;
898 if (str->buf_len == 0)
900 return True;
903 end_offset = ps->offset + str->buf_len * sizeof(uint8);
904 if (!prs_grow(ps, end_offset))
906 return False;
908 q = prs_data(ps, ps->offset);
909 e = prs_data(ps, end_offset - 1);
911 if (q == NULL || e == NULL)
913 ps->error = True;
914 prs_debug_out(ps, "_prs_buffer2 error", 5);
915 return False;
918 DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q,
919 str->buffer, str->buf_len);
920 ps->offset = end_offset;
922 return True;
925 /******************************************************************
926 stream a string, length/buffer specified separately,
927 in uint8 chars.
928 ********************************************************************/
929 BOOL _prs_string2(BOOL charmode, char *name, prs_struct *ps, int depth,
930 STRING2 * str)
932 char *q;
933 int end_offset;
934 char *e;
935 CHECK_STRUCT(ps);
936 if (ps->error)
937 return False;
939 if (str->str_str_len == 0)
941 return True;
944 end_offset = ps->offset + str->str_str_len * sizeof(uint8);
945 if (!prs_grow(ps, end_offset))
947 return False;
949 q = prs_data(ps, ps->offset);
950 e = prs_data(ps, end_offset - 1);
952 if (q == NULL || e == NULL)
954 ps->error = True;
955 prs_debug_out(ps, "_prs_string2 error", 5);
956 return False;
959 DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q,
960 str->buffer, str->str_str_len);
961 ps->offset = end_offset;
963 return True;
966 /******************************************************************
967 stream a unicode string, length/buffer specified separately,
968 in uint16 chars.
969 ********************************************************************/
970 BOOL _prs_unistr2(BOOL charmode, char *name, prs_struct *ps, int depth,
971 UNISTR2 *str)
973 char *q;
974 int end_offset;
975 char *e;
976 CHECK_STRUCT(ps);
977 if (ps->error)
978 return False;
980 if (str->uni_str_len == 0)
982 return True;
985 end_offset = ps->offset + str->uni_str_len * sizeof(uint16);
986 if (!prs_grow(ps, end_offset))
988 return False;
990 q = prs_data(ps, ps->offset);
991 e = prs_data(ps, end_offset - 1);
993 if (q == NULL || e == NULL)
995 ps->error = True;
996 prs_debug_out(ps, "_prs_unistr2 error", 5);
997 return False;
1000 DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, ps->bigendian,
1001 q, str->buffer, str->uni_str_len);
1002 ps->offset = end_offset;
1004 return True;
1007 /******************************************************************
1008 stream a unicode string, length/buffer specified separately,
1009 in uint16 chars.
1010 ********************************************************************/
1011 BOOL _prs_unistr3(BOOL charmode, char *name, UNISTR3 * str, prs_struct *ps,
1012 int depth)
1014 char *q;
1015 int end_offset;
1016 char *e;
1017 CHECK_STRUCT(ps);
1018 if (ps->error)
1019 return False;
1021 if (str->uni_str_len == 0)
1023 return True;
1026 end_offset = ps->offset + str->uni_str_len * sizeof(uint16);
1027 if (!prs_grow(ps, end_offset))
1029 return False;
1031 q = prs_data(ps, ps->offset);
1032 e = prs_data(ps, end_offset - 1);
1034 if (q == NULL || e == NULL)
1036 ps->error = True;
1037 prs_debug_out(ps, "_prs_unistr3 error", 5);
1038 return False;
1041 DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, ps->bigendian,
1042 q, str->str.buffer, str->uni_str_len);
1043 ps->offset = end_offset;
1045 return True;
1048 /*******************************************************************
1049 stream a unicode null-terminated string
1050 ********************************************************************/
1051 BOOL _prs_unistr(char *name, prs_struct *ps, int depth, UNISTR * str)
1053 int i = -1;
1054 uint8 *start;
1055 CHECK_STRUCT(ps);
1056 if (ps->error)
1057 return False;
1058 start = (uint8 *)prs_data(ps, ps->offset);
1062 char *q;
1063 i++;
1064 if (!prs_grow(ps, ps->offset + (i + 1) * 2))
1066 return False;
1068 q = prs_data(ps, ps->offset + i * 2);
1069 if (q == NULL)
1071 ps->error = True;
1072 prs_debug_out(ps, "_prs_unistr error", 5);
1073 return False;
1075 RW_SVAL(ps->io, ps->bigendian, q, str->buffer[i], 0);
1077 while ((((size_t) i) < sizeof(str->buffer) / sizeof(str->buffer[0]))
1078 && (str->buffer[i] != 0));
1081 ps->offset += (i + 1) * 2;
1083 dump_data(5 + depth, (char *)start, i * 2);
1085 return True;
1088 /*******************************************************************
1089 stream a null-terminated string. len is strlen, and therefore does
1090 not include the null-termination character.
1092 len == 0 indicates variable length string
1093 (up to max size of pstring - 1024 chars).
1095 ********************************************************************/
1096 BOOL _prs_string(char *name, prs_struct *ps, int depth, char *str,
1097 uint16 len, uint16 max_buf_size)
1099 int i = -1; /* start off at zero after 1st i++ */
1100 BOOL len_limited;
1102 CHECK_STRUCT(ps);
1103 if (ps->error)
1104 return False;
1106 len_limited = len == 0 || !ps->io;
1108 DEBUG(200, ("_prs_string: string %s len %d max %d\n",
1109 str, len, max_buf_size));
1111 DEBUG(5+depth,
1112 ("%s%04x %s: ", tab_depth(depth), ps->offset,
1113 name != NULL ? name : ""));
1116 char *q;
1117 i++;
1119 if (!prs_grow(ps, ps->offset + i + 1))
1121 return False;
1123 q = prs_data(ps, ps->offset + i);
1124 if (q == NULL)
1126 ps->error = True;
1127 DEBUG(5+depth, ("%s\n", str));
1128 prs_debug_out(ps, "_prs_string error", 5);
1129 return False;
1132 if (i < len || len_limited)
1134 RW_CVAL(ps->io, q, str[i], 0);
1136 else
1138 uint8 dummy = 0;
1139 RW_CVAL(ps->io, q, dummy, 0);
1143 while (i < max_buf_size && (len_limited ? str[i] != 0 : i < len));
1145 ps->offset += i + 1;
1147 DEBUG(5+depth, ("%s\n", str));
1149 return True;
1152 /*******************************************************************
1153 prs_uint16 wrapper. call this and it sets up a pointer to where the
1154 uint16 should be stored, or gets the size if reading
1155 ********************************************************************/
1156 BOOL _prs_uint16_pre(char *name, prs_struct *ps, int depth, uint16 *data16,
1157 uint32 *offset)
1159 CHECK_STRUCT(ps);
1160 if (ps->error)
1161 return False;
1162 (*offset) = ps->offset;
1163 if (ps->io)
1165 /* reading. */
1166 return _prs_uint16(name, ps, depth, data16);
1168 else
1170 ps->offset += sizeof(uint16);
1172 return True;
1175 /*******************************************************************
1176 prs_uint16 wrapper. call this and it retrospectively stores the size.
1177 does nothing on reading, as that is already handled by ...._pre()
1178 ********************************************************************/
1179 BOOL _prs_uint16_post(char *name, prs_struct *ps, int depth, uint16 *data16,
1180 uint32 ptr_uint16, uint32 start_offset)
1182 CHECK_STRUCT(ps);
1183 if (ps->error)
1184 return False;
1185 if (!ps->io)
1187 /* storing: go back and do a retrospective job. i hate this */
1188 uint16 data_size = ps->offset - start_offset;
1189 uint32 old_offset = ps->offset;
1191 ps->offset = ptr_uint16;
1192 prs_uint16(name, ps, depth, &data_size);
1193 ps->offset = old_offset;
1195 else
1197 ps->offset = start_offset + (*data16);
1199 return True;
1202 /*******************************************************************
1203 prs_uint32 wrapper. call this and it sets up a pointer to where the
1204 uint32 should be stored, or gets the size if reading
1205 ********************************************************************/
1206 BOOL _prs_uint32_pre(char *name, prs_struct *ps, int depth, uint32 *data32,
1207 uint32 *offset)
1209 CHECK_STRUCT(ps);
1210 if (ps->error)
1211 return False;
1212 (*offset) = ps->offset;
1213 if (ps->io)
1215 /* reading. */
1216 return _prs_uint32(name, ps, depth, data32);
1218 else
1220 ps->offset += sizeof(uint32);
1222 return True;
1225 /*******************************************************************
1226 prs_uint32 wrapper. call this and it retrospectively stores the size.
1227 does nothing on reading, as that is already handled by ...._pre()
1228 ********************************************************************/
1229 BOOL _prs_uint32_post(char *name, prs_struct *ps, int depth, uint32 *data32,
1230 uint32 ptr_uint32, uint32 data_size)
1232 CHECK_STRUCT(ps);
1233 if (ps->error)
1234 return False;
1235 if (!ps->io)
1237 /* storing: go back and do a retrospective job. i hate this */
1238 uint32 old_offset = ps->offset;
1239 ps->offset = ptr_uint32;
1240 prs_uint32(name, ps, depth, &data_size);
1241 ps->offset = old_offset;
1243 else
1245 ps->offset = data_size + (*data32);
1247 return True;
1250 /*******************************************************************
1251 prs_tdb_store. stores prs_struct data by prs_struct key
1252 ********************************************************************/
1253 int prs_tdb_delete(TDB_CONTEXT * tdb, prs_struct *pk)
1255 TDB_DATA key;
1257 key.dptr = (char *)prs_data(pk, 0);
1258 key.dsize = prs_buf_len(pk);
1260 return tdb_delete(tdb, key);
1263 /*******************************************************************
1264 prs_tdb_store. stores prs_struct data by prs_struct key
1265 ********************************************************************/
1266 int prs_tdb_store(TDB_CONTEXT * tdb, int flgs, prs_struct *pk, prs_struct *pd)
1268 TDB_DATA key;
1269 TDB_DATA data;
1271 key.dptr = (char *)prs_data(pk, 0);
1272 key.dsize = prs_buf_len(pk);
1274 data.dptr = prs_data(pd, 0);
1275 data.dsize = prs_buf_len(pd);
1277 return tdb_store(tdb, key, data, flgs);
1280 /*******************************************************************
1281 prs_tdb_fetch. fetches prs_struct data by prs_struct key
1282 ********************************************************************/
1283 void prs_tdb_fetch(TDB_CONTEXT * tdb, prs_struct *pk, prs_struct *pd)
1285 TDB_DATA key;
1286 TDB_DATA data;
1288 key.dptr = (char *)prs_data(pk, 0);
1289 key.dsize = prs_buf_len(pk);
1291 data = tdb_fetch(tdb, key);
1293 prs_create(pd, data.dptr, data.dsize, 4, True);