2 Unix SMB/CIFS implementation.
4 routines for marshalling/unmarshalling basic types
6 Copyright (C) Andrew Tridgell 2003
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.
25 #define NDR_BE(ndr) (((ndr)->flags & (LIBNDR_FLAG_BIGENDIAN|LIBNDR_FLAG_LITTLE_ENDIAN)) == LIBNDR_FLAG_BIGENDIAN)
26 #define NDR_SVAL(ndr, ofs) (NDR_BE(ndr)?RSVAL(ndr->data,ofs):SVAL(ndr->data,ofs))
27 #define NDR_IVAL(ndr, ofs) (NDR_BE(ndr)?RIVAL(ndr->data,ofs):IVAL(ndr->data,ofs))
28 #define NDR_SSVAL(ndr, ofs, v) do { if (NDR_BE(ndr)) { RSSVAL(ndr->data,ofs,v); } else SSVAL(ndr->data,ofs,v); } while (0)
29 #define NDR_SIVAL(ndr, ofs, v) do { if (NDR_BE(ndr)) { RSIVAL(ndr->data,ofs,v); } else SIVAL(ndr->data,ofs,v); } while (0)
34 NTSTATUS ndr_pull_uint8(struct ndr_pull *ndr, uint8_t *v)
36 NDR_PULL_NEED_BYTES(ndr, 1);
37 *v = CVAL(ndr->data, ndr->offset);
46 NTSTATUS ndr_pull_uint16(struct ndr_pull *ndr, uint16_t *v)
48 NDR_PULL_ALIGN(ndr, 2);
49 NDR_PULL_NEED_BYTES(ndr, 2);
50 *v = NDR_SVAL(ndr, ndr->offset);
59 NTSTATUS ndr_pull_uint32(struct ndr_pull *ndr, uint32_t *v)
61 NDR_PULL_ALIGN(ndr, 4);
62 NDR_PULL_NEED_BYTES(ndr, 4);
63 *v = NDR_IVAL(ndr, ndr->offset);
71 NTSTATUS ndr_pull_ptr(struct ndr_pull *ndr, uint32_t *v)
74 status = ndr_pull_uint32(ndr, v);
84 NTSTATUS ndr_pull_uint64(struct ndr_pull *ndr, uint64_t *v)
86 NDR_PULL_ALIGN(ndr, 4);
87 NDR_PULL_NEED_BYTES(ndr, 8);
88 *v = NDR_IVAL(ndr, ndr->offset);
89 *v |= (uint64_t)(NDR_IVAL(ndr, ndr->offset+4)) << 32;
97 NTSTATUS ndr_pull_int64(struct ndr_pull *ndr, int64_t *v)
99 return ndr_pull_uint64(ndr, (uint64_t *)v);
105 NTSTATUS ndr_pull_HYPER_T(struct ndr_pull *ndr, HYPER_T *v)
107 NDR_PULL_ALIGN(ndr, 8);
108 return ndr_pull_uint64(ndr, v);
114 NTSTATUS ndr_pull_NTSTATUS(struct ndr_pull *ndr, NTSTATUS *status)
117 NDR_CHECK(ndr_pull_uint32(ndr, &v));
118 *status = NT_STATUS(v);
125 NTSTATUS ndr_push_NTSTATUS(struct ndr_push *ndr, NTSTATUS status)
127 return ndr_push_uint32(ndr, NT_STATUS_V(status));
130 void ndr_print_NTSTATUS(struct ndr_print *ndr, const char *name, NTSTATUS *r)
132 ndr->print(ndr, "%-25s: %s", name, nt_errstr(*r));
138 NTSTATUS ndr_pull_WERROR(struct ndr_pull *ndr, WERROR *status)
141 NDR_CHECK(ndr_pull_uint32(ndr, &v));
142 *status = W_ERROR(v);
149 NTSTATUS ndr_push_WERROR(struct ndr_push *ndr, WERROR status)
151 return ndr_push_uint32(ndr, W_ERROR_V(status));
154 void ndr_print_WERROR(struct ndr_print *ndr, const char *name, WERROR *r)
156 ndr->print(ndr, "%-25s: %s", name, win_errstr(*r));
162 NTSTATUS ndr_pull_bytes(struct ndr_pull *ndr, char *data, uint32_t n)
164 NDR_PULL_NEED_BYTES(ndr, n);
165 memcpy(data, ndr->data + ndr->offset, n);
171 pull an array of uint8
173 NTSTATUS ndr_pull_array_uint8(struct ndr_pull *ndr, int ndr_flags, char *data, uint32_t n)
175 if (!(ndr_flags & NDR_SCALARS)) {
178 return ndr_pull_bytes(ndr, data, n);
183 pull an array of uint16
185 NTSTATUS ndr_pull_array_uint16(struct ndr_pull *ndr, int ndr_flags, uint16_t *data, uint32_t n)
188 if (!(ndr_flags & NDR_SCALARS)) {
192 NDR_CHECK(ndr_pull_uint16(ndr, &data[i]));
198 pull a const array of uint32_t
200 NTSTATUS ndr_pull_array_uint32(struct ndr_pull *ndr, int ndr_flags, uint32_t *data, uint32_t n)
203 if (!(ndr_flags & NDR_SCALARS)) {
207 NDR_CHECK(ndr_pull_uint32(ndr, &data[i]));
213 pull a const array of HYPER_T
215 NTSTATUS ndr_pull_array_HYPER_T(struct ndr_pull *ndr, int ndr_flags, HYPER_T *data, uint32_t n)
218 if (!(ndr_flags & NDR_SCALARS)) {
222 NDR_CHECK(ndr_pull_HYPER_T(ndr, &data[i]));
230 NTSTATUS ndr_push_uint8(struct ndr_push *ndr, uint8_t v)
232 NDR_PUSH_NEED_BYTES(ndr, 1);
233 SCVAL(ndr->data, ndr->offset, v);
241 NTSTATUS ndr_push_uint16(struct ndr_push *ndr, uint16_t v)
243 NDR_PUSH_ALIGN(ndr, 2);
244 NDR_PUSH_NEED_BYTES(ndr, 2);
245 NDR_SSVAL(ndr, ndr->offset, v);
253 NTSTATUS ndr_push_uint32(struct ndr_push *ndr, uint32_t v)
255 NDR_PUSH_ALIGN(ndr, 4);
256 NDR_PUSH_NEED_BYTES(ndr, 4);
257 NDR_SIVAL(ndr, ndr->offset, v);
265 NTSTATUS ndr_push_uint64(struct ndr_push *ndr, uint64_t v)
267 NDR_PUSH_ALIGN(ndr, 4);
268 NDR_PUSH_NEED_BYTES(ndr, 8);
269 NDR_SIVAL(ndr, ndr->offset, (v & 0xFFFFFFFF));
270 NDR_SIVAL(ndr, ndr->offset+4, (v>>32));
278 NTSTATUS ndr_push_int64(struct ndr_push *ndr, int64_t v)
280 return ndr_push_uint64(ndr, (uint64_t)v);
286 NTSTATUS ndr_push_HYPER_T(struct ndr_push *ndr, HYPER_T v)
288 NDR_PUSH_ALIGN(ndr, 8);
289 return ndr_push_uint64(ndr, v);
292 NTSTATUS ndr_push_align(struct ndr_push *ndr, size_t size)
294 NDR_PUSH_ALIGN(ndr, size);
298 NTSTATUS ndr_pull_align(struct ndr_pull *ndr, size_t size)
300 NDR_PULL_ALIGN(ndr, size);
307 NTSTATUS ndr_push_bytes(struct ndr_push *ndr, const char *data, uint32_t n)
309 NDR_PUSH_NEED_BYTES(ndr, n);
310 memcpy(ndr->data + ndr->offset, data, n);
318 NTSTATUS ndr_push_zero(struct ndr_push *ndr, uint32_t n)
320 NDR_PUSH_NEED_BYTES(ndr, n);
321 memset(ndr->data + ndr->offset, 0, n);
327 push an array of uint8
329 NTSTATUS ndr_push_array_uint8(struct ndr_push *ndr, int ndr_flags, const char *data, uint32_t n)
331 if (!(ndr_flags & NDR_SCALARS)) {
334 return ndr_push_bytes(ndr, data, n);
338 push an array of uint16
340 NTSTATUS ndr_push_array_uint16(struct ndr_push *ndr, int ndr_flags, const uint16_t *data, uint32_t n)
343 if (!(ndr_flags & NDR_SCALARS)) {
347 NDR_CHECK(ndr_push_uint16(ndr, data[i]));
353 push an array of uint32_t
355 NTSTATUS ndr_push_array_uint32(struct ndr_push *ndr, int ndr_flags, const uint32_t *data, uint32_t n)
358 if (!(ndr_flags & NDR_SCALARS)) {
362 NDR_CHECK(ndr_push_uint32(ndr, data[i]));
368 push an array of HYPER_T
370 NTSTATUS ndr_push_array_HYPER_T(struct ndr_push *ndr, int ndr_flags, const HYPER_T *data, uint32_t n)
373 if (!(ndr_flags & NDR_SCALARS)) {
377 NDR_CHECK(ndr_push_HYPER_T(ndr, data[i]));
383 save the current position
385 void ndr_push_save(struct ndr_push *ndr, struct ndr_push_save *save)
387 save->offset = ndr->offset;
393 void ndr_push_restore(struct ndr_push *ndr, struct ndr_push_save *save)
395 ndr->offset = save->offset;
399 push a 1 if a pointer is non-NULL, otherwise 0
401 NTSTATUS ndr_push_ptr(struct ndr_push *ndr, const void *p)
405 /* we do this to ensure that we generate unique ref ids,
406 which means we can handle the case where a MS programmer
407 forgot to mark a pointer as unique */
409 ptr = ndr->ptr_count;
411 return ndr_push_uint32(ndr, ptr);
416 pull a general string from the wire
418 NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s)
421 uint32_t len1, ofs, len2;
426 if (!(ndr_flags & NDR_SCALARS)) {
434 switch (ndr->flags & LIBNDR_STRING_FLAGS) {
435 case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
436 case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM:
437 NDR_CHECK(ndr_pull_uint32(ndr, &len1));
438 NDR_CHECK(ndr_pull_uint32(ndr, &ofs));
439 NDR_CHECK(ndr_pull_uint32(ndr, &len2));
441 return ndr_pull_error(ndr, NDR_ERR_STRING,
442 "Bad string lengths len1=%u ofs=%u len2=%u\n",
446 *s = talloc_strdup(ndr->mem_ctx, "");
449 NDR_PULL_NEED_BYTES(ndr, len2*2);
450 ret = convert_string_talloc(ndr->mem_ctx, chset, CH_UNIX,
451 ndr->data+ndr->offset,
455 return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
456 "Bad character conversion");
458 NDR_CHECK(ndr_pull_advance(ndr, len2*2));
460 /* this is a way of detecting if a string is sent with the wrong
462 if (ndr->flags & LIBNDR_FLAG_STR_NOTERM) {
463 if (strlen(as) < len2) {
464 DEBUG(6,("short string '%s'\n", as));
467 if (strlen(as) == len2) {
468 DEBUG(6,("long string '%s'\n", as));
474 case LIBNDR_FLAG_STR_SIZE4:
475 NDR_CHECK(ndr_pull_uint32(ndr, &len1));
476 NDR_PULL_NEED_BYTES(ndr, len1*2);
478 *s = talloc_strdup(ndr->mem_ctx, "");
481 ret = convert_string_talloc(ndr->mem_ctx, chset, CH_UNIX,
482 ndr->data+ndr->offset,
486 return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
487 "Bad character conversion");
489 NDR_CHECK(ndr_pull_advance(ndr, len1*2));
493 case LIBNDR_FLAG_STR_NULLTERM:
494 len1 = strnlen_w(ndr->data+ndr->offset,
495 (ndr->data_size - ndr->offset)/2);
496 if (len1*2+2 <= ndr->data_size - ndr->offset) {
499 ret = convert_string_talloc(ndr->mem_ctx, chset, CH_UNIX,
500 ndr->data+ndr->offset,
504 return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
505 "Bad character conversion");
507 NDR_CHECK(ndr_pull_advance(ndr, len1*2));
510 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
511 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM:
512 NDR_CHECK(ndr_pull_uint32(ndr, &len1));
513 NDR_CHECK(ndr_pull_uint32(ndr, &ofs));
514 NDR_CHECK(ndr_pull_uint32(ndr, &len2));
516 return ndr_pull_error(ndr, NDR_ERR_STRING,
517 "Bad ascii string lengths len1=%u ofs=%u len2=%u\n",
520 NDR_ALLOC_N(ndr, as, (len2+1));
521 NDR_CHECK(ndr_pull_bytes(ndr, as, len2));
526 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4:
527 NDR_CHECK(ndr_pull_uint32(ndr, &ofs));
528 NDR_CHECK(ndr_pull_uint32(ndr, &len2));
529 NDR_ALLOC_N(ndr, as, (len2+1));
530 NDR_CHECK(ndr_pull_bytes(ndr, as, len2));
535 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_SIZE2:
536 NDR_CHECK(ndr_pull_uint16(ndr, &len3));
537 NDR_ALLOC_N(ndr, as, (len3+1));
538 NDR_CHECK(ndr_pull_bytes(ndr, as, len3));
543 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM:
544 len1 = strnlen(ndr->data+ndr->offset, (ndr->data_size - ndr->offset));
545 if (len1+1 <= ndr->data_size - ndr->offset) {
548 NDR_ALLOC_N(ndr, as, (len1+1));
549 NDR_CHECK(ndr_pull_bytes(ndr, as, len1));
555 return ndr_pull_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",
556 ndr->flags & LIBNDR_STRING_FLAGS);
564 push a general string onto the wire
566 NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s)
568 ssize_t s_len, c_len;
572 if (!(ndr_flags & NDR_SCALARS)) {
580 s_len = s?strlen(s):0;
581 c_len = s?strlen_m(s):0;
583 switch (ndr->flags & LIBNDR_STRING_FLAGS) {
584 case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
585 NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
586 NDR_CHECK(ndr_push_uint32(ndr, 0));
587 NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
588 NDR_PUSH_NEED_BYTES(ndr, c_len*2 + 2);
589 ret = convert_string(CH_UNIX, chset,
591 ndr->data+ndr->offset, c_len*2 + 2);
593 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
594 "Bad character conversion");
596 ndr->offset += c_len*2 + 2;
599 case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM:
600 NDR_CHECK(ndr_push_uint32(ndr, c_len));
601 NDR_CHECK(ndr_push_uint32(ndr, 0));
602 NDR_CHECK(ndr_push_uint32(ndr, c_len));
603 NDR_PUSH_NEED_BYTES(ndr, c_len*2);
604 ret = convert_string(CH_UNIX, chset,
606 ndr->data+ndr->offset, c_len*2);
608 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
609 "Bad character conversion");
611 ndr->offset += c_len*2;
614 case LIBNDR_FLAG_STR_SIZE4:
615 NDR_CHECK(ndr_push_uint32(ndr, c_len + 1));
616 NDR_PUSH_NEED_BYTES(ndr, c_len*2 + 2);
617 ret = convert_string(CH_UNIX, chset,
619 ndr->data+ndr->offset, c_len*2 + 2);
621 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
622 "Bad character conversion");
624 ndr->offset += c_len*2 + 2;
627 case LIBNDR_FLAG_STR_NULLTERM:
628 NDR_PUSH_NEED_BYTES(ndr, c_len*2 + 2);
629 ret = convert_string(CH_UNIX, chset,
631 ndr->data+ndr->offset, c_len*2 + 2);
633 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
634 "Bad character conversion");
636 ndr->offset += c_len*2 + 2;
639 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
640 NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
641 NDR_CHECK(ndr_push_uint32(ndr, 0));
642 NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
643 NDR_PUSH_NEED_BYTES(ndr, c_len + 1);
644 ret = convert_string(CH_UNIX, CH_DOS,
646 ndr->data+ndr->offset, c_len + 1);
648 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
649 "Bad character conversion");
651 ndr->offset += c_len + 1;
654 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM:
655 NDR_CHECK(ndr_push_uint32(ndr, c_len));
656 NDR_CHECK(ndr_push_uint32(ndr, 0));
657 NDR_CHECK(ndr_push_uint32(ndr, c_len));
658 NDR_PUSH_NEED_BYTES(ndr, c_len);
659 ret = convert_string(CH_UNIX, CH_DOS,
661 ndr->data+ndr->offset, c_len);
663 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
664 "Bad character conversion");
666 ndr->offset += c_len;
669 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4:
670 NDR_CHECK(ndr_push_uint32(ndr, 0));
671 NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
672 NDR_PUSH_NEED_BYTES(ndr, c_len + 1);
673 ret = convert_string(CH_UNIX, CH_DOS,
675 ndr->data+ndr->offset, c_len + 1);
677 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
678 "Bad character conversion");
680 ndr->offset += c_len + 1;
683 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_SIZE2:
684 NDR_CHECK(ndr_push_uint16(ndr, c_len+1));
685 NDR_PUSH_NEED_BYTES(ndr, c_len + 1);
686 ret = convert_string(CH_UNIX, CH_DOS,
688 ndr->data+ndr->offset, c_len + 1);
690 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
691 "Bad character conversion");
693 ndr->offset += c_len + 1;
696 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM:
697 NDR_PUSH_NEED_BYTES(ndr, c_len + 1);
698 ret = convert_string(CH_UNIX, CH_DOS,
700 ndr->data+ndr->offset, c_len + 1);
702 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
703 "Bad character conversion");
705 ndr->offset += c_len + 1;
709 return ndr_push_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",
710 ndr->flags & LIBNDR_STRING_FLAGS);
719 NTSTATUS ndr_push_NTTIME(struct ndr_push *ndr, NTTIME t)
721 NDR_CHECK(ndr_push_uint64(ndr, t));
728 NTSTATUS ndr_pull_NTTIME(struct ndr_pull *ndr, NTTIME *t)
730 NDR_CHECK(ndr_pull_uint64(ndr, t));
737 NTSTATUS ndr_push_time_t(struct ndr_push *ndr, time_t t)
739 return ndr_push_uint32(ndr, t);
745 NTSTATUS ndr_pull_time_t(struct ndr_pull *ndr, time_t *t)
748 NDR_CHECK(ndr_pull_uint32(ndr, &tt));
754 void ndr_print_struct(struct ndr_print *ndr, const char *name, const char *type)
756 ndr->print(ndr, "%s: struct %s", name, type);
759 void ndr_print_uint8(struct ndr_print *ndr, const char *name, uint8_t v)
761 ndr->print(ndr, "%-25s: 0x%02x (%u)", name, v, v);
764 void ndr_print_uint16(struct ndr_print *ndr, const char *name, uint16_t v)
766 ndr->print(ndr, "%-25s: 0x%04x (%u)", name, v, v);
769 void ndr_print_uint32(struct ndr_print *ndr, const char *name, uint32_t v)
771 ndr->print(ndr, "%-25s: 0x%08x (%u)", name, v, v);
774 void ndr_print_uint64(struct ndr_print *ndr, const char *name, uint64_t v)
776 ndr->print(ndr, "%-25s: 0x%08x%08x", name, (uint32_t)(v >> 32), (uint32_t)(v & 0xFFFFFFFF));
779 void ndr_print_int64(struct ndr_print *ndr, const char *name, int64_t v)
781 ndr->print(ndr, "%-25s: 0x%08x%08x (%lld)", name,
783 (uint32_t)(v & 0xFFFFFFFF),
787 void ndr_print_HYPER_T(struct ndr_print *ndr, const char *name, HYPER_T v)
789 ndr->print(ndr, "%-25s: 0x%08x%08x", name, (uint32_t)(v >> 32), (uint32_t)(v & 0xFFFFFFFF));
792 void ndr_print_ptr(struct ndr_print *ndr, const char *name, const void *p)
795 ndr->print(ndr, "%-25s: *", name);
797 ndr->print(ndr, "%-25s: NULL", name);
801 void ndr_print_string(struct ndr_print *ndr, const char *name, const char *s)
804 ndr->print(ndr, "%-25s: '%s'", name, s);
806 ndr->print(ndr, "%-25s: NULL", name);
810 void ndr_print_NTTIME(struct ndr_print *ndr, const char *name, NTTIME t)
812 ndr->print(ndr, "%-25s: %s", name, nt_time_string(ndr->mem_ctx, t));
815 void ndr_print_time_t(struct ndr_print *ndr, const char *name, time_t t)
817 if (t == (time_t)-1 || t == 0) {
818 ndr->print(ndr, "%-25s: (time_t)%d", name, (int)t);
820 ndr->print(ndr, "%-25s: %s", name, timestring(ndr->mem_ctx, t));
824 void ndr_print_union(struct ndr_print *ndr, const char *name, uint16_t level, const char *type)
826 ndr->print(ndr, "%-25s: union %s(case %u)", name, type, level);
829 void ndr_print_bad_level(struct ndr_print *ndr, const char *name, uint16_t level)
831 ndr->print(ndr, "UNKNOWN LEVEL %u", level);
834 void ndr_print_array_HYPER_T(struct ndr_print *ndr, const char *name,
835 const HYPER_T *data, uint32_t count)
839 ndr->print(ndr, "%s: ARRAY(%d)", name, count);
841 for (i=0;i<count;i++) {
843 asprintf(&idx, "[%d]", i);
845 ndr_print_HYPER_T(ndr, idx, data[i]);
852 void ndr_print_array_uint32(struct ndr_print *ndr, const char *name,
853 const uint32_t *data, uint32_t count)
857 ndr->print(ndr, "%s: ARRAY(%d)", name, count);
859 for (i=0;i<count;i++) {
861 asprintf(&idx, "[%d]", i);
863 ndr_print_uint32(ndr, idx, data[i]);
870 void ndr_print_array_uint16(struct ndr_print *ndr, const char *name,
871 const uint16_t *data, uint32_t count)
875 ndr->print(ndr, "%s: ARRAY(%d)", name, count);
877 for (i=0;i<count;i++) {
879 asprintf(&idx, "[%d]", i);
881 ndr_print_uint16(ndr, idx, data[i]);
888 void ndr_print_array_uint8(struct ndr_print *ndr, const char *name,
889 const uint8_t *data, uint32_t count)
893 if (count <= 600 && (ndr->flags & LIBNDR_PRINT_ARRAY_HEX)) {
895 for (i=0;i<count;i++) {
896 snprintf(&s[i*2], 3, "%02x", data[i]);
899 ndr->print(ndr, "%-25s: %s", name, s);
903 ndr->print(ndr, "%s: ARRAY(%d)", name, count);
905 for (i=0;i<count;i++) {
907 asprintf(&idx, "[%d]", i);
909 ndr_print_uint8(ndr, idx, data[i]);
917 build a GUID from a string
919 NTSTATUS GUID_from_string(const char *s, struct GUID *guid)
922 uint32_t time_mid, time_hi_and_version;
923 uint32_t clock_seq[2];
927 if (11 != sscanf(s, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
928 &time_low, &time_mid, &time_hi_and_version,
929 &clock_seq[0], &clock_seq[1],
930 &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
931 return NT_STATUS_INVALID_PARAMETER;
934 guid->time_low = time_low;
935 guid->time_mid = time_mid;
936 guid->time_hi_and_version = time_hi_and_version;
937 guid->clock_seq[0] = clock_seq[0];
938 guid->clock_seq[1] = clock_seq[1];
940 guid->node[i] = node[i];
947 its useful to be able to display these in debugging messages
949 const char *GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid)
951 return talloc_asprintf(mem_ctx,
952 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
953 guid->time_low, guid->time_mid,
954 guid->time_hi_and_version,
957 guid->node[0], guid->node[1],
958 guid->node[2], guid->node[3],
959 guid->node[4], guid->node[5]);
962 void ndr_print_GUID(struct ndr_print *ndr, const char *name, const struct GUID *guid)
964 ndr->print(ndr, "%-25s: %s", name, GUID_string(ndr->mem_ctx, guid));
967 void ndr_print_DATA_BLOB(struct ndr_print *ndr, const char *name, DATA_BLOB r)
969 ndr->print(ndr, "%-25s: DATA_BLOB length=%u", name, r.length);
971 dump_data(10, r.data, r.length);
977 push a DATA_BLOB onto the wire.
979 NTSTATUS ndr_push_DATA_BLOB(struct ndr_push *ndr, DATA_BLOB blob)
981 if (ndr->flags & LIBNDR_ALIGN_FLAGS) {
982 if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
983 blob.length = NDR_ALIGN(ndr, 2);
984 } else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
985 blob.length = NDR_ALIGN(ndr, 4);
986 } else if (ndr->flags & LIBNDR_FLAG_ALIGN8) {
987 blob.length = NDR_ALIGN(ndr, 8);
989 NDR_PUSH_ALLOC_SIZE(ndr, blob.data, blob.length);
990 data_blob_clear(&blob);
991 } else if (!(ndr->flags & LIBNDR_FLAG_REMAINING)) {
992 NDR_CHECK(ndr_push_uint32(ndr, blob.length));
994 NDR_CHECK(ndr_push_bytes(ndr, blob.data, blob.length));
999 pull a DATA_BLOB from the wire.
1001 NTSTATUS ndr_pull_DATA_BLOB(struct ndr_pull *ndr, DATA_BLOB *blob)
1005 if (ndr->flags & LIBNDR_ALIGN_FLAGS) {
1006 if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
1007 length = NDR_ALIGN(ndr, 2);
1008 } else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
1009 length = NDR_ALIGN(ndr, 4);
1010 } else if (ndr->flags & LIBNDR_FLAG_ALIGN8) {
1011 length = NDR_ALIGN(ndr, 8);
1013 if (ndr->data_size - ndr->offset < length) {
1014 length = ndr->data_size - ndr->offset;
1016 } else if (ndr->flags & LIBNDR_FLAG_REMAINING) {
1017 length = ndr->data_size - ndr->offset;
1019 NDR_CHECK(ndr_pull_uint32(ndr, &length));
1021 NDR_PULL_NEED_BYTES(ndr, length);
1022 *blob = data_blob_talloc(ndr->mem_ctx, ndr->data+ndr->offset, length);
1023 ndr->offset += length;
1024 return NT_STATUS_OK;