4static int TestNdrBasic_1(
void)
13 0x02, 0x00, 0x00, 0x00,
18 wStream* s = Stream_StaticInit(&staticS, payload,
sizeof(payload));
20 BYTE* target =
nullptr;
23 (
void*)&target, TRUE, winpr_ndr_uint8Array_descr() };
39#define NDR_TYPEDEF(V) \
40 static BOOL ndr_descr_read_##V(WinPrNdrDecoder* context, wStream* s, const void* hints, \
43 WINPR_UNUSED(hints); \
44 return winpr_ndr_decoder_read_fromDescr(context, s, &V##_struct, obj); \
46 static BOOL ndr_descr_write_##V(WinPrNdrEncoder* context, wStream* s, const void* hints, \
49 WINPR_UNUSED(hints); \
50 return winpr_ndr_encoder_write_fromDescr(context, s, &V##_struct, obj); \
52 static void ndr_descr_destroy_##V(const void* hints, void* obj) \
54 WINPR_UNUSED(hints); \
55 winpr_ndr_struct_destroy(&V##_struct, obj); \
57 static void ndr_descr_dump_##V(wLog* logger, UINT32 lvl, size_t indentLevel, const void* obj) \
59 winpr_ndr_struct_dump_fromDescr(logger, lvl, indentLevel, &V##_struct, obj); \
62 static WinPrNdrMessageDescr ndr_##V##_descr_s = { \
63 WINPR_NDR_ARITY_SIMPLE, sizeof(V), ndr_descr_read_##V, ndr_descr_write_##V, \
64 ndr_descr_destroy_##V, ndr_descr_dump_##V, \
67 WinPrNdrMessageType ndr_##V##_descr(void) \
69 return &ndr_##V##_descr_s; \
80 &winpr_ndr_uint32_descr_s },
86 ARRAYSIZE(REDIR_SCARDCONTEXT_fields),
87 REDIR_SCARDCONTEXT_fields };
100 &winpr_ndr_uint32_descr_s },
102 &ndr_REDIR_SCARDCONTEXT_descr_s },
106 "EstablishContext_Return", ARRAYSIZE(EstablishContext_Return_fields),
107 EstablishContext_Return_fields
114static int TestNdrStaticArrayRead(
void)
118 unsigned char payload[] = { 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
119 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
121 0x0, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0,
122 0x0, 0x0, 0x2, 0x0, 0x8, 0x0, 0x0, 0x0,
123 0x49, 0x91, 0xe4, 0x7c, 0x0, 0x0, 0x0, 0x0 };
125 wStream* s = Stream_StaticConstInit(&staticS, payload,
sizeof(payload));
134 !ndr_EstablishContext_Return_descr_s.readFn(decoder, &cpayload,
nullptr, &context) ||
139 unsigned char expected[] = { 0x49, 0x91, 0xe4, 0x7c, 0x0, 0x0, 0x0, 0x0 };
140 if (context.hContext.cbContext != 8 || memcmp(context.hContext.pbContext, expected, 8) != 0)
149static int TestNdrStaticArrayWrite(
void)
158 wStream* s = Stream_StaticInit(&staticS, buffer,
sizeof(buffer));
161 context.cbContext = 10;
162 for (
int i = 0; i < 10; i++)
163 context.pbContext[i] = i + 1;
168 Stream_SealLength(s);
170 unsigned char expected[] = {
171 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0xa, 0x0, 0x0,
172 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
175 if (Stream_Length(s) !=
sizeof(expected))
178 retCode = memcmp(Stream_Buffer(s), expected,
sizeof(expected));
184static int TestNdrStaticArrayOverflow(
void)
187 unsigned char payload[] = { 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x30, 0x00,
188 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
190 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0,
191 0x2, 0x0, 0x20, 0x0, 0x0, 0x0, 0x41, 0x41, 0x41, 0x41,
192 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
193 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
194 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 };
196 wStream* s = Stream_StaticConstInit(&staticS, payload,
sizeof(payload));
206 ndr_EstablishContext_Return_descr_s.readFn(decoder, &cpayload,
nullptr, &context) &&
226 &winpr_ndr_uint8Array_descr_s },
229static const WinPrNdrStructDescr TEST_BLOB_struct = {
"TEST_BLOB", ARRAYSIZE(TEST_BLOB_fields),
232NDR_TYPEDEF(TEST_BLOB)
234static BOOL ndr_read_TEST_BLOB_array(WinPrNdrDecoder* context,
wStream* s,
const void* hints,
240static BOOL ndr_write_TEST_BLOB_array(WinPrNdrEncoder* context,
wStream* s,
const void* hints,
245 &ndr_TEST_BLOB_descr_s, v);
248static void ndr_destroy_TEST_BLOB_array(
const void* hints,
void* obj)
251 TEST_BLOB* blobs = obj;
252 for (UINT32 i = 0; i < ahints->
count; i++)
258 ndr_write_TEST_BLOB_array, ndr_destroy_TEST_BLOB_array,
nullptr
269 &winpr_ndr_uint32_descr_s },
270 {
"blobs", offsetof(TEST_BLOBS, blobs),
WINPR_NDR_POINTER, 0, &ndr_TEST_BLOB_array_descr_s },
273static const WinPrNdrStructDescr TEST_BLOBS_struct = {
"TEST_BLOBS", ARRAYSIZE(TEST_BLOBS_fields),
277static const BYTE blobsPayload[] = {
278 0x02, 0x00, 0x00, 0x00,
279 0x00, 0x00, 0x02, 0x00,
280 0x02, 0x00, 0x00, 0x00,
281 0x01, 0x00, 0x00, 0x00,
282 0x04, 0x00, 0x02, 0x00,
283 0x02, 0x00, 0x00, 0x00,
284 0x08, 0x00, 0x02, 0x00,
285 0x01, 0x00, 0x00, 0x00,
286 'A', 0x00, 0x00, 0x00,
287 0x02, 0x00, 0x00, 0x00,
291static int TestNdrDeferredOrderWrite(
void)
294 BYTE data0[] = {
'A' };
295 BYTE data1[] = {
'B',
'C' };
296 TEST_BLOB items[] = { { 1, data0 }, { 2, data1 } };
297 TEST_BLOBS blobs = { { 2 }, items };
300 wStream* s = Stream_New(
nullptr, 100);
310 if ((Stream_GetPosition(s) !=
sizeof(blobsPayload)) ||
311 (memcmp(Stream_Buffer(s), blobsPayload,
sizeof(blobsPayload)) != 0))
316 Stream_Free(s, TRUE);
321static int TestNdrDeferredOrderRead(
void)
324 TEST_BLOBS blobs = WINPR_C_ARRAY_INIT;
326 wStream* s = Stream_StaticConstInit(&staticS, blobsPayload,
sizeof(blobsPayload));
337 if ((Stream_GetRemainingLength(s) != 0) || (blobs.hints.count != 2) || !blobs.blobs)
341 if ((blobs.blobs[0].count != 1) || (blobs.blobs[0].data[0] !=
'A') ||
342 (blobs.blobs[1].count != 2) || (memcmp(blobs.blobs[1].data,
"BC", 2) != 0))
352static int TestNdrObject(
void)
356 wStream* s = Stream_New(
nullptr, 100);
364 !winpr_ndr_encoder_write_uint16(encoder, s, 0x1234) ||
369 const BYTE expected[] = { 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
370 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
371 0x00, 0x00, 0x02, 0x00, 0x34, 0x12, 0x00, 0x00 };
373 if ((Stream_GetPosition(s) !=
sizeof(expected)) ||
374 (memcmp(Stream_Buffer(s), expected,
sizeof(expected)) != 0))
378 Stream_SealLength(s);
379 Stream_SetPosition(s, 0);
382 wStream object = WINPR_C_ARRAY_INIT;
386 (Stream_GetRemainingLength(s) == 0) &&
388 (refId == 0x20000) && winpr_ndr_decoder_read_uint16(decoder, &
object, &v) &&
394 Stream_Free(s, TRUE);
400static int TestNdrSignedTypes(
void)
402 for (
int bigEndian = 0; bigEndian < 2; bigEndian++)
406 WinPrNdrDecoder* decoder =
nullptr;
407 wStream* s = Stream_New(
nullptr, 64);
413 const INT16 i16 = -0x1234;
414 const INT64 i64 = -0x123456789abcdefLL;
415 if (!winpr_ndr_encoder_write_int8(encoder, s, i8) ||
416 !winpr_ndr_encoder_write_int16(encoder, s, i16) ||
417 !winpr_ndr_encoder_write_int8_(encoder, s,
nullptr, &i8) ||
418 !winpr_ndr_encoder_write_int64(encoder, s, i64))
421 const BYTE expectedLE[] = { 0xfe, 0x00, 0xcc, 0xed, 0xfe, 0x00, 0x00, 0x00,
422 0x11, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe };
423 const BYTE expectedBE[] = { 0xfe, 0x00, 0xed, 0xcc, 0xfe, 0x00, 0x00, 0x00,
424 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x11 };
425 const BYTE* expected = bigEndian ? expectedBE : expectedLE;
427 if ((Stream_GetPosition(s) !=
sizeof(expectedLE)) ||
428 (memcmp(Stream_Buffer(s), expected,
sizeof(expectedLE)) != 0))
432 Stream_SealLength(s);
433 Stream_SetPosition(s, 0);
439 if (!decoder || !winpr_ndr_decoder_read_int8(decoder, s, &r8) ||
440 !winpr_ndr_int16_descr()->readFn(decoder, s,
nullptr, &r16) ||
441 !winpr_ndr_decoder_read_int8_(decoder, s,
nullptr, &r8bis) ||
442 !winpr_ndr_decoder_read_int64(decoder, s, &r64))
446 if ((r8 != i8) || (r16 != i16) || (r8bis != i8) || (r64 != i64) ||
447 (Stream_GetRemainingLength(s) != 0) || (winpr_ndr_int8_descr()->itemSize != 1) ||
448 (winpr_ndr_int16_descr()->itemSize != 2) || (winpr_ndr_int64_descr()->itemSize != 8))
455 Stream_Free(s, TRUE);
457 return retCode - (bigEndian * 10);
465static const BYTE wcharMemory[] = {
'a', 0x00, 0xac, 0x20 };
467static const BYTE wcharArrayLE[] = { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
468 0x02, 0x00, 0x00, 0x00,
'a', 0x00, 0xac, 0x20 };
469static const BYTE wcharArrayBE[] = { 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
470 0x00, 0x00, 0x00, 0x02, 0x00,
'a', 0x20, 0xac };
472static int TestNdrWchar(
void)
474 for (
int bigEndian = 0; bigEndian < 2; bigEndian++)
476 const BYTE* expected = bigEndian ? wcharArrayBE : wcharArrayLE;
477 WCHAR str[ARRAYSIZE(wcharMemory) /
sizeof(WCHAR) + 1] = WINPR_C_ARRAY_INIT;
478 WCHAR* decodedStr =
nullptr;
479 WCHAR decoded[ARRAYSIZE(str)] = WINPR_C_ARRAY_INIT;
480 memcpy(str, wcharMemory,
sizeof(wcharMemory));
483 WinPrNdrDecoder* decoder =
nullptr;
485 wStream* s = Stream_New(
nullptr, 64);
492 if (!winpr_ndr_wcharVaryingArray_descr()->writeFn(encoder, s, &countHints, str) ||
493 (Stream_GetPosition(s) !=
sizeof(wcharArrayLE)) ||
494 (memcmp(Stream_Buffer(s), expected,
sizeof(wcharArrayLE)) != 0))
499 Stream_SealLength(s);
500 Stream_SetPosition(s, 0);
504 !winpr_ndr_wcharVaryingArray_descr()->readFn(decoder, s, &byteHints, decoded) ||
505 (Stream_GetRemainingLength(s) != 0) ||
506 (memcmp(decoded, wcharMemory,
sizeof(wcharMemory)) != 0))
511 const WCHAR* pstr = str;
512 Stream_SetPosition(s, 0);
517 Stream_SealLength(s);
518 Stream_SetPosition(s, 0);
523 !decodedStr || (memcmp(decodedStr, wcharMemory,
sizeof(wcharMemory)) != 0) ||
524 (decodedStr[ARRAYSIZE(str) - 1] != 0))
532 Stream_Free(s, TRUE);
534 return retCode - (bigEndian * 10);
541static BOOL decode_payload(
const WinPrNdrStructDescr* descr,
const BYTE* payload,
size_t len,
545 wStream* s = Stream_StaticConstInit(&staticS, payload, len);
550 (Stream_GetRemainingLength(s) == 0);
566static const WinPrNdrStructDescr FULL_PAIR_struct = {
"FULL_PAIR", ARRAYSIZE(FULL_PAIR_fields),
570static int TestNdrFullPointerAlias(
void)
572 const BYTE payload[] = {
573 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x78, 0x56, 0x34, 0x12
575 FULL_PAIR pair = WINPR_C_ARRAY_INIT;
578 if (!decode_payload(&FULL_PAIR_struct, payload,
sizeof(payload), &pair))
582 if (!pair.a || (pair.a != pair.b) || (*pair.a != 0x12345678))
590 if (pair.a || pair.b || (*kept != 0x12345678))
598 const BYTE payload2[] = { 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00,
599 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00 };
601 if (!decode_payload(&FULL_PAIR_struct, payload2,
sizeof(payload2), &pair) ||
602 (pair.a == pair.b) || (*pair.a != 1) || (*pair.b != 2))
622static const WinPrNdrStructDescr FULL_MIXED_struct = {
"FULL_MIXED", ARRAYSIZE(FULL_MIXED_fields),
632 {
"u", offsetof(UNIQUE_FULL, u),
WINPR_NDR_POINTER, -1, &winpr_ndr_uint32_descr_s },
637 ARRAYSIZE(UNIQUE_FULL_fields),
638 UNIQUE_FULL_fields };
656 ARRAYSIZE(FULL_ARRAYS_fields),
657 FULL_ARRAYS_fields };
660static int TestNdrFullPointerConfusion(
void)
665 const BYTE mixed[] = { 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x78, 0x56, 0x34, 0x12 };
666 FULL_MIXED fmixed = WINPR_C_ARRAY_INIT;
667 const BOOL mixedOk = decode_payload(&FULL_MIXED_struct, mixed,
sizeof(mixed), &fmixed);
674 UNIQUE_FULL ufull = WINPR_C_ARRAY_INIT;
675 const BOOL ufullOk = decode_payload(&UNIQUE_FULL_struct, mixed,
sizeof(mixed), &ufull);
682 const BYTE arrays[] = { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00,
683 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00,
'A',
'B' };
684 FULL_ARRAYS farrays = WINPR_C_ARRAY_INIT;
685 const BOOL arraysOk = decode_payload(&FULL_ARRAYS_struct, arrays,
sizeof(arrays), &farrays) &&
686 farrays.a && (farrays.a == farrays.b) &&
687 (memcmp(farrays.a,
"AB", 2) == 0);
694 const BYTE sizes[] = { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 0x00, 0x00,
695 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00,
'A',
'B' };
696 const BOOL sizesOk = decode_payload(&FULL_ARRAYS_struct, sizes,
sizeof(sizes), &farrays);
716 { 0x20, {
"Pointer", 0,
WINPR_NDR_POINTER, -1, &winpr_ndr_uint32_descr_s, 0, 0 } },
721static const WinPrNdrUnionDescr SHORT_UNION_union = {
"SHORT_UNION", ARRAYSIZE(SHORT_UNION_arms),
722 SHORT_UNION_arms, 2, &SHORT_UNION_default };
734 &winpr_ndr_uint16_descr_s, 0, 0 },
739 ARRAYSIZE(SHORT_SWITCH_fields),
740 SHORT_SWITCH_fields, 4 };
742static const BYTE shortSwitchPointer[] = {
743 0x20, 0x00, 0x20, 0x00,
744 0x00, 0x00, 0x02, 0x00,
745 0x44, 0x33, 0x22, 0x11,
748static const BYTE shortSwitchValue[] = {
749 0x10, 0x00, 0x10, 0x00,
750 0x88, 0x77, 0x66, 0x55,
754static const BYTE shortSwitchDefault[] = { 0x99, 0x00, 0x99, 0x00 };
756static const BYTE shortSwitchMismatch[] = {
757 0x10, 0x00, 0x20, 0x00,
758 0x88, 0x77, 0x66, 0x55,
761static int TestNdrUnionWrite(
void)
764 UINT32 value = 0x11223344;
765 const SHORT_SWITCH msgs[] = { { 0x20, { .Pointer = &value } },
766 { 0x10, { .Value = 0x55667788 } },
767 { 0x99, { .Value = 0 } } };
768 const BYTE* expected[] = { shortSwitchPointer, shortSwitchValue, shortSwitchDefault };
769 const size_t expectedLen[] = {
sizeof(shortSwitchPointer),
sizeof(shortSwitchValue),
770 sizeof(shortSwitchDefault) };
772 wStream* s = Stream_New(
nullptr, 100);
776 for (
size_t i = 0; i < ARRAYSIZE(msgs); i++)
779 Stream_SetPosition(s, 0);
785 (Stream_GetPosition(s) == expectedLen[i]) &&
786 (memcmp(Stream_Buffer(s), expected[i], expectedLen[i]) == 0);
794 Stream_Free(s, TRUE);
798static int TestNdrUnionRead(
void)
800 SHORT_SWITCH msg = WINPR_C_ARRAY_INIT;
801 if (!decode_payload(&SHORT_SWITCH_struct, shortSwitchPointer,
sizeof(shortSwitchPointer),
803 (msg.CallId != 0x20) || !msg.u.Pointer || (*msg.u.Pointer != 0x11223344))
807 SHORT_SWITCH value = WINPR_C_ARRAY_INIT;
808 if (!decode_payload(&SHORT_SWITCH_struct, shortSwitchValue,
sizeof(shortSwitchValue), &value) ||
809 (value.CallId != 0x10) || (value.u.Value != 0x55667788))
812 SHORT_SWITCH def = WINPR_C_ARRAY_INIT;
813 if (!decode_payload(&SHORT_SWITCH_struct, shortSwitchDefault,
sizeof(shortSwitchDefault),
815 (def.CallId != 0x99))
818 SHORT_SWITCH mismatch = WINPR_C_ARRAY_INIT;
819 if (decode_payload(&SHORT_SWITCH_struct, shortSwitchMismatch,
sizeof(shortSwitchMismatch),
827int TestNdrBasic(
int argc,
char* argv[])
832 int (*
const tests[])(void) = { TestNdrBasic_1,
833 TestNdrStaticArrayRead,
834 TestNdrStaticArrayWrite,
835 TestNdrStaticArrayOverflow,
836 TestNdrDeferredOrderWrite,
837 TestNdrDeferredOrderRead,
841 TestNdrFullPointerAlias,
842 TestNdrFullPointerConfusion,
846 for (
size_t i = 0; i < ARRAYSIZE(tests); i++)
848 const int ret = tests[i]();
851 (void)fprintf(stderr,
"test %" PRIuz
" failed with %d\n", i, ret);
NDR encoder and decoder ([C706] chapter 14, [MS-RPCE] 2.2.5 and 2.2.6)
WINPR_ATTR_NODISCARD WINPR_API BOOL winpr_ndr_encoder_end_object(WinPrNdrEncoder *context, wStream *s)
ends the serialized object started with winpr_ndr_encoder_start_object()
UINT32 winpr_ndr_refid
a referent id, the wire value of a pointer (WINPR_NDR_PTR_NULL for a null pointer)
@ WINPR_NDR_POINTER_NON_NULL
WINPR_API void * winpr_ndr_pointer_ref(void *ptr)
takes a reference on a referent
WINPR_ATTR_NODISCARD WINPR_API BOOL winpr_ndr_encoder_write_header(WinPrNdrEncoder *context, wStream *s)
writes the common type header ([MS-RPCE] 2.2.6.1): version, endianness, header length and filler
WINPR_ATTR_NODISCARD WINPR_API BOOL winpr_ndr_decoder_read_uconformant_array(WinPrNdrDecoder *context, wStream *s, const WinPrNdrArrayHints *hints, WinPrNdrMessageType itemType, void *vtarget)
reads a conformant array: its count and the items
static INLINE void winpr_ndr_decoder_destroy(WinPrNdrDecoder **pcontext)
frees a decoder and resets the pointer
WINPR_ATTR_NODISCARD WINPR_API BOOL winpr_ndr_decoder_read_fromDescr(WinPrNdrDecoder *context, wStream *s, const WinPrNdrStructDescr *descr, void *target)
reads a structure from its descriptor
WINPR_ATTR_NODISCARD WINPR_API WinPrNdrMessageType winpr_ndr_wstring_varying_descr(void)
the message type of winpr_ndr_wstring_varying_descr_s
WINPR_ATTR_NODISCARD WINPR_API BOOL winpr_ndr_encoder_treat_deferreds(WinPrNdrEncoder *context, wStream *s)
writes the pending deferred referents
WINPR_API WinPrNdrDecoder * winpr_ndr_decoder_new(BOOL bigEndianDrep, BYTE version)
creates a decoder
WINPR_API WinPrNdrEncoder * winpr_ndr_encoder_new(BOOL bigEndianDrep, BYTE version)
creates an encoder
static INLINE void winpr_ndr_encoder_destroy(WinPrNdrEncoder **pcontext)
frees an encoder and resets the pointer
WINPR_ATTR_NODISCARD WINPR_API BOOL winpr_ndr_encoder_write_toplevel_refid(WinPrNdrEncoder *context, wStream *s)
writes a new referent id for a non-null top-level pointer
@ WINPR_NDR_ARITY_ARRAYOF
WINPR_ATTR_NODISCARD WINPR_API BOOL winpr_ndr_decoder_read_refpointer(WinPrNdrDecoder *context, wStream *s, UINT32 *refId)
reads a referent id
WINPR_API void winpr_ndr_pointer_release(void *ptr)
releases a referent
WINPR_ATTR_NODISCARD WINPR_API BOOL winpr_ndr_decoder_read_object(WinPrNdrDecoder *context, wStream *s, wStream *object)
reads the private header of a serialized object ([MS-RPCE] 2.2.6 type serialization version 1)
WINPR_API WinPrNdrDecoder * winpr_ndr_decoder_new_fromStream(wStream *s)
reads the common type header ([MS-RPCE] 2.2.6.1) and creates a decoder for its version and endianness
#define WINPR_NDR_UNION_MESSAGE_DEFINE(PREFIX, CTYPE)
defines a static message type for a non-encapsulated union
WINPR_API void winpr_ndr_struct_destroy(const WinPrNdrStructDescr *descr, void *pptr)
releases the content of a structure from its descriptor
WINPR_ATTR_NODISCARD WINPR_API BOOL winpr_ndr_encoder_write_fromDescr(WinPrNdrEncoder *context, wStream *s, const WinPrNdrStructDescr *descr, const void *src)
writes a structure from its descriptor
WINPR_ATTR_NODISCARD WINPR_API BOOL winpr_ndr_decoder_push_deferreds(WinPrNdrDecoder *context, WinPrNdrDeferredEntry *deferreds, size_t ndeferred)
adds deferred pointers, read by the next winpr_ndr_decoder_treat_deferreds()
WINPR_ATTR_NODISCARD WINPR_API BOOL winpr_ndr_encoder_write_uconformant_array(WinPrNdrEncoder *context, wStream *s, UINT32 len, WinPrNdrMessageType itemType, const BYTE *ptr)
writes a conformant array: its count and the items
WINPR_ATTR_NODISCARD WINPR_API BOOL winpr_ndr_encoder_start_object(WinPrNdrEncoder *context, wStream *s)
starts a serialized object ([MS-RPCE] 2.2.6 type serialization version 1)
WINPR_ATTR_NODISCARD WINPR_API BOOL winpr_ndr_decoder_treat_deferreds(WinPrNdrDecoder *context, wStream *s)
reads the pending deferred referents
hints for a conformant array
a deferred pointer, a referent to read after the current construct
descriptor of a field in a structure
an arm of a non-encapsulated union
a non-encapsulated union ([switch_type()])
hints for a conformant varying array