summaryrefslogtreecommitdiff
path: root/librpc/ndr/ndr_basic.c
diff options
context:
space:
mode:
Diffstat (limited to 'librpc/ndr/ndr_basic.c')
-rw-r--r--librpc/ndr/ndr_basic.c128
1 files changed, 123 insertions, 5 deletions
diff --git a/librpc/ndr/ndr_basic.c b/librpc/ndr/ndr_basic.c
index d46590f0cb..00e33ad9d0 100644
--- a/librpc/ndr/ndr_basic.c
+++ b/librpc/ndr/ndr_basic.c
@@ -126,6 +126,26 @@ _PUBLIC_ enum ndr_err_code ndr_pull_uint32(struct ndr_pull *ndr, int ndr_flags,
}
/*
+ parse a arch dependent uint32/uint64
+*/
+_PUBLIC_ enum ndr_err_code ndr_pull_uint3264(struct ndr_pull *ndr, int ndr_flags, uint32_t *v)
+{
+ uint64_t v64;
+ enum ndr_err_code err;
+ if (likely(!(ndr->flags & LIBNDR_FLAG_NDR64))) {
+ return ndr_pull_uint32(ndr, ndr_flags, v);
+ }
+ err = ndr_pull_hyper(ndr, ndr_flags, &v64);
+ *v = (uint32_t)v64;
+ if (unlikely(v64 != *v)) {
+ DEBUG(0,(__location__ ": non-zero upper 32 bits 0x%016llx\n",
+ (unsigned long long)v64));
+ return NDR_ERR_NDR64;
+ }
+ return err;
+}
+
+/*
parse a double
*/
_PUBLIC_ enum ndr_err_code ndr_pull_double(struct ndr_pull *ndr, int ndr_flags, double *v)
@@ -142,7 +162,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_double(struct ndr_pull *ndr, int ndr_flags,
*/
_PUBLIC_ enum ndr_err_code ndr_pull_generic_ptr(struct ndr_pull *ndr, uint32_t *v)
{
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, v));
+ NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, v));
if (*v != 0) {
ndr->ptr_count++;
}
@@ -154,7 +174,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_generic_ptr(struct ndr_pull *ndr, uint32_t *
*/
_PUBLIC_ enum ndr_err_code ndr_pull_ref_ptr(struct ndr_pull *ndr, uint32_t *v)
{
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, v));
+ NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, v));
/* ref pointers always point to data */
*v = 1;
return NDR_ERR_SUCCESS;
@@ -252,6 +272,73 @@ _PUBLIC_ enum ndr_err_code ndr_pull_WERROR(struct ndr_pull *ndr, int ndr_flags,
return NDR_ERR_SUCCESS;
}
+
+/*
+ parse a uint8_t enum
+*/
+_PUBLIC_ enum ndr_err_code ndr_pull_enum_uint8(struct ndr_pull *ndr, int ndr_flags, uint8_t *v)
+{
+ return ndr_pull_uint8(ndr, ndr_flags, v);
+}
+
+/*
+ parse a uint16_t enum (uint32_t on NDR64)
+*/
+_PUBLIC_ enum ndr_err_code ndr_pull_enum_uint16(struct ndr_pull *ndr, int ndr_flags, uint16_t *v)
+{
+ if (unlikely(ndr->flags & LIBNDR_FLAG_NDR64)) {
+ uint32_t v32;
+ NDR_CHECK(ndr_pull_uint32(ndr, ndr_flags, &v32));
+ *v = v32;
+ if (v32 != *v) {
+ DEBUG(0,(__location__ ": non-zero upper 16 bits 0x%08x\n", (unsigned)v32));
+ return NDR_ERR_NDR64;
+ }
+ return NDR_ERR_SUCCESS;
+ }
+ NDR_PULL_ALIGN(ndr, 2);
+ NDR_PULL_NEED_BYTES(ndr, 2);
+ *v = NDR_SVAL(ndr, ndr->offset);
+ ndr->offset += 2;
+ return NDR_ERR_SUCCESS;
+}
+
+/*
+ parse a uint32_t enum
+*/
+_PUBLIC_ enum ndr_err_code ndr_pull_enum_uint32(struct ndr_pull *ndr, int ndr_flags, uint32_t *v)
+{
+ return ndr_pull_uint32(ndr, ndr_flags, v);
+}
+
+/*
+ push a uint8_t enum
+*/
+_PUBLIC_ enum ndr_err_code ndr_push_enum_uint8(struct ndr_push *ndr, int ndr_flags, uint8_t v)
+{
+ return ndr_push_uint8(ndr, ndr_flags, v);
+}
+
+/*
+ push a uint16_t enum (uint32_t on NDR64)
+*/
+_PUBLIC_ enum ndr_err_code ndr_push_enum_uint16(struct ndr_push *ndr, int ndr_flags, uint16_t v)
+{
+ if (unlikely(ndr->flags & LIBNDR_FLAG_NDR64)) {
+ return ndr_push_uint32(ndr, ndr_flags, v);
+ }
+ return ndr_push_uint16(ndr, ndr_flags, v);
+}
+
+/*
+ push a uint32_t enum
+*/
+_PUBLIC_ enum ndr_err_code ndr_push_enum_uint32(struct ndr_push *ndr, int ndr_flags, uint32_t v)
+{
+ return ndr_push_uint32(ndr, ndr_flags, v);
+}
+
+
/*
push a WERROR
*/
@@ -358,6 +445,21 @@ _PUBLIC_ enum ndr_err_code ndr_push_uint32(struct ndr_push *ndr, int ndr_flags,
}
/*
+ push a uint3264
+*/
+_PUBLIC_ enum ndr_err_code ndr_push_uint3264(struct ndr_push *ndr, int ndr_flags, uint32_t v)
+{
+ if (unlikely(ndr->flags & LIBNDR_FLAG_NDR64)) {
+ return ndr_push_hyper(ndr, ndr_flags, v);
+ }
+ NDR_PUSH_ALIGN(ndr, 4);
+ NDR_PUSH_NEED_BYTES(ndr, 4);
+ NDR_SIVAL(ndr, ndr->offset, v);
+ ndr->offset += 4;
+ return NDR_ERR_SUCCESS;
+}
+
+/*
push a udlong
*/
_PUBLIC_ enum ndr_err_code ndr_push_udlong(struct ndr_push *ndr, int ndr_flags, uint64_t v)
@@ -427,12 +529,28 @@ _PUBLIC_ enum ndr_err_code ndr_push_pointer(struct ndr_push *ndr, int ndr_flags,
_PUBLIC_ enum ndr_err_code ndr_push_align(struct ndr_push *ndr, size_t size)
{
+ /* this is a nasty hack to make pidl work with NDR64 */
+ if (size == 5) {
+ if (ndr->flags & LIBNDR_FLAG_NDR64) {
+ size = 8;
+ } else {
+ size = 4;
+ }
+ }
NDR_PUSH_ALIGN(ndr, size);
return NDR_ERR_SUCCESS;
}
_PUBLIC_ enum ndr_err_code ndr_pull_align(struct ndr_pull *ndr, size_t size)
{
+ /* this is a nasty hack to make pidl work with NDR64 */
+ if (size == 5) {
+ if (ndr->flags & LIBNDR_FLAG_NDR64) {
+ size = 8;
+ } else {
+ size = 4;
+ }
+ }
NDR_PULL_ALIGN(ndr, size);
return NDR_ERR_SUCCESS;
}
@@ -481,7 +599,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_unique_ptr(struct ndr_push *ndr, const void
ptr |= 0x00020000;
ndr->ptr_count++;
}
- return ndr_push_uint32(ndr, NDR_SCALARS, ptr);
+ return ndr_push_uint3264(ndr, NDR_SCALARS, ptr);
}
/*
@@ -499,7 +617,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_full_ptr(struct ndr_push *ndr, const void *p
ndr_token_store(ndr, &ndr->full_ptr_list, p, ptr);
}
}
- return ndr_push_uint32(ndr, NDR_SCALARS, ptr);
+ return ndr_push_uint3264(ndr, NDR_SCALARS, ptr);
}
/*
@@ -507,7 +625,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_full_ptr(struct ndr_push *ndr, const void *p
*/
_PUBLIC_ enum ndr_err_code ndr_push_ref_ptr(struct ndr_push *ndr)
{
- return ndr_push_uint32(ndr, NDR_SCALARS, 0xAEF1AEF1);
+ return ndr_push_uint3264(ndr, NDR_SCALARS, 0xAEF1AEF1);
}