예제 #1
0
파일: ndr_basic.c 프로젝트: gojdic/samba
/*
  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;
}
예제 #2
0
파일: ndr_basic.c 프로젝트: gojdic/samba
/*
  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;
}
예제 #3
0
/*
  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;
}
예제 #4
0
/*
  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);
}
예제 #5
0
파일: ndr_basic.c 프로젝트: gojdic/samba
/*
  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;
}
예제 #6
0
파일: ndr_basic.c 프로젝트: gojdic/samba
/*
  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;
}
예제 #7
0
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;
}
예제 #8
0
_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;
}
예제 #9
0
파일: ndr_basic.c 프로젝트: gojdic/samba
_PUBLIC_ enum ndr_err_code ndr_push_align(struct ndr_push *ndr, size_t size)
{
	NDR_PUSH_ALIGN(ndr, size);
	return NDR_ERR_SUCCESS;
}
예제 #10
0
/*
  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;
}