/* push a int16_t */ _PUBLIC_ enum ndr_err_code ndr_push_int16(struct ndr_push *ndr, int ndr_flags, int16_t v) { NDR_PUSH_ALIGN(ndr, 2); NDR_PUSH_NEED_BYTES(ndr, 2); NDR_SSVAL(ndr, ndr->offset, (uint16_t)v); ndr->offset += 2; return NDR_ERR_SUCCESS; }
/* push a uint32_t */ _PUBLIC_ enum ndr_err_code ndr_push_uint32(struct ndr_push *ndr, int ndr_flags, uint32_t 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 double */ _PUBLIC_ enum ndr_err_code ndr_push_double(struct ndr_push *ndr, int ndr_flags, double v) { NDR_PUSH_ALIGN(ndr, 8); NDR_PUSH_NEED_BYTES(ndr, 8); memcpy(ndr->data+ndr->offset, &v, 8); ndr->offset += 8; return NDR_ERR_SUCCESS; }
/* push a hyper */ _PUBLIC_ enum ndr_err_code ndr_push_hyper(struct ndr_push *ndr, int ndr_flags, uint64_t v) { NDR_PUSH_ALIGN(ndr, 8); if (NDR_BE(ndr)) { return ndr_push_udlongr(ndr, NDR_SCALARS, v); } return ndr_push_udlong(ndr, NDR_SCALARS, v); }
/* push a pointer */ _PUBLIC_ enum ndr_err_code ndr_push_pointer(struct ndr_push *ndr, int ndr_flags, void* v) { uintptr_t h = (intptr_t)v; NDR_PUSH_ALIGN(ndr, sizeof(h)); NDR_PUSH_NEED_BYTES(ndr, sizeof(h)); memcpy(ndr->data+ndr->offset, &h, sizeof(h)); ndr->offset += sizeof(h); return NDR_ERR_SUCCESS; }
/* push a udlongr */ _PUBLIC_ enum ndr_err_code ndr_push_udlongr(struct ndr_push *ndr, int ndr_flags, uint64_t v) { NDR_PUSH_ALIGN(ndr, 4); NDR_PUSH_NEED_BYTES(ndr, 8); NDR_SIVAL(ndr, ndr->offset, (v>>32)); NDR_SIVAL(ndr, ndr->offset+4, (v & 0xFFFFFFFF)); ndr->offset += 8; return NDR_ERR_SUCCESS; }
enum ndr_err_code ndr_push_DNS_RPC_RECORDS_ARRAY(struct ndr_push *ndr, int ndr_flags, const struct DNS_RPC_RECORDS_ARRAY *rec) { int i; for (i=0; i<rec->count; i++) { NDR_CHECK(ndr_push_DNS_RPC_RECORDS(ndr, ndr_flags, &rec->rec[i])); NDR_PUSH_ALIGN(ndr, 4); } return NDR_ERR_SUCCESS; }
_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; } } else if (size == 3) { if (ndr->flags & LIBNDR_FLAG_NDR64) { size = 4; } else { size = 2; } } NDR_PUSH_ALIGN(ndr, size); return NDR_ERR_SUCCESS; }
_PUBLIC_ enum ndr_err_code ndr_push_align(struct ndr_push *ndr, size_t size) { NDR_PUSH_ALIGN(ndr, size); return NDR_ERR_SUCCESS; }
/* push a relative object - stage2 end this is called during buffers processing */ _PUBLIC_ enum ndr_err_code ndr_push_relative_ptr2_end(struct ndr_push *ndr, const void *p) { uint32_t begin_offset = 0xFFFFFFFF; ssize_t len; uint32_t correct_offset = 0; uint32_t align = 1; uint32_t pad = 0; if (p == NULL) { return NDR_ERR_SUCCESS; } if (!(ndr->flags & LIBNDR_FLAG_RELATIVE_REVERSE)) { return NDR_ERR_SUCCESS; } if (ndr->flags & LIBNDR_FLAG_NO_NDR_SIZE) { /* better say more than calculation a too small buffer */ NDR_PUSH_ALIGN(ndr, 8); return NDR_ERR_SUCCESS; } if (ndr->relative_end_offset < ndr->offset) { return ndr_push_error(ndr, NDR_ERR_RELATIVE, "ndr_push_relative_ptr2_end:" "relative_end_offset %u < offset %u", ndr->relative_end_offset, ndr->offset); } NDR_CHECK(ndr_token_retrieve(&ndr->relative_begin_list, p, &begin_offset)); /* we have marshalled a buffer, see how long it was */ len = ndr->offset - begin_offset; if (len < 0) { return ndr_push_error(ndr, NDR_ERR_RELATIVE, "ndr_push_relative_ptr2_end:" "offset %u - begin_offset %u < 0", ndr->offset, begin_offset); } if (ndr->relative_end_offset < len) { return ndr_push_error(ndr, NDR_ERR_RELATIVE, "ndr_push_relative_ptr2_end:" "relative_end_offset %u < len %lld", ndr->offset, (long long)len); } /* the reversed offset is at the end of the main buffer */ correct_offset = ndr->relative_end_offset - len; /* TODO: remove this hack and let the idl use FLAG_ALIGN2 explicit */ align = 2; if (ndr->flags & LIBNDR_FLAG_ALIGN2) { align = 2; } else if (ndr->flags & LIBNDR_FLAG_ALIGN4) { align = 4; } else if (ndr->flags & LIBNDR_FLAG_ALIGN8) { align = 8; } pad = ndr_align_size(correct_offset, align); if (pad) { correct_offset += pad; correct_offset -= align; } if (correct_offset < begin_offset) { return ndr_push_error(ndr, NDR_ERR_RELATIVE, "ndr_push_relative_ptr2_end: " "correct_offset %u < begin_offset %u", correct_offset, begin_offset); } if (len > 0) { uint32_t clear_size = correct_offset - begin_offset; clear_size = MIN(clear_size, len); /* now move the marshalled buffer to the end of the main buffer */ memmove(ndr->data + correct_offset, ndr->data + begin_offset, len); if (clear_size) { /* and wipe out old buffer within the main buffer */ memset(ndr->data + begin_offset, '\0', clear_size); } } /* and set the end offset for the next buffer */ ndr->relative_end_offset = correct_offset; /* finally write the offset to the main buffer */ ndr->offset = correct_offset; NDR_CHECK(ndr_push_relative_ptr2(ndr, p)); /* restore to where we were in the main buffer */ ndr->offset = begin_offset; return NDR_ERR_SUCCESS; }