📄 ndr_basic.c
字号:
/* Unix SMB/CIFS implementation. routines for marshalling/unmarshalling basic types Copyright (C) Andrew Tridgell 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include "includes.h"#define NDR_SVAL(ndr, ofs) (NDR_BE(ndr)?RSVAL(ndr->data,ofs):SVAL(ndr->data,ofs))#define NDR_IVAL(ndr, ofs) (NDR_BE(ndr)?RIVAL(ndr->data,ofs):IVAL(ndr->data,ofs))#define NDR_IVALS(ndr, ofs) (NDR_BE(ndr)?RIVALS(ndr->data,ofs):IVALS(ndr->data,ofs))#define NDR_SSVAL(ndr, ofs, v) do { if (NDR_BE(ndr)) { RSSVAL(ndr->data,ofs,v); } else SSVAL(ndr->data,ofs,v); } while (0)#define NDR_SIVAL(ndr, ofs, v) do { if (NDR_BE(ndr)) { RSIVAL(ndr->data,ofs,v); } else SIVAL(ndr->data,ofs,v); } while (0)#define NDR_SIVALS(ndr, ofs, v) do { if (NDR_BE(ndr)) { RSIVALS(ndr->data,ofs,v); } else SIVALS(ndr->data,ofs,v); } while (0)/* check for data leaks from the server by looking for non-zero pad bytes these could also indicate that real structure elements have been mistaken for padding in the IDL*/void ndr_check_padding(struct ndr_pull *ndr, size_t n){ size_t ofs2 = (ndr->offset + (n-1)) & ~(n-1); int i; for (i=ndr->offset;i<ofs2;i++) { if (ndr->data[i] != 0) { break; } } if (i<ofs2) { DEBUG(0,("WARNING: Non-zero padding to %d: ", (int)n)); for (i=ndr->offset;i<ofs2;i++) { DEBUG(0,("%02x ", ndr->data[i])); } DEBUG(0,("\n")); }}/* parse a int8_t*/NTSTATUS ndr_pull_int8(struct ndr_pull *ndr, int ndr_flags, int8_t *v){ NDR_PULL_NEED_BYTES(ndr, 1); *v = (int8_t)CVAL(ndr->data, ndr->offset); ndr->offset += 1; return NT_STATUS_OK;}/* parse a uint8_t*/NTSTATUS ndr_pull_uint8(struct ndr_pull *ndr, int ndr_flags, uint8_t *v){ NDR_PULL_NEED_BYTES(ndr, 1); *v = CVAL(ndr->data, ndr->offset); ndr->offset += 1; return NT_STATUS_OK;}/* parse a int16_t*/NTSTATUS ndr_pull_int16(struct ndr_pull *ndr, int ndr_flags, int16_t *v){ NDR_PULL_ALIGN(ndr, 2); NDR_PULL_NEED_BYTES(ndr, 2); *v = (uint16_t)NDR_SVAL(ndr, ndr->offset); ndr->offset += 2; return NT_STATUS_OK;}/* parse a uint16_t*/NTSTATUS ndr_pull_uint16(struct ndr_pull *ndr, int ndr_flags, uint16_t *v){ NDR_PULL_ALIGN(ndr, 2); NDR_PULL_NEED_BYTES(ndr, 2); *v = NDR_SVAL(ndr, ndr->offset); ndr->offset += 2; return NT_STATUS_OK;}/* parse a int32_t*/NTSTATUS ndr_pull_int32(struct ndr_pull *ndr, int ndr_flags, int32_t *v){ NDR_PULL_ALIGN(ndr, 4); NDR_PULL_NEED_BYTES(ndr, 4); *v = NDR_IVALS(ndr, ndr->offset); ndr->offset += 4; return NT_STATUS_OK;}/* parse a uint32_t*/NTSTATUS ndr_pull_uint32(struct ndr_pull *ndr, int ndr_flags, uint32_t *v){ NDR_PULL_ALIGN(ndr, 4); NDR_PULL_NEED_BYTES(ndr, 4); *v = NDR_IVAL(ndr, ndr->offset); ndr->offset += 4; return NT_STATUS_OK;}/* parse a pointer referent identifier*/NTSTATUS ndr_pull_generic_ptr(struct ndr_pull *ndr, uint32_t *v){ NTSTATUS status; status = ndr_pull_uint32(ndr, NDR_SCALARS, v); if (NT_STATUS_IS_OK(status) && *v != 0) { ndr->ptr_count++; } return status;}/* parse a ref pointer referent identifier*/NTSTATUS ndr_pull_ref_ptr(struct ndr_pull *ndr, uint32_t *v){ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, v)); /* ref pointers always point to data */ *v = 1; return NT_STATUS_OK;}/* parse a udlong*/NTSTATUS ndr_pull_udlong(struct ndr_pull *ndr, int ndr_flags, uint64_t *v){ NDR_PULL_ALIGN(ndr, 4); NDR_PULL_NEED_BYTES(ndr, 8); *v = NDR_IVAL(ndr, ndr->offset); *v |= (uint64_t)(NDR_IVAL(ndr, ndr->offset+4)) << 32; ndr->offset += 8; return NT_STATUS_OK;}/* parse a udlongr*/NTSTATUS ndr_pull_udlongr(struct ndr_pull *ndr, int ndr_flags, uint64_t *v){ NDR_PULL_ALIGN(ndr, 4); NDR_PULL_NEED_BYTES(ndr, 8); *v = ((uint64_t)NDR_IVAL(ndr, ndr->offset)) << 32; *v |= NDR_IVAL(ndr, ndr->offset+4); ndr->offset += 8; return NT_STATUS_OK;}/* parse a dlong*/NTSTATUS ndr_pull_dlong(struct ndr_pull *ndr, int ndr_flags, int64_t *v){ return ndr_pull_udlong(ndr, ndr_flags, (uint64_t *)v);}/* parse a hyper*/NTSTATUS ndr_pull_hyper(struct ndr_pull *ndr, int ndr_flags, uint64_t *v){ NDR_PULL_ALIGN(ndr, 8); return ndr_pull_udlong(ndr, ndr_flags, v);}/* parse a pointer*/NTSTATUS ndr_pull_pointer(struct ndr_pull *ndr, int ndr_flags, void* *v){ intptr_t h; NDR_PULL_ALIGN(ndr, sizeof(h)); NDR_PULL_NEED_BYTES(ndr, sizeof(h)); memcpy(&h, ndr->data+ndr->offset, sizeof(h)); ndr->offset += sizeof(h); *v = (void *)h; return NT_STATUS_OK; }/* pull a NTSTATUS*/NTSTATUS ndr_pull_NTSTATUS(struct ndr_pull *ndr, int ndr_flags, NTSTATUS *status){ uint32_t v; NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v)); *status = NT_STATUS(v); return NT_STATUS_OK;}/* push a NTSTATUS*/NTSTATUS ndr_push_NTSTATUS(struct ndr_push *ndr, int ndr_flags, NTSTATUS status){ return ndr_push_uint32(ndr, ndr_flags, NT_STATUS_V(status));}void ndr_print_NTSTATUS(struct ndr_print *ndr, const char *name, NTSTATUS r){ ndr->print(ndr, "%-25s: %s", name, nt_errstr(r));}/* pull a WERROR*/NTSTATUS ndr_pull_WERROR(struct ndr_pull *ndr, int ndr_flags, WERROR *status){ uint32_t v; NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v)); *status = W_ERROR(v); return NT_STATUS_OK;}/* push a WERROR*/NTSTATUS ndr_push_WERROR(struct ndr_push *ndr, int ndr_flags, WERROR status){ return ndr_push_uint32(ndr, NDR_SCALARS, W_ERROR_V(status));}void ndr_print_WERROR(struct ndr_print *ndr, const char *name, WERROR r){ ndr->print(ndr, "%-25s: %s", name, dos_errstr(r));}/* parse a set of bytes*/NTSTATUS ndr_pull_bytes(struct ndr_pull *ndr, uint8_t *data, uint32_t n){ NDR_PULL_NEED_BYTES(ndr, n); memcpy(data, ndr->data + ndr->offset, n); ndr->offset += n; return NT_STATUS_OK;}/* pull an array of uint8*/NTSTATUS ndr_pull_array_uint8(struct ndr_pull *ndr, int ndr_flags, uint8_t *data, uint32_t n){ if (!(ndr_flags & NDR_SCALARS)) { return NT_STATUS_OK; } return ndr_pull_bytes(ndr, data, n);}/* push a int8_t*/NTSTATUS ndr_push_int8(struct ndr_push *ndr, int ndr_flags, int8_t v){ NDR_PUSH_NEED_BYTES(ndr, 1); SCVAL(ndr->data, ndr->offset, (uint8_t)v); ndr->offset += 1; return NT_STATUS_OK;}/* push a uint8_t*/NTSTATUS ndr_push_uint8(struct ndr_push *ndr, int ndr_flags, uint8_t v){ NDR_PUSH_NEED_BYTES(ndr, 1); SCVAL(ndr->data, ndr->offset, v); ndr->offset += 1; return NT_STATUS_OK;}/* push a int16_t*/NTSTATUS 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 NT_STATUS_OK;}/* push a uint16_t*/NTSTATUS ndr_push_uint16(struct ndr_push *ndr, int ndr_flags, uint16_t v){ NDR_PUSH_ALIGN(ndr, 2); NDR_PUSH_NEED_BYTES(ndr, 2); NDR_SSVAL(ndr, ndr->offset, v); ndr->offset += 2; return NT_STATUS_OK;}/* push a int32_t*/NTSTATUS ndr_push_int32(struct ndr_push *ndr, int ndr_flags, int32_t v){ NDR_PUSH_ALIGN(ndr, 4); NDR_PUSH_NEED_BYTES(ndr, 4); NDR_SIVALS(ndr, ndr->offset, v); ndr->offset += 4; return NT_STATUS_OK;}/* push a uint32_t*/NTSTATUS 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 NT_STATUS_OK;}/* push a udlong*/NTSTATUS ndr_push_udlong(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 & 0xFFFFFFFF)); NDR_SIVAL(ndr, ndr->offset+4, (v>>32)); ndr->offset += 8; return NT_STATUS_OK;}/* push a udlongr*/NTSTATUS 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 NT_STATUS_OK;}/* push a dlong*/NTSTATUS ndr_push_dlong(struct ndr_push *ndr, int ndr_flags, int64_t v){ return ndr_push_udlong(ndr, NDR_SCALARS, (uint64_t)v);}/* push a hyper*/NTSTATUS ndr_push_hyper(struct ndr_push *ndr, int ndr_flags, uint64_t v){ NDR_PUSH_ALIGN(ndr, 8); return ndr_push_udlong(ndr, NDR_SCALARS, v);}/* push a pointer*/NTSTATUS ndr_push_pointer(struct ndr_push *ndr, int ndr_flags, void* v){ intptr_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 NT_STATUS_OK; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -