2 Unix SMB/CIFS implementation.
3 Samba memory buffer functions
4 Copyright (C) Andrew Tridgell 1992-1997
5 Copyright (C) Luke Kenneth Casson Leighton 1996-1997
6 Copyright (C) Jeremy Allison 1999
7 Copyright (C) Andrew Bartlett 2003.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "../librpc/gen_ndr/ndr_schannel.h"
27 #define DBGC_CLASS DBGC_RPC_PARSE
30 * Dump a prs to a file: from the current location through to the end.
32 void prs_dump(const char *name
, int v
, prs_struct
*ps
)
34 prs_dump_region(name
, v
, ps
, ps
->data_offset
, ps
->buffer_size
);
38 * Dump from the start of the prs to the current location.
40 void prs_dump_before(const char *name
, int v
, prs_struct
*ps
)
42 prs_dump_region(name
, v
, ps
, 0, ps
->data_offset
);
46 * Dump everything from the start of the prs up to the current location.
48 void prs_dump_region(const char *name
, int v
, prs_struct
*ps
,
49 int from_off
, int to_off
)
54 if (DEBUGLEVEL
< 50) return;
57 if (asprintf(&fname
,"/tmp/%s_%d.%d.prs", name
, v
, i
) < 0) {
61 if (asprintf(&fname
,"/tmp/%s.%d.prs", name
, i
) < 0) {
65 fd
= open(fname
, O_WRONLY
|O_CREAT
|O_EXCL
, 0644);
66 if (fd
!= -1 || errno
!= EEXIST
) break;
69 sz
= write(fd
, ps
->data_p
+ from_off
, to_off
- from_off
);
71 if ( (sz
!= to_off
-from_off
) || (i
!= 0) ) {
72 DEBUG(0,("Error writing/closing %s: %ld!=%ld %d\n", fname
, (unsigned long)sz
, (unsigned long)to_off
-from_off
, i
));
74 DEBUG(0,("created %s\n", fname
));
80 /*******************************************************************
81 Debug output for parsing info
83 XXXX side-effect of this function is to increase the debug depth XXXX.
85 ********************************************************************/
87 void prs_debug(prs_struct
*ps
, int depth
, const char *desc
, const char *fn_name
)
89 DEBUG(5+depth
, ("%s%06x %s %s\n", tab_depth(5+depth
,depth
), ps
->data_offset
, fn_name
, desc
));
93 * Initialise an expandable parse structure.
95 * @param size Initial buffer size. If >0, a new buffer will be
96 * created with malloc().
98 * @return False if allocation fails, otherwise True.
101 bool prs_init(prs_struct
*ps
, uint32 size
, TALLOC_CTX
*ctx
, bool io
)
105 ps
->bigendian_data
= RPC_LITTLE_ENDIAN
;
106 ps
->align
= RPC_PARSE_ALIGN
;
107 ps
->is_dynamic
= False
;
114 ps
->buffer_size
= size
;
115 if((ps
->data_p
= (char *)SMB_MALLOC((size_t)size
)) == NULL
) {
116 DEBUG(0,("prs_init: malloc fail for %u bytes.\n", (unsigned int)size
));
119 memset(ps
->data_p
, '\0', (size_t)size
);
120 ps
->is_dynamic
= True
; /* We own this memory. */
121 } else if (MARSHALLING(ps
)) {
122 /* If size is zero and we're marshalling we should allocate memory on demand. */
123 ps
->is_dynamic
= True
;
129 /*******************************************************************
130 Delete the memory in a parse structure - if we own it.
132 NOTE: Contrary to the somewhat confusing naming, this function is not
133 intended for freeing memory allocated by prs_alloc_mem(). That memory
134 is attached to the talloc context given by ps->mem_ctx.
135 ********************************************************************/
137 void prs_mem_free(prs_struct
*ps
)
140 SAFE_FREE(ps
->data_p
);
141 ps
->is_dynamic
= False
;
146 /*******************************************************************
147 Clear the memory in a parse structure.
148 ********************************************************************/
150 void prs_mem_clear(prs_struct
*ps
)
153 memset(ps
->data_p
, '\0', (size_t)ps
->buffer_size
);
156 /*******************************************************************
157 Allocate memory when unmarshalling... Always zero clears.
158 ********************************************************************/
160 #if defined(PARANOID_MALLOC_CHECKER)
161 char *prs_alloc_mem_(prs_struct
*ps
, size_t size
, unsigned int count
)
163 char *prs_alloc_mem(prs_struct
*ps
, size_t size
, unsigned int count
)
169 /* We can't call the type-safe version here. */
170 ret
= (char *)_talloc_zero_array(ps
->mem_ctx
, size
, count
,
176 /*******************************************************************
177 Return the current talloc context we're using.
178 ********************************************************************/
180 TALLOC_CTX
*prs_get_mem_context(prs_struct
*ps
)
185 /*******************************************************************
186 Hand some already allocated memory to a prs_struct.
187 ********************************************************************/
189 void prs_give_memory(prs_struct
*ps
, char *buf
, uint32 size
, bool is_dynamic
)
191 ps
->is_dynamic
= is_dynamic
;
193 ps
->buffer_size
= size
;
196 /*******************************************************************
197 Take some memory back from a prs_struct.
198 ********************************************************************/
200 char *prs_take_memory(prs_struct
*ps
, uint32
*psize
)
202 char *ret
= ps
->data_p
;
204 *psize
= ps
->buffer_size
;
205 ps
->is_dynamic
= False
;
210 /*******************************************************************
211 Set a prs_struct to exactly a given size. Will grow or tuncate if neccessary.
212 ********************************************************************/
214 bool prs_set_buffer_size(prs_struct
*ps
, uint32 newsize
)
216 if (newsize
> ps
->buffer_size
)
217 return prs_force_grow(ps
, newsize
- ps
->buffer_size
);
219 if (newsize
< ps
->buffer_size
) {
220 ps
->buffer_size
= newsize
;
222 /* newsize == 0 acts as a free and set pointer to NULL */
224 SAFE_FREE(ps
->data_p
);
226 ps
->data_p
= (char *)SMB_REALLOC(ps
->data_p
, newsize
);
228 if (ps
->data_p
== NULL
) {
229 DEBUG(0,("prs_set_buffer_size: Realloc failure for size %u.\n",
230 (unsigned int)newsize
));
231 DEBUG(0,("prs_set_buffer_size: Reason %s\n",strerror(errno
)));
240 /*******************************************************************
241 Attempt, if needed, to grow a data buffer.
242 Also depends on the data stream mode (io).
243 ********************************************************************/
245 bool prs_grow(prs_struct
*ps
, uint32 extra_space
)
249 ps
->grow_size
= MAX(ps
->grow_size
, ps
->data_offset
+ extra_space
);
251 if(ps
->data_offset
+ extra_space
<= ps
->buffer_size
)
255 * We cannot grow the buffer if we're not reading
256 * into the prs_struct, or if we don't own the memory.
259 if(UNMARSHALLING(ps
) || !ps
->is_dynamic
) {
260 DEBUG(0,("prs_grow: Buffer overflow - unable to expand buffer by %u bytes.\n",
261 (unsigned int)extra_space
));
266 * Decide how much extra space we really need.
269 extra_space
-= (ps
->buffer_size
- ps
->data_offset
);
270 if(ps
->buffer_size
== 0) {
273 * Start with 128 bytes (arbitrary value), enough for small rpc
276 new_size
= MAX(128, extra_space
);
278 if((ps
->data_p
= (char *)SMB_MALLOC(new_size
)) == NULL
) {
279 DEBUG(0,("prs_grow: Malloc failure for size %u.\n", (unsigned int)new_size
));
282 memset(ps
->data_p
, '\0', (size_t)new_size
);
285 * If the current buffer size is bigger than the space needed,
286 * just double it, else add extra_space. Always keep 64 bytes
287 * more, so that after we added a large blob we don't have to
288 * realloc immediately again.
290 new_size
= MAX(ps
->buffer_size
*2,
291 ps
->buffer_size
+ extra_space
+ 64);
293 if ((ps
->data_p
= (char *)SMB_REALLOC(ps
->data_p
, new_size
)) == NULL
) {
294 DEBUG(0,("prs_grow: Realloc failure for size %u.\n",
295 (unsigned int)new_size
));
299 memset(&ps
->data_p
[ps
->buffer_size
], '\0', (size_t)(new_size
- ps
->buffer_size
));
301 ps
->buffer_size
= new_size
;
306 /*******************************************************************
307 Attempt to force a data buffer to grow by len bytes.
308 This is only used when appending more data onto a prs_struct
309 when reading an rpc reply, before unmarshalling it.
310 ********************************************************************/
312 bool prs_force_grow(prs_struct
*ps
, uint32 extra_space
)
314 uint32 new_size
= ps
->buffer_size
+ extra_space
;
316 if(!UNMARSHALLING(ps
) || !ps
->is_dynamic
) {
317 DEBUG(0,("prs_force_grow: Buffer overflow - unable to expand buffer by %u bytes.\n",
318 (unsigned int)extra_space
));
322 if((ps
->data_p
= (char *)SMB_REALLOC(ps
->data_p
, new_size
)) == NULL
) {
323 DEBUG(0,("prs_force_grow: Realloc failure for size %u.\n",
324 (unsigned int)new_size
));
328 memset(&ps
->data_p
[ps
->buffer_size
], '\0', (size_t)(new_size
- ps
->buffer_size
));
330 ps
->buffer_size
= new_size
;
335 /*******************************************************************
336 Get the data pointer (external interface).
337 ********************************************************************/
339 char *prs_data_p(prs_struct
*ps
)
344 /*******************************************************************
345 Get the current data size (external interface).
346 ********************************************************************/
348 uint32
prs_data_size(prs_struct
*ps
)
350 return ps
->buffer_size
;
353 /*******************************************************************
354 Fetch the current offset (external interface).
355 ********************************************************************/
357 uint32
prs_offset(prs_struct
*ps
)
359 return ps
->data_offset
;
362 /*******************************************************************
363 Set the current offset (external interface).
364 ********************************************************************/
366 bool prs_set_offset(prs_struct
*ps
, uint32 offset
)
368 if ((offset
> ps
->data_offset
)
369 && !prs_grow(ps
, offset
- ps
->data_offset
)) {
373 ps
->data_offset
= offset
;
377 /*******************************************************************
378 Append the data from one parse_struct into another.
379 ********************************************************************/
381 bool prs_append_prs_data(prs_struct
*dst
, prs_struct
*src
)
383 if (prs_offset(src
) == 0)
386 if(!prs_grow(dst
, prs_offset(src
)))
389 memcpy(&dst
->data_p
[dst
->data_offset
], src
->data_p
, (size_t)prs_offset(src
));
390 dst
->data_offset
+= prs_offset(src
);
395 /*******************************************************************
396 Append some data from one parse_struct into another.
397 ********************************************************************/
399 bool prs_append_some_data(prs_struct
*dst
, void *src_base
, uint32_t start
,
406 if(!prs_grow(dst
, len
)) {
410 memcpy(&dst
->data_p
[dst
->data_offset
], ((char *)src_base
) + start
, (size_t)len
);
411 dst
->data_offset
+= len
;
415 bool prs_append_some_prs_data(prs_struct
*dst
, prs_struct
*src
, int32 start
,
418 return prs_append_some_data(dst
, src
->data_p
, start
, len
);
421 /*******************************************************************
422 Append the data from a buffer into a parse_struct.
423 ********************************************************************/
425 bool prs_copy_data_in(prs_struct
*dst
, const char *src
, uint32 len
)
430 if(!prs_grow(dst
, len
))
433 memcpy(&dst
->data_p
[dst
->data_offset
], src
, (size_t)len
);
434 dst
->data_offset
+= len
;
439 /*******************************************************************
440 Copy some data from a parse_struct into a buffer.
441 ********************************************************************/
443 bool prs_copy_data_out(char *dst
, prs_struct
*src
, uint32 len
)
448 if(!prs_mem_get(src
, len
))
451 memcpy(dst
, &src
->data_p
[src
->data_offset
], (size_t)len
);
452 src
->data_offset
+= len
;
457 /*******************************************************************
458 Copy all the data from a parse_struct into a buffer.
459 ********************************************************************/
461 bool prs_copy_all_data_out(char *dst
, prs_struct
*src
)
463 uint32 len
= prs_offset(src
);
468 prs_set_offset(src
, 0);
469 return prs_copy_data_out(dst
, src
, len
);
472 /*******************************************************************
473 Set the data as X-endian (external interface).
474 ********************************************************************/
476 void prs_set_endian_data(prs_struct
*ps
, bool endian
)
478 ps
->bigendian_data
= endian
;
481 /*******************************************************************
482 Align a the data_len to a multiple of align bytes - filling with
484 ********************************************************************/
486 bool prs_align(prs_struct
*ps
)
488 uint32 mod
= ps
->data_offset
& (ps
->align
-1);
490 if (ps
->align
!= 0 && mod
!= 0) {
491 uint32 extra_space
= (ps
->align
- mod
);
492 if(!prs_grow(ps
, extra_space
))
494 memset(&ps
->data_p
[ps
->data_offset
], '\0', (size_t)extra_space
);
495 ps
->data_offset
+= extra_space
;
501 /******************************************************************
502 Align on a 2 byte boundary
503 *****************************************************************/
505 bool prs_align_uint16(prs_struct
*ps
)
508 uint8 old_align
= ps
->align
;
512 ps
->align
= old_align
;
517 /******************************************************************
518 Align on a 8 byte boundary
519 *****************************************************************/
521 bool prs_align_uint64(prs_struct
*ps
)
524 uint8 old_align
= ps
->align
;
528 ps
->align
= old_align
;
533 /******************************************************************
534 Align on a specific byte boundary
535 *****************************************************************/
537 bool prs_align_custom(prs_struct
*ps
, uint8 boundary
)
540 uint8 old_align
= ps
->align
;
542 ps
->align
= boundary
;
544 ps
->align
= old_align
;
551 /*******************************************************************
552 Align only if required (for the unistr2 string mainly)
553 ********************************************************************/
555 bool prs_align_needed(prs_struct
*ps
, uint32 needed
)
560 return prs_align(ps
);
563 /*******************************************************************
564 Ensure we can read/write to a given offset.
565 ********************************************************************/
567 char *prs_mem_get(prs_struct
*ps
, uint32 extra_size
)
569 if(UNMARSHALLING(ps
)) {
571 * If reading, ensure that we can read the requested size item.
573 if (ps
->data_offset
+ extra_size
> ps
->buffer_size
) {
574 DEBUG(0,("prs_mem_get: reading data of size %u would overrun "
575 "buffer by %u bytes.\n",
576 (unsigned int)extra_size
,
577 (unsigned int)(ps
->data_offset
+ extra_size
- ps
->buffer_size
) ));
582 * Writing - grow the buffer if needed.
584 if(!prs_grow(ps
, extra_size
))
587 return &ps
->data_p
[ps
->data_offset
];
590 /*******************************************************************
591 Change the struct type.
592 ********************************************************************/
594 void prs_switch_type(prs_struct
*ps
, bool io
)
596 if ((ps
->io
^ io
) == True
)
600 /*******************************************************************
601 Force a prs_struct to be dynamic even when it's size is 0.
602 ********************************************************************/
604 void prs_force_dynamic(prs_struct
*ps
)
609 /*******************************************************************
610 Associate a session key with a parse struct.
611 ********************************************************************/
613 void prs_set_session_key(prs_struct
*ps
, const char sess_key
[16])
615 ps
->sess_key
= sess_key
;
618 /*******************************************************************
620 ********************************************************************/
622 bool prs_uint8(const char *name
, prs_struct
*ps
, int depth
, uint8
*data8
)
624 char *q
= prs_mem_get(ps
, 1);
628 if (UNMARSHALLING(ps
))
633 DEBUGADD(5,("%s%04x %s: %02x\n", tab_depth(5,depth
), ps
->data_offset
, name
, *data8
));
635 ps
->data_offset
+= 1;
640 /*******************************************************************
642 ********************************************************************/
644 bool prs_uint16(const char *name
, prs_struct
*ps
, int depth
, uint16
*data16
)
646 char *q
= prs_mem_get(ps
, sizeof(uint16
));
650 if (UNMARSHALLING(ps
)) {
651 if (ps
->bigendian_data
)
652 *data16
= RSVAL(q
,0);
656 if (ps
->bigendian_data
)
662 DEBUGADD(5,("%s%04x %s: %04x\n", tab_depth(5,depth
), ps
->data_offset
, name
, *data16
));
664 ps
->data_offset
+= sizeof(uint16
);
669 /*******************************************************************
671 ********************************************************************/
673 bool prs_uint32(const char *name
, prs_struct
*ps
, int depth
, uint32
*data32
)
675 char *q
= prs_mem_get(ps
, sizeof(uint32
));
679 if (UNMARSHALLING(ps
)) {
680 if (ps
->bigendian_data
)
681 *data32
= RIVAL(q
,0);
685 if (ps
->bigendian_data
)
691 DEBUGADD(5,("%s%04x %s: %08x\n", tab_depth(5,depth
), ps
->data_offset
, name
, *data32
));
693 ps
->data_offset
+= sizeof(uint32
);
698 /*******************************************************************
700 ********************************************************************/
702 bool prs_int32(const char *name
, prs_struct
*ps
, int depth
, int32
*data32
)
704 char *q
= prs_mem_get(ps
, sizeof(int32
));
708 if (UNMARSHALLING(ps
)) {
709 if (ps
->bigendian_data
)
710 *data32
= RIVALS(q
,0);
712 *data32
= IVALS(q
,0);
714 if (ps
->bigendian_data
)
715 RSIVALS(q
,0,*data32
);
720 DEBUGADD(5,("%s%04x %s: %08x\n", tab_depth(5,depth
), ps
->data_offset
, name
, *data32
));
722 ps
->data_offset
+= sizeof(int32
);
727 /*******************************************************************
728 Stream a uint64_struct
729 ********************************************************************/
730 bool prs_uint64(const char *name
, prs_struct
*ps
, int depth
, uint64
*data64
)
732 if (UNMARSHALLING(ps
)) {
735 if (!prs_uint32(name
, ps
, depth
+1, &low
))
738 if (!prs_uint32(name
, ps
, depth
+1, &high
))
741 *data64
= ((uint64_t)high
<< 32) + low
;
745 uint32 high
= (*data64
) >> 32, low
= (*data64
) & 0xFFFFFFFF;
746 return prs_uint32(name
, ps
, depth
+1, &low
) &&
747 prs_uint32(name
, ps
, depth
+1, &high
);
751 /*******************************************************************
752 Stream a DCE error code
753 ********************************************************************/
755 bool prs_dcerpc_status(const char *name
, prs_struct
*ps
, int depth
, NTSTATUS
*status
)
757 char *q
= prs_mem_get(ps
, sizeof(uint32
));
761 if (UNMARSHALLING(ps
)) {
762 if (ps
->bigendian_data
)
763 *status
= NT_STATUS(RIVAL(q
,0));
765 *status
= NT_STATUS(IVAL(q
,0));
767 if (ps
->bigendian_data
)
768 RSIVAL(q
,0,NT_STATUS_V(*status
));
770 SIVAL(q
,0,NT_STATUS_V(*status
));
773 DEBUGADD(5,("%s%04x %s: %s\n", tab_depth(5,depth
), ps
->data_offset
, name
,
774 dcerpc_errstr(talloc_tos(), NT_STATUS_V(*status
))));
776 ps
->data_offset
+= sizeof(uint32
);
781 /******************************************************************
782 Stream an array of uint8s. Length is number of uint8s.
783 ********************************************************************/
785 bool prs_uint8s(bool charmode
, const char *name
, prs_struct
*ps
, int depth
, uint8
*data8s
, int len
)
788 char *q
= prs_mem_get(ps
, len
);
792 if (UNMARSHALLING(ps
)) {
793 for (i
= 0; i
< len
; i
++)
794 data8s
[i
] = CVAL(q
,i
);
796 for (i
= 0; i
< len
; i
++)
797 SCVAL(q
, i
, data8s
[i
]);
800 DEBUGADD(5,("%s%04x %s: ", tab_depth(5,depth
), ps
->data_offset
,name
));
802 print_asc(5, (unsigned char*)data8s
, len
);
804 for (i
= 0; i
< len
; i
++)
805 DEBUGADD(5,("%02x ", data8s
[i
]));
809 ps
->data_offset
+= len
;
814 /******************************************************************
815 Stream an array of uint16s. Length is number of uint16s.
816 ********************************************************************/
818 bool prs_uint16s(bool charmode
, const char *name
, prs_struct
*ps
, int depth
, uint16
*data16s
, int len
)
821 char *q
= prs_mem_get(ps
, len
* sizeof(uint16
));
825 if (UNMARSHALLING(ps
)) {
826 if (ps
->bigendian_data
) {
827 for (i
= 0; i
< len
; i
++)
828 data16s
[i
] = RSVAL(q
, 2*i
);
830 for (i
= 0; i
< len
; i
++)
831 data16s
[i
] = SVAL(q
, 2*i
);
834 if (ps
->bigendian_data
) {
835 for (i
= 0; i
< len
; i
++)
836 RSSVAL(q
, 2*i
, data16s
[i
]);
838 for (i
= 0; i
< len
; i
++)
839 SSVAL(q
, 2*i
, data16s
[i
]);
843 DEBUGADD(5,("%s%04x %s: ", tab_depth(5,depth
), ps
->data_offset
, name
));
845 print_asc(5, (unsigned char*)data16s
, 2*len
);
847 for (i
= 0; i
< len
; i
++)
848 DEBUGADD(5,("%04x ", data16s
[i
]));
852 ps
->data_offset
+= (len
* sizeof(uint16
));
857 /******************************************************************
858 Stream an array of uint32s. Length is number of uint32s.
859 ********************************************************************/
861 bool prs_uint32s(bool charmode
, const char *name
, prs_struct
*ps
, int depth
, uint32
*data32s
, int len
)
864 char *q
= prs_mem_get(ps
, len
* sizeof(uint32
));
868 if (UNMARSHALLING(ps
)) {
869 if (ps
->bigendian_data
) {
870 for (i
= 0; i
< len
; i
++)
871 data32s
[i
] = RIVAL(q
, 4*i
);
873 for (i
= 0; i
< len
; i
++)
874 data32s
[i
] = IVAL(q
, 4*i
);
877 if (ps
->bigendian_data
) {
878 for (i
= 0; i
< len
; i
++)
879 RSIVAL(q
, 4*i
, data32s
[i
]);
881 for (i
= 0; i
< len
; i
++)
882 SIVAL(q
, 4*i
, data32s
[i
]);
886 DEBUGADD(5,("%s%04x %s: ", tab_depth(5,depth
), ps
->data_offset
, name
));
888 print_asc(5, (unsigned char*)data32s
, 4*len
);
890 for (i
= 0; i
< len
; i
++)
891 DEBUGADD(5,("%08x ", data32s
[i
]));
895 ps
->data_offset
+= (len
* sizeof(uint32
));
900 /*******************************************************************
901 Stream a unicode null-terminated string. As the string is already
902 in little-endian format then do it as a stream of bytes.
903 ********************************************************************/
905 bool prs_unistr(const char *name
, prs_struct
*ps
, int depth
, UNISTR
*str
)
907 unsigned int len
= 0;
908 unsigned char *p
= (unsigned char *)str
->buffer
;
914 if (MARSHALLING(ps
)) {
916 for(len
= 0; str
->buffer
[len
] != 0; len
++)
919 q
= prs_mem_get(ps
, (len
+1)*2);
925 for(len
= 0; str
->buffer
[len
] != 0; len
++) {
926 if(ps
->bigendian_data
) {
927 /* swap bytes - p is little endian, q is big endian. */
943 * even if the string is 'empty' (only an \0 char)
944 * at this point the leading \0 hasn't been parsed.
954 DEBUGADD(5,("%s%04x %s: ", tab_depth(5,depth
), ps
->data_offset
, name
));
955 print_asc(5, (unsigned char*)start
, 2*len
);
958 else { /* unmarshalling */
960 uint32 alloc_len
= 0;
961 q
= ps
->data_p
+ prs_offset(ps
);
964 * Work out how much space we need and talloc it.
966 max_len
= (ps
->buffer_size
- ps
->data_offset
)/sizeof(uint16
);
968 /* the test of the value of *ptr helps to catch the circumstance
969 where we have an emtpty (non-existent) string in the buffer */
970 for ( ptr
= (uint16
*)q
; *ptr
++ && (alloc_len
<= max_len
); alloc_len
++)
974 if (alloc_len
< max_len
)
977 /* should we allocate anything at all? */
978 str
->buffer
= PRS_ALLOC_MEM(ps
,uint16
,alloc_len
);
979 if ((str
->buffer
== NULL
) && (alloc_len
> 0))
982 p
= (unsigned char *)str
->buffer
;
985 /* the (len < alloc_len) test is to prevent us from overwriting
986 memory that is not ours...if we get that far, we have a non-null
987 terminated string in the buffer and have messed up somewhere */
988 while ((len
< alloc_len
) && (*(uint16
*)q
!= 0)) {
989 if(ps
->bigendian_data
)
991 /* swap bytes - q is big endian, p is little endian. */
992 p
[0] = (unsigned char)q
[1];
993 p
[1] = (unsigned char)q
[0];
998 p
[0] = (unsigned char)q
[0];
999 p
[1] = (unsigned char)q
[1];
1006 if (len
< alloc_len
) {
1007 /* NULL terminate the UNISTR */
1008 str
->buffer
[len
++] = '\0';
1011 DEBUGADD(5,("%s%04x %s: ", tab_depth(5,depth
), ps
->data_offset
, name
));
1012 print_asc(5, (unsigned char*)str
->buffer
, 2*len
);
1013 DEBUGADD(5, ("\n"));
1016 /* set the offset in the prs_struct; 'len' points to the
1017 terminiating NULL in the UNISTR so we need to go one more
1019 ps
->data_offset
+= (len
)*2;
1024 /*******************************************************************
1025 creates a new prs_struct containing a DATA_BLOB
1026 ********************************************************************/
1027 bool prs_init_data_blob(prs_struct
*prs
, DATA_BLOB
*blob
, TALLOC_CTX
*mem_ctx
)
1029 if (!prs_init( prs
, RPC_MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
))
1033 if (!prs_copy_data_in(prs
, (char *)blob
->data
, blob
->length
))
1039 /*******************************************************************
1040 return the contents of a prs_struct in a DATA_BLOB
1041 ********************************************************************/
1042 bool prs_data_blob(prs_struct
*prs
, DATA_BLOB
*blob
, TALLOC_CTX
*mem_ctx
)
1044 blob
->length
= prs_data_size(prs
);
1045 blob
->data
= (uint8
*)TALLOC_ZERO_SIZE(mem_ctx
, blob
->length
);
1047 /* set the pointer at the end of the buffer */
1048 prs_set_offset( prs
, prs_data_size(prs
) );
1050 if (!prs_copy_all_data_out((char *)blob
->data
, prs
))