From c212a65b65ba0100ceb9c4fa48c1f44dc0c804f5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 16 Sep 2008 02:27:33 +0200 Subject: More changes getting WMI code to compile, import manual marshalling. --- source4/lib/com/com.h | 12 + source4/lib/com/dcom/dcom.h | 2 + source4/lib/com/dcom/main.c | 29 +- source4/lib/wmi/tools/wmic.c | 4 +- source4/lib/wmi/wbemdata.c | 1 + source4/lib/wmi/wmicore.c | 2 +- source4/librpc/config.mk | 13 +- source4/librpc/idl/dcom.idl | 2 + source4/librpc/idl/wmi.idl | 4 +- source4/librpc/ndr/ndr_wmi.c | 849 +++++++++++++++++++++++++++++++++++++++++++ source4/librpc/ndr/ndr_wmi.h | 6 + 11 files changed, 906 insertions(+), 18 deletions(-) create mode 100644 source4/librpc/ndr/ndr_wmi.c create mode 100644 source4/librpc/ndr/ndr_wmi.h diff --git a/source4/lib/com/com.h b/source4/lib/com/com.h index f88c914a04..2074bd11ca 100644 --- a/source4/lib/com/com.h +++ b/source4/lib/com/com.h @@ -25,6 +25,18 @@ struct com_context; struct event_context; +struct com_context +{ + struct dcom_client_context *dcom; + struct event_context *event_ctx; + struct com_extension { + uint32_t id; + void *data; + struct com_extension *prev, *next; + } *extensions; + struct loadparm_context *lp_ctx; +}; + struct IUnknown *com_class_by_clsid(struct com_context *ctx, const struct GUID *clsid); NTSTATUS com_register_running_class(struct GUID *clsid, const char *progid, struct IUnknown *p); diff --git a/source4/lib/com/dcom/dcom.h b/source4/lib/com/dcom/dcom.h index 69bb7183b2..3ce0478172 100644 --- a/source4/lib/com/dcom/dcom.h +++ b/source4/lib/com/dcom/dcom.h @@ -68,5 +68,7 @@ NTSTATUS dcom_register_marshal(struct GUID *clsid, marshal_fn marshal, unmarshal #include "libcli/composite/composite.h" void dcom_release_continue(struct composite_context *cr); #define IUnknown_ipid(d) ((d)->obj.u_objref.u_standard.std.ipid) +struct composite_context *dcom_release_send(struct IUnknown *d, TALLOC_CTX *mem_ctx); +marshal_fn dcom_marshal_by_clsid(struct GUID *clsid); #endif /* _DCOM_H */ diff --git a/source4/lib/com/dcom/main.c b/source4/lib/com/dcom/main.c index a4b37f1927..2770897ca3 100644 --- a/source4/lib/com/dcom/main.c +++ b/source4/lib/com/dcom/main.c @@ -25,6 +25,7 @@ #include "librpc/gen_ndr/ndr_remact_c.h" #include "librpc/gen_ndr/com_dcom.h" #include "librpc/gen_ndr/dcom.h" +#include "librpc/rpc/dcerpc.h" #include "lib/com/dcom/dcom.h" #include "librpc/ndr/ndr_table.h" #include "lib/util/dlinklist.h" @@ -154,7 +155,7 @@ struct dcom_client_context *dcom_client_init(struct com_context *ctx, struct cli cli_credentials_set_conf(credentials, ctx->lp_ctx); cli_credentials_parse_string(credentials, "%", CRED_SPECIFIED); } - dcom_set_server_credentials(ctx, NULL, credentials); + dcom_add_server_credentials(ctx, NULL, credentials); return ctx->dcom; } @@ -191,9 +192,11 @@ static NTSTATUS dcom_connect_host(struct com_context *ctx, if (!binding) { status = NT_STATUS_NO_MEMORY; goto end; - }; - status = dcerpc_pipe_connect(ctx->event_ctx, p, binding, &ndr_table_IRemoteActivation, - dcom_get_server_credentials(ctx, server), ctx->event_ctx, ctx->lp_ctx); + } + status = dcerpc_pipe_connect(ctx->event_ctx, p, binding, + &ndr_table_IRemoteActivation, + dcom_get_server_credentials(ctx, server), + ctx->event_ctx, ctx->lp_ctx); if (NT_STATUS_IS_OK(status)) { if (DEBUGLVL(11)) @@ -507,7 +510,7 @@ NTSTATUS dcom_get_pipe(struct IUnknown *iface, struct dcerpc_pipe **pp) return NT_STATUS_OK; } -NTSTATUS dcom_OBJREF_from_IUnknown(struct OBJREF *o, struct IUnknown *p) +NTSTATUS dcom_OBJREF_from_IUnknown(TALLLOC_CTX *mem_ctx, struct OBJREF *o, struct IUnknown *p) { /* FIXME: Cache generated objref objects? */ ZERO_STRUCTP(o); @@ -523,7 +526,7 @@ NTSTATUS dcom_OBJREF_from_IUnknown(struct OBJREF *o, struct IUnknown *p) marshal = dcom_marshal_by_clsid(&o->u_objref.u_custom.clsid); if (marshal) { - return marshal(p, o); + return marshal(mem_ctx, p, o); } else { return NT_STATUS_NOT_SUPPORTED; } @@ -534,15 +537,16 @@ NTSTATUS dcom_OBJREF_from_IUnknown(struct OBJREF *o, struct IUnknown *p) return NT_STATUS_OK; } -NTSTATUS dcom_IUnknown_from_OBJREF(struct com_context *ctx, struct IUnknown **_p, struct OBJREF *o) +enum ndr_err_code dcom_IUnknown_from_OBJREF(struct com_context *ctx, struct IUnknown **_p, struct OBJREF *o) { struct IUnknown *p; struct dcom_object_exporter *ox; + unmarshal_fn unmarshal; switch(o->flags) { case OBJREF_NULL: *_p = NULL; - return NT_STATUS_OK; + return NDR_ERR_SUCCESS; case OBJREF_STANDARD: p = talloc_zero(ctx, struct IUnknown); @@ -552,7 +556,7 @@ NTSTATUS dcom_IUnknown_from_OBJREF(struct com_context *ctx, struct IUnknown **_p if (!p->vtable) { DEBUG(0, ("Unable to find proxy class for interface with IID %s\n", GUID_string(ctx, &o->iid))); - return NT_STATUS_NOT_SUPPORTED; + return NDR_ERR_INVALID_POINTER; } p->vtable->Release_send = dcom_release_send; @@ -560,7 +564,7 @@ NTSTATUS dcom_IUnknown_from_OBJREF(struct com_context *ctx, struct IUnknown **_p ox = object_exporter_by_oxid(ctx, o->u_objref.u_standard.std.oxid); /* FIXME: Add object to list of objects to ping */ *_p = p; - return NT_STATUS_OK; + return NDR_ERR_SUCCESS; case OBJREF_HANDLER: p = talloc_zero(ctx, struct IUnknown); @@ -579,17 +583,16 @@ NTSTATUS dcom_IUnknown_from_OBJREF(struct com_context *ctx, struct IUnknown **_p p->ctx = ctx; p->vtable = NULL; p->obj = *o; - unmarshal_fn unmarshal; unmarshal = dcom_unmarshal_by_clsid(&o->u_objref.u_custom.clsid); *_p = p; if (unmarshal) { return unmarshal(ctx, o, _p); } else { - return NT_STATUS_NOT_SUPPORTED; + return NDR_ERR_BAD_SWITCH; } } - return NT_STATUS_NOT_SUPPORTED; + return NDR_ERR_BAD_SWITCH; } uint64_t dcom_get_current_oxid(void) diff --git a/source4/lib/wmi/tools/wmic.c b/source4/lib/wmi/tools/wmic.c index 4b84c27c8d..bbfe5ed334 100644 --- a/source4/lib/wmi/tools/wmic.c +++ b/source4/lib/wmi/tools/wmic.c @@ -200,12 +200,12 @@ int main(int argc, char **argv) class_name = talloc_strdup(ctx, co[i]->obj_class->__CLASS); printf("CLASS: %s\n", class_name); for (j = 0; j < co[i]->obj_class->__PROPERTY_COUNT; ++j) - printf("%s%s", j?"|":"", co[i]->obj_class->properties[j].name); + printf("%s%s", j?"|":"", co[i]->obj_class->properties[j].property.name); printf("\n"); } for (j = 0; j < co[i]->obj_class->__PROPERTY_COUNT; ++j) { char *s; - s = string_CIMVAR(ctx, &co[i]->instance->data[j], co[i]->obj_class->properties[j].desc->cimtype & CIM_TYPEMASK); + s = string_CIMVAR(ctx, &co[i]->instance->data[j], co[i]->obj_class->properties[j].property.desc->cimtype & CIM_TYPEMASK); printf("%s%s", j?"|":"", s); } printf("\n"); diff --git a/source4/lib/wmi/wbemdata.c b/source4/lib/wmi/wbemdata.c index b24499ab5c..58bf177c0c 100644 --- a/source4/lib/wmi/wbemdata.c +++ b/source4/lib/wmi/wbemdata.c @@ -33,6 +33,7 @@ #include "lib/talloc/talloc.h" #include "libcli/composite/composite.h" #include "lib/wmi/wmi.h" +#include "librpc/ndr/ndr_wmi.h" enum { DATATYPE_CLASSOBJECT = 2, diff --git a/source4/lib/wmi/wmicore.c b/source4/lib/wmi/wmicore.c index fbd6b339bf..49c1e03312 100644 --- a/source4/lib/wmi/wmicore.c +++ b/source4/lib/wmi/wmicore.c @@ -69,7 +69,7 @@ WERROR WBEM_ConnectServer(struct com_context *ctx, const char *server, const uin cc = cli_credentials_init(cred); cli_credentials_set_conf(cc, global_loadparm); cli_credentials_parse_string(cc, cred, CRED_SPECIFIED); - dcom_set_server_credentials(ctx, server, cc); + dcom_add_server_credentials(ctx, server, cc); talloc_free(cred); } diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index b68d5e6a69..8b1cec46b3 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -84,6 +84,16 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY NDR_NBT NDR_IRPC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_irpc.o +[SUBSYSTEM::NDR_DCOM] +PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY NDR_ORPC + +NDR_DCOM_OBJ_FILES = $(gen_ndrsrcdir)/ndr_dcom.o + +[SUBSYSTEM::NDR_WMI] +PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY NDR_DCOM + +NDR_WMI_OBJ_FILES = $(gen_ndrsrcdir)/ndr_wmi.o $(ndrsrcdir)/ndr_wmi.o + [SUBSYSTEM::NDR_DSBACKUP] PUBLIC_DEPENDENCIES = LIBNDR @@ -379,7 +389,8 @@ PUBLIC_DEPENDENCIES = \ NDR_NETLOGON NDR_TRKWKS NDR_KEYSVC NDR_KRB5PAC NDR_XATTR NDR_SCHANNEL \ NDR_ROT NDR_DRSBLOBS NDR_SVCCTL NDR_NBT NDR_WINSREPL NDR_SECURITY \ NDR_INITSHUTDOWN NDR_DNSSERVER NDR_WINSTATION NDR_IRPC NDR_OPENDB \ - NDR_SASL_HELPERS NDR_NOTIFY NDR_WINBIND NDR_FRSRPC NDR_FRSAPI NDR_NFS4ACL NDR_NTP_SIGND + NDR_SASL_HELPERS NDR_NOTIFY NDR_WINBIND NDR_FRSRPC NDR_FRSAPI NDR_NFS4ACL NDR_NTP_SIGND \ + NDR_DCOM NDR_WMI NDR_TABLE_OBJ_FILES = $(ndrsrcdir)/ndr_table.o $(gen_ndrsrcdir)/tables.o diff --git a/source4/librpc/idl/dcom.idl b/source4/librpc/idl/dcom.idl index 64e1c1850b..977c7ed86a 100644 --- a/source4/librpc/idl/dcom.idl +++ b/source4/librpc/idl/dcom.idl @@ -3,6 +3,8 @@ http://www.ietf.org/internet-drafts/draft-brown-dcom-v1-spec-04.txt */ +import "misc.idl"; + [ uuid("18f70770-8e64-11cf-9af1-0020af6e72f4"), pointer_default(unique), diff --git a/source4/librpc/idl/wmi.idl b/source4/librpc/idl/wmi.idl index fe16e5e8ef..e3e98ba83d 100644 --- a/source4/librpc/idl/wmi.idl +++ b/source4/librpc/idl/wmi.idl @@ -5,8 +5,10 @@ #include "idl_types.h" import "dcom.idl"; +import "misc.idl"; [ + helper("librpc/ndr/ndr_wmi.h"), uuid("8BC3F05E-D86B-11d0-A075-00C04FB68820") ] coclass WbemLevel1Login { @@ -424,7 +426,7 @@ interface IWbemClassObject : IUnknown } WbemClassProperty; - typedef [public,nopush,nopull,noprint,flag(NDR_NOALIGN)] struct + typedef [public,nopush,nopull,flag(NDR_NOALIGN)] struct { uint8 u_0; [relative, null_is_ffffffff,charset(UTF16)] uint16 *__CLASS; diff --git a/source4/librpc/ndr/ndr_wmi.c b/source4/librpc/ndr/ndr_wmi.c new file mode 100644 index 0000000000..69cbe95f40 --- /dev/null +++ b/source4/librpc/ndr/ndr_wmi.c @@ -0,0 +1,849 @@ +/* + Unix SMB/CIFS implementation. + + routines for marshalling/unmarshalling DCOM string arrays + + Copyright (C) Jelmer Vernooij 2004 + + 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. +*/ +//#define NDR_CHECK_DEBUG +#include "includes.h" +#include "librpc/gen_ndr/ndr_dcom.h" +#include "librpc/gen_ndr/ndr_wmi.h" +#include "librpc/ndr/ndr_wmi.h" + +// Just for debugging +int NDR_CHECK_depth = 0; +int NDR_CHECK_shift = 0x18; + +int get_CIMTYPE_size(int t) +{ + if (t & CIM_FLAG_ARRAY) return 4; + t &= 0x1FF; + switch (t) { + case CIM_SINT8: + case CIM_UINT8: + return 1; + case CIM_SINT16: + case CIM_UINT16: + case CIM_BOOLEAN: + return 2; + case CIM_SINT32: + case CIM_UINT32: + case CIM_REAL32: + case CIM_STRING: + case CIM_DATETIME: + case CIM_REFERENCE: + case CIM_OBJECT: + return 4; + case CIM_SINT64: + case CIM_UINT64: + case CIM_REAL64: + return 8; + default: + DEBUG(0, ("Unknown CIMTYPE size for %04X", t)); + return 4; + } +} + +enum ndr_err_code ndr_push_BSTR(struct ndr_push *ndr, int ndr_flags, const struct BSTR *r) +{ + uint32_t len; + uint32_t flags; + enum ndr_err_code status; + len = strlen(r->data); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0x72657355)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, len)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 2*len)); + flags = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NOTERM | LIBNDR_FLAG_STR_SIZE4); + status = ndr_push_string(ndr, NDR_SCALARS, r->data); + ndr->flags = flags; + return status; + } + return NDR_ERR_SUCCESS; +} + +enum ndr_err_code ndr_pull_BSTR(struct ndr_pull *ndr, int ndr_flags, struct BSTR *r) +{ + return NDR_ERR_BAD_SWITCH; +} + +void ndr_print_BSTR(struct ndr_print *ndr, const char *name, const struct BSTR *r) +{ + ndr->print(ndr, "%-25s: BSTR(\"%s\")", name, r->data); +} + +enum ndr_err_code ndr_push_CIMSTRING(struct ndr_push *ndr, int ndr_flags, const CIMSTRING *r) +{ + uint8_t u; + enum ndr_err_code status; + + if (!(ndr_flags & NDR_SCALARS)) return NDR_ERR_SUCCESS; + + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, 0)); + u = ndr->flags; + ndr->flags |= LIBNDR_FLAG_STR_ASCII | LIBNDR_FLAG_STR_NULLTERM; + status = ndr_push_string(ndr, NDR_SCALARS, *r); + DEBUG(9, ("%08X: Push string: %s\n", ndr->offset, *r)); + ndr->flags = u; + return status; +} + +enum ndr_err_code ndr_pull_CIMSTRING(struct ndr_pull *ndr, int ndr_flags, CIMSTRING *r) +{ + uint8_t u; + enum ndr_err_code status; + + if (!(ndr_flags & NDR_SCALARS)) return NDR_ERR_SUCCESS; + + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &u)); + switch (u) { + case 0: + u = ndr->flags; + ndr->flags |= LIBNDR_FLAG_STR_ASCII | LIBNDR_FLAG_STR_NULLTERM; + status = ndr_pull_string(ndr, NDR_SCALARS, r); + DEBUG(10, ("%08X: Pull string: %s\n", ndr->offset, *r)); + ndr->flags = u; + return status; + case 1: + u = ndr->flags; + ndr->flags |= LIBNDR_FLAG_STR_NULLTERM; + status = ndr_pull_string(ndr, NDR_SCALARS, r); + DEBUG(10, ("%08X: Pull string: %s\n", ndr->offset, *r)); + ndr->flags = u; + return status; + default: return NDR_ERR_BAD_SWITCH; + } +} + +void ndr_print_CIMSTRING(struct ndr_print *ndr, const char *name, const CIMSTRING *r) +{ + ndr->print(ndr, "%-25s: \"%s\"", name, *r); +} + +enum ndr_err_code ndr_push_CIMSTRINGS(struct ndr_push *ndr, int ndr_flags, const struct CIMSTRINGS *r) +{ + uint32_t ofs_size, ofs, i; + + if (!(ndr_flags & NDR_SCALARS)) return NDR_ERR_SUCCESS; + + ofs_size = ndr->offset; + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + + for (i = 0; i < r->count; ++i) { + ofs = ndr->offset; + NDR_CHECK(ndr_push_CIMSTRING(ndr, ndr_flags, &r->item[i])); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr->offset - ofs)); + } + ofs = ndr->offset; + ndr->offset = ofs_size; + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ofs - ofs_size)); + ndr->offset = ofs; + + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_CIMSTRINGS(struct ndr_pull *ndr, int ndr_flags, struct CIMSTRINGS *r) +{ + uint32_t endofs; + uint32_t len; + TALLOC_CTX *mem_ctx; + uint32_t u; + + if (!(ndr_flags & NDR_SCALARS)) return NDR_ERR_SUCCESS; + + mem_ctx = ndr->current_mem_ctx; + + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &endofs)); + endofs += ndr->offset - sizeof(endofs); + + r->count = 0; + len = 5; + r->item = talloc_array(mem_ctx, CIMSTRING, len); + ndr->current_mem_ctx = r->item; + while (ndr->offset < endofs) { + if (r->count >= len) { + len += 3; + r->item = talloc_realloc(mem_ctx, r->item, CIMSTRING, len); + } + NDR_CHECK(ndr_pull_CIMSTRING(ndr, ndr_flags, &r->item[r->count])); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &u)); + ++r->count; + } + + r->item = talloc_realloc(mem_ctx, r->item, CIMSTRING, r->count); + + ndr->current_mem_ctx = mem_ctx; + + return NDR_ERR_SUCCESS; +} + +static const char *qualifier_keys[] = {[1] = "key", [3] = "read", [6] = "provider", [7] = "dynamic", [10] = "CIMTYPE" }; +#define arr_sizeof(a) (sizeof(a)/sizeof(a[0])) +static const char *qn_unknown = "Unknown_qualifier_name"; + +_PUBLIC_ enum ndr_err_code ndr_push_WbemQualifier(struct ndr_push *ndr, int ndr_flags, const struct WbemQualifier *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->name)); + NDR_CHECK(ndr_push_WBEM_FLAVOR_TYPE(ndr, NDR_SCALARS, r->flavors)); + NDR_CHECK(ndr_push_CIMTYPE_ENUMERATION(ndr, NDR_SCALARS, r->cimtype)); + NDR_CHECK(ndr_push_set_switch_value(ndr, &r->value, r->cimtype & CIM_TYPEMASK)); + NDR_CHECK(ndr_push_CIMVAR(ndr, NDR_SCALARS, &r->value)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->name) { + uint32_t ofs; + int32_t i; + for (i = 0; i < arr_sizeof(qualifier_keys); ++i) + if (qualifier_keys[i] && !strcmp(r->name, qualifier_keys[i])) break; + if (i == arr_sizeof(qualifier_keys)) { + if (!strncmp(qn_unknown, r->name, sizeof(qn_unknown) - 1)) + i = atoi(r->name + sizeof(qn_unknown) - 1); + else + i = -1; + } + if (i >= 0) { + ofs = ndr->offset; + NDR_CHECK(ndr_token_retrieve(&ndr->relative_list, r->name, &ndr->offset)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0x80000000 | i)); + ndr->offset = ofs; + } else { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->name)); + NDR_CHECK(ndr_push_CIMSTRING(ndr, NDR_SCALARS, &r->name)); + } + } + NDR_CHECK(ndr_push_CIMVAR(ndr, NDR_BUFFERS, &r->value)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_WbemQualifier(struct ndr_pull *ndr, int ndr_flags, struct WbemQualifier *r) +{ + uint32_t _ptr_name; + TALLOC_CTX *_mem_save_name_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_name)); + if (_ptr_name != 0xFFFFFFFF) { + NDR_PULL_ALLOC(ndr, r->name); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->name, _ptr_name)); + } else { + r->name = NULL; + } + NDR_CHECK(ndr_pull_WBEM_FLAVOR_TYPE(ndr, NDR_SCALARS, &r->flavors)); + NDR_CHECK(ndr_pull_CIMTYPE_ENUMERATION(ndr, NDR_SCALARS, &r->cimtype)); + NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->value, r->cimtype & CIM_TYPEMASK)); + NDR_CHECK(ndr_pull_CIMVAR(ndr, NDR_SCALARS, &r->value)); + } + if (ndr_flags & NDR_BUFFERS) { + uint32_t relofs; + relofs = ndr_token_peek(&ndr->relative_list, r->name); + if (relofs & 0x80000000) { + relofs &= 0xFF; + if ((relofs < sizeof(qualifier_keys)/sizeof(qualifier_keys[0])) && qualifier_keys[relofs]) { + r->name = talloc_strdup(ndr->current_mem_ctx, qualifier_keys[relofs]); + } else { + r->name = talloc_asprintf(ndr->current_mem_ctx, "%s%d", qn_unknown, relofs); + } + } else if (r->name) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->name)); + _mem_save_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->name, 0); + NDR_CHECK(ndr_pull_CIMSTRING(ndr, NDR_SCALARS, &r->name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_name_0, 0); + ndr->offset = _relative_save_offset; + } + NDR_CHECK(ndr_pull_CIMVAR(ndr, NDR_BUFFERS, &r->value)); + } + return NDR_ERR_SUCCESS; +} + +enum ndr_err_code ndr_push_WbemQualifiers(struct ndr_push *ndr, int ndr_flags, const struct WbemQualifiers *r) +{ + uint32_t i, ofs, ofs_size; + + if (ndr_flags & NDR_SCALARS) { + ofs_size = ndr->offset; + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + for (i = 0; i < r->count; ++i) + NDR_CHECK(ndr_push_WbemQualifier(ndr, NDR_SCALARS, r->item[i])); + ofs = ndr->offset; + ndr->offset = ofs_size; + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ofs - ofs_size)); + ndr->offset = ofs; + } + if (ndr_flags & NDR_BUFFERS) { + for (i = 0; i < r->count; ++i) + NDR_CHECK(ndr_push_WbemQualifier(ndr, NDR_BUFFERS, r->item[i])); + } + return NDR_ERR_SUCCESS; +} + +enum ndr_err_code ndr_pull_WbemQualifiers(struct ndr_pull *ndr, int ndr_flags, struct WbemQualifiers *r) +{ + uint32_t endofs; + uint32_t len; + TALLOC_CTX *mem_ctx; + + mem_ctx = ndr->current_mem_ctx; + + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &endofs)); + endofs += ndr->offset - 4; + + r->count = 0; + len = 10; + r->item = talloc_array(mem_ctx, struct WbemQualifier*, len); + ndr->current_mem_ctx = r->item; + while (ndr->offset < endofs) { + if (r->count >= len) { + len += 3; + r->item = talloc_realloc(mem_ctx, r->item, struct WbemQualifier*, len); + } + NDR_PULL_ALLOC(ndr, r->item[r->count]); + NDR_CHECK(ndr_pull_WbemQualifier(ndr, NDR_SCALARS, r->item[r->count])); + ++r->count; + } + r->item = talloc_realloc(mem_ctx, r->item, struct WbemQualifier*, r->count); + } + if (ndr_flags & NDR_BUFFERS) { + uint32_t i; + ndr->current_mem_ctx = r->item; + for (i = 0; i < r->count; ++i) { + NDR_CHECK(ndr_pull_WbemQualifier(ndr, NDR_BUFFERS, r->item[i])); + } + } + + ndr->current_mem_ctx = mem_ctx; + + return NDR_ERR_SUCCESS; +} + +enum ndr_err_code ndr_push_DataWithStack(struct ndr_push *ndr, ndr_push_flags_fn_t fn, const void *r) +{ + uint32_t ofs, ofs_size, ofs_ssize; + + ofs_size = ndr->offset; + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + + NDR_CHECK(fn(ndr, NDR_SCALARS, r)); + + ofs_ssize = ndr->offset; + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + ndr->relative_base_offset = ndr->offset; + + NDR_CHECK(fn(ndr, NDR_BUFFERS, r)); + + ofs = ndr->offset; + ndr->offset = ofs_size; + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ofs-ofs_size)); + ndr->offset = ofs_ssize; + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, (ofs-ofs_ssize-4) | 0x80000000)); + ndr->offset = ofs; + + return NDR_ERR_SUCCESS; +} + +enum ndr_err_code ndr_pull_DataWithStack(struct ndr_pull *ndr, ndr_pull_flags_fn_t fn, void *r) +{ + uint32_t end, size, ssize, ndrend; + + end = ndr->offset; + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &size)); + NDR_PULL_NEED_BYTES(ndr, size - 4); + end += size; + ndrend = ndr->data_size; + ndr->data_size = end; + + NDR_CHECK(fn(ndr, NDR_SCALARS, r)); + + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &ssize)); + if (!(ssize & 0x80000000)) + return ndr_pull_error(ndr, NDR_ERR_VALIDATE, "ndr_pull_DataWithStack(%08X): Stack size without 31th bit set: 0x%08X", ndr->offset - 4, ssize); + ssize &= 0x7FFFFFFF; + NDR_PULL_NEED_BYTES(ndr, ssize); + ndr->data_size = ndr->offset + ssize; + + ndr->relative_base_offset = ndr->offset; + + NDR_CHECK(fn(ndr, NDR_BUFFERS, r)); + + ndr->data_size = ndrend; + ndr->offset = end; + + return NDR_ERR_SUCCESS; +} + +enum ndr_err_code ndr_push_uint32_flags(struct ndr_push *ndr, int ndr_flags, uint32_t v) +{ + if (ndr_flags & NDR_SCALARS) + return ndr_push_uint32(ndr, NDR_SCALARS, v); + return NDR_ERR_SUCCESS; +} + +enum ndr_err_code ndr_pull_uint32_flags(struct ndr_pull *ndr, int ndr_flags, uint32_t *v) +{ + if (ndr_flags & NDR_SCALARS) + return ndr_pull_uint32(ndr, NDR_SCALARS, v); + return NDR_ERR_SUCCESS; +} + +void copy_bits(const uint8_t *src, uint32_t bsrc, uint8_t *dst, uint32_t bdst, uint32_t count) +{ + uint8_t mask; + + src += bsrc >> 3; + bsrc &= 7; + dst += bdst >> 3; + bdst &= 7; + mask = ((1 << count) - 1); + *dst &= ~(mask << bdst); + *dst |= ((*src >> bsrc) & mask) << bdst; +} + +#define IS_CIMTYPE_PTR(t) (((t) & CIM_FLAG_ARRAY) || ((t) == CIM_STRING) || ((t) == CIM_DATETIME) || ((t) == CIM_REFERENCE)) +enum ndr_err_code ndr_push_WbemInstance_priv(struct ndr_push *ndr, int ndr_flags, const struct WbemClassObject *r) +{ + int i; + if (ndr_flags & NDR_SCALARS) { + uint32_t ofs, vofs; + + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->instance->u1_0)); + + if (r->instance->__CLASS) { + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->instance->__CLASS)); + } else { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0xFFFFFFFF)); + } + + ofs = ndr->offset; + NDR_PUSH_NEED_BYTES(ndr, r->obj_class->data_size); + + for (i = 0; i < r->obj_class->__PROPERTY_COUNT; ++i) { + copy_bits(&r->instance->properties[i].default_flags, 0, ndr->data + ndr->offset, 2*r->obj_class->properties[i].property.desc->nr, 2); + } + i = 0xFF; + copy_bits((uint8_t *)&i, 0, ndr->data + ndr->offset, 2*r->obj_class->__PROPERTY_COUNT, (8 - 2*r->obj_class->__PROPERTY_COUNT) % 7); + vofs = ofs + ((r->obj_class->__PROPERTY_COUNT + 3) >> 2); + + for (i = 0; i < r->obj_class->__PROPERTY_COUNT; ++i) { + NDR_CHECK(ndr_push_set_switch_value(ndr, &r->instance->data[i], r->obj_class->properties[i].property.desc->cimtype & CIM_TYPEMASK)); + ndr->offset = vofs + r->obj_class->properties[i].property.desc->offset; + NDR_CHECK(ndr_push_CIMVAR(ndr, NDR_SCALARS, &r->instance->data[i])); + } + ndr->offset = ofs + r->obj_class->data_size; + + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->instance->u2_4)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->instance->u3_1)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->instance->__CLASS) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->instance->__CLASS)); + NDR_CHECK(ndr_push_CIMSTRING(ndr, NDR_SCALARS, &r->instance->__CLASS)); + } + for (i = 0; i < r->obj_class->__PROPERTY_COUNT; ++i) { + NDR_CHECK(ndr_push_CIMVAR(ndr, NDR_BUFFERS, &r->instance->data[i])); + } + } + return NDR_ERR_SUCCESS; +} + +enum ndr_err_code ndr_pull_WbemInstance_priv(struct ndr_pull *ndr, int ndr_flags, const struct WbemClassObject *r) +{ + int i; + + if (!r->obj_class) { +DEBUG(1,("ndr_pull_WbemInstance_priv: There is no class for given instance\n")); + return NDR_ERR_VALIDATE; + } + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); + if (ndr_flags & NDR_SCALARS) { + uint32_t ofs, vofs; + uint32_t _ptr___CLASS; + + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->instance->u1_0)); + + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr___CLASS)); + if (_ptr___CLASS != 0xFFFFFFFF) { + NDR_PULL_ALLOC(ndr, r->instance->__CLASS); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->instance->__CLASS, _ptr___CLASS)); + } else { + r->instance->__CLASS = NULL; + } + + ofs = ndr->offset; + NDR_PULL_NEED_BYTES(ndr, r->obj_class->data_size); + NDR_PULL_ALLOC_N(ndr, r->instance->default_flags, r->obj_class->__PROPERTY_COUNT); + for (i = 0; i < r->obj_class->__PROPERTY_COUNT; ++i) { + r->instance->default_flags[i] = 0; + copy_bits(ndr->data + ndr->offset, 2*r->obj_class->properties[i].property.desc->nr, &r->instance->properties[i].default_flags, 0, 2); + } + vofs = ofs + ((r->obj_class->__PROPERTY_COUNT + 3) >> 2); + + NDR_PULL_ALLOC_N(ndr, r->instance->data, r->obj_class->__PROPERTY_COUNT); + memset(r->instance->data, 0, sizeof(*r->instance->data) * r->obj_class->__PROPERTY_COUNT); + for (i = 0; i < r->obj_class->__PROPERTY_COUNT; ++i) { + NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->instance->data[i], r->obj_class->properties[i].property.desc->cimtype & CIM_TYPEMASK)); + ndr->offset = vofs + r->obj_class->properties[i].property.desc->offset; + NDR_CHECK(ndr_pull_CIMVAR(ndr, NDR_SCALARS, &r->instance->data[i])); + } + ndr->offset = ofs + r->obj_class->data_size; + + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->instance->u2_4)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->instance->u3_1)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->instance->__CLASS) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->instance->__CLASS)); + NDR_CHECK(ndr_pull_CIMSTRING(ndr, NDR_SCALARS, &r->instance->__CLASS)); + ndr->offset = _relative_save_offset; + } + for (i = 0; i < r->obj_class->__PROPERTY_COUNT; ++i) { + NDR_CHECK(ndr_pull_CIMVAR(ndr, NDR_BUFFERS, &r->instance->data[i])); + } + } + return NDR_ERR_SUCCESS; +} + +void ndr_print_WbemInstance_priv(struct ndr_print *ndr, const char *name, const struct WbemClassObject *r) +{ + int i; + + ndr_print_array_uint8(ndr, "default_flags", r->instance->default_flags, r->obj_class->__PROPERTY_COUNT); + + ndr->print(ndr, "%s: ARRAY(%d)", "data", r->obj_class->__PROPERTY_COUNT); + ndr->depth++; + for (i = 0; i < r->obj_class->__PROPERTY_COUNT; ++i) { + ndr->print(ndr, "%s[%d]", "data", i); + ndr->depth++; + ndr_print_set_switch_value(ndr, &r->instance->data[i], r->obj_class->properties[i].property.desc->cimtype & CIM_TYPEMASK); + ndr_print_CIMVAR(ndr, r->obj_class->properties[i].property.name, &r->instance->data[i]); + ndr->depth--; + } + ndr->depth--; +} + +enum ndr_err_code ndr_push_WbemClassObject(struct ndr_push *ndr, int ndr_flags, const struct WbemClassObject *r) +{ + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->flags)); + if (r->flags & WCF_CLASS) { + NDR_CHECK(ndr_push_CIMSTRING(ndr, NDR_SCALARS, &r->__SERVER)); + NDR_CHECK(ndr_push_CIMSTRING(ndr, NDR_SCALARS, &r->__NAMESPACE)); + } + if (r->flags & WCF_DECORATIONS) { + NDR_CHECK(ndr_push_DataWithStack(ndr, (ndr_push_flags_fn_t)ndr_push_WbemClass, r->sup_class)); + NDR_CHECK(ndr_push_DataWithStack(ndr, (ndr_push_flags_fn_t)ndr_push_WbemMethods, r->sup_methods)); + } + if (r->flags & (WCF_CLASS | WCF_INSTANCE)) { + NDR_CHECK(ndr_push_DataWithStack(ndr, (ndr_push_flags_fn_t)ndr_push_WbemClass, r->obj_class)); + } + if (r->flags & WCF_DECORATIONS) { + NDR_CHECK(ndr_push_DataWithStack(ndr, (ndr_push_flags_fn_t)ndr_push_WbemMethods, r->obj_methods)); + } + if (r->flags & WCF_INSTANCE) { + NDR_CHECK(ndr_push_DataWithStack(ndr, (ndr_push_flags_fn_t)ndr_push_WbemInstance_priv, r)); + } + return NDR_ERR_SUCCESS; +} + +enum ndr_err_code ndr_pull_WbemClassObject(struct ndr_pull *ndr, int ndr_flags, struct WbemClassObject *r) +{ + TALLOC_CTX *tc; + + tc = NDR_PULL_GET_MEM_CTX(ndr); + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->flags)); + if (r->flags & WCF_CLASS) { + NDR_CHECK(ndr_pull_CIMSTRING(ndr, NDR_SCALARS, &r->__SERVER)); + NDR_CHECK(ndr_pull_CIMSTRING(ndr, NDR_SCALARS, &r->__NAMESPACE)); + } + if (r->flags & WCF_DECORATIONS) { + r->sup_class = talloc_zero(r, struct WbemClass); + NDR_PULL_SET_MEM_CTX(ndr, r->sup_class, 0); + NDR_CHECK(ndr_pull_DataWithStack(ndr, (ndr_pull_flags_fn_t)ndr_pull_WbemClass, r->sup_class)); + r->sup_methods = talloc_zero(r, struct WbemMethods); + NDR_PULL_SET_MEM_CTX(ndr, r->sup_methods, 0); + NDR_CHECK(ndr_pull_DataWithStack(ndr, (ndr_pull_flags_fn_t)ndr_pull_WbemMethods, r->sup_methods)); + NDR_PULL_SET_MEM_CTX(ndr, tc, 0); + } else + r->sup_class = NULL; + if (r->flags & (WCF_CLASS | WCF_INSTANCE)) { + r->obj_class = talloc_zero(r, struct WbemClass); + NDR_PULL_SET_MEM_CTX(ndr, r->obj_class, 0); + NDR_CHECK(ndr_pull_DataWithStack(ndr, (ndr_pull_flags_fn_t)ndr_pull_WbemClass, r->obj_class)); + NDR_PULL_SET_MEM_CTX(ndr, tc, 0); + } + if (r->flags & WCF_DECORATIONS) { + r->obj_methods = talloc_zero(r, struct WbemMethods); + NDR_PULL_SET_MEM_CTX(ndr, r->obj_methods, 0); + NDR_CHECK(ndr_pull_DataWithStack(ndr, (ndr_pull_flags_fn_t)ndr_pull_WbemMethods, r->obj_methods)); + NDR_PULL_SET_MEM_CTX(ndr, tc, 0); + } + if (r->flags & WCF_INSTANCE) { + r->instance = talloc_zero(r, struct WbemInstance); + NDR_PULL_SET_MEM_CTX(ndr, r->instance, 0); + NDR_CHECK(ndr_pull_DataWithStack(ndr, (ndr_pull_flags_fn_t)ndr_pull_WbemInstance_priv, r)); + NDR_PULL_SET_MEM_CTX(ndr, tc, 0); + } else + r->instance = NULL; + return NDR_ERR_SUCCESS; +} + +enum ndr_err_code ndr_pull_WbemClassObject_Object(struct ndr_pull *ndr, int ndr_flags, struct WbemClassObject *r) +{ + TALLOC_CTX *tc; + + tc = NDR_PULL_GET_MEM_CTX(ndr); + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->flags)); + if (r->flags & WCF_CLASS) { + NDR_CHECK(ndr_pull_CIMSTRING(ndr, NDR_SCALARS, &r->__SERVER)); + NDR_CHECK(ndr_pull_CIMSTRING(ndr, NDR_SCALARS, &r->__NAMESPACE)); + } + if (r->flags & WCF_INSTANCE) { + r->instance = talloc_zero(r, struct WbemInstance); + NDR_PULL_SET_MEM_CTX(ndr, r->instance, 0); + NDR_CHECK(ndr_pull_DataWithStack(ndr, (ndr_pull_flags_fn_t)ndr_pull_WbemInstance_priv, r)); + NDR_PULL_SET_MEM_CTX(ndr, tc, 0); + } else + r->instance = NULL; + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_WbemClassObject(struct ndr_print *ndr, const char *name, const struct WbemClassObject *r) +{ + ndr_print_struct(ndr, name, "WbemClassObject"); + { + uint32_t _flags_save_STRUCT = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); + ndr->depth++; + ndr_print_WCO_FLAGS(ndr, "flags", r->flags); + if (r->flags & WCF_CLASS) { + ndr_print_ptr(ndr, "__SERVER", r->__SERVER); + ndr->depth++; + ndr_print_CIMSTRING(ndr, "__SERVER", &r->__SERVER); + ndr->depth--; + ndr_print_ptr(ndr, "__NAMESPACE", r->__NAMESPACE); + ndr->depth++; + ndr_print_CIMSTRING(ndr, "__NAMESPACE", &r->__NAMESPACE); + ndr->depth--; + } + if (r->flags & WCF_DECORATIONS) { + ndr_print_ptr(ndr, "sup_class", r->sup_class); + ndr->depth++; + if (r->sup_class) { + ndr_print_WbemClass(ndr, "sup_class", r->sup_class); + } + ndr->depth--; + ndr_print_ptr(ndr, "sup_methods", r->sup_methods); + ndr->depth++; + if (r->sup_methods) { + ndr_print_WbemMethods(ndr, "sup_methods", r->sup_methods); + } + ndr->depth--; + } + if (r->flags & (WCF_CLASS | WCF_INSTANCE)) { + ndr_print_ptr(ndr, "obj_class", r->obj_class); + ndr->depth++; + if (r->obj_class) { + ndr_print_WbemClass(ndr, "obj_class", r->obj_class); + } + ndr->depth--; + } + if (r->flags & WCF_DECORATIONS) { + ndr_print_ptr(ndr, "obj_methods", r->obj_methods); + ndr->depth++; + if (r->obj_methods) { + ndr_print_WbemMethods(ndr, "obj_methods", r->obj_methods); + } + ndr->depth--; + } + if (r->flags & WCF_INSTANCE) { + ndr_print_ptr(ndr, "instance", r->instance); + ndr->depth++; + if (r->instance) { + ndr_print_WbemInstance_priv(ndr, "instance", r); + } + ndr->depth--; + } + ndr->depth--; + ndr->flags = _flags_save_STRUCT; + } +} + +_PUBLIC_ enum ndr_err_code ndr_push_WbemClass(struct ndr_push *ndr, int ndr_flags, const struct WbemClass *r) +{ + uint32_t cntr_properties_0; + uint32_t i, ofs, vofs; + { + uint32_t _flags_save_STRUCT = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->u_0)); + if (r->__CLASS) { + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->__CLASS)); + } else { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0xFFFFFFFF)); + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->data_size)); + NDR_CHECK(ndr_push_CIMSTRINGS(ndr, NDR_SCALARS, &r->__DERIVATION)); + NDR_CHECK(ndr_push_WbemQualifiers(ndr, NDR_SCALARS, &r->qualifiers)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->__PROPERTY_COUNT)); + for (cntr_properties_0 = 0; cntr_properties_0 < r->__PROPERTY_COUNT; cntr_properties_0++) { + NDR_CHECK(ndr_push_WbemProperty(ndr, NDR_SCALARS, &r->properties[cntr_properties_0].property)); + } + + ofs = ndr->offset; + NDR_PUSH_NEED_BYTES(ndr, r->data_size); + + for (i = 0; i < r->__PROPERTY_COUNT; ++i) { + copy_bits(&r->properties[i].default_flags, 0, ndr->data + ndr->offset, 2*r->properties[i].property.desc->nr, 2); + } + i = 0xFF; + copy_bits((uint8_t *)&i, 0, ndr->data + ndr->offset, 2*r->__PROPERTY_COUNT, (8 - 2*r->__PROPERTY_COUNT) % 7); + vofs = ofs + ((r->__PROPERTY_COUNT + 3) >> 2); + for (i = 0; i < r->__PROPERTY_COUNT; ++i) { + NDR_CHECK(ndr_push_set_switch_value(ndr, &r->properties[i].default_values, r->properties[i].property.desc->cimtype & CIM_TYPEMASK)); + ndr->offset = vofs + r->properties[i].property.desc->offset; + if ((r->properties[i].default_flags & DEFAULT_FLAG_EMPTY) && IS_CIMTYPE_PTR(r->properties[i].property.desc->cimtype & CIM_TYPEMASK)) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0xFFFFFFFF)); + } else { + NDR_CHECK(ndr_push_CIMVAR(ndr, NDR_SCALARS, &r->properties[i].default_values)); + } + } + ndr->offset = ofs + r->data_size; + } + if (ndr_flags & NDR_BUFFERS) { + if (r->__CLASS) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->__CLASS)); + NDR_CHECK(ndr_push_CIMSTRING(ndr, NDR_SCALARS, &r->__CLASS)); + } + NDR_CHECK(ndr_push_CIMSTRINGS(ndr, NDR_BUFFERS, &r->__DERIVATION)); + NDR_CHECK(ndr_push_WbemQualifiers(ndr, NDR_BUFFERS, &r->qualifiers)); + for (cntr_properties_0 = 0; cntr_properties_0 < r->__PROPERTY_COUNT; cntr_properties_0++) { + NDR_CHECK(ndr_push_WbemProperty(ndr, NDR_BUFFERS, &r->properties[cntr_properties_0].property)); + } + for (i = 0; i < r->__PROPERTY_COUNT; ++i) { + if (r->properties[i].default_flags & DEFAULT_FLAG_EMPTY) continue; + NDR_CHECK(ndr_push_CIMVAR(ndr, NDR_BUFFERS, &r->properties[i].default_values)); + } + } + ndr->flags = _flags_save_STRUCT; + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_WbemClass(struct ndr_pull *ndr, int ndr_flags, struct WbemClass *r) +{ + uint32_t _ptr___CLASS; + uint32_t cntr_properties_0; + TALLOC_CTX *_mem_save_properties_0; + uint32_t i; + + { + uint32_t _flags_save_STRUCT = ndr->flags; + + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->u_0)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr___CLASS)); + if (_ptr___CLASS != 0xFFFFFFFF) { + NDR_PULL_ALLOC(ndr, r->__CLASS); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->__CLASS, _ptr___CLASS)); + } else { + r->__CLASS = NULL; + } + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->data_size)); + NDR_CHECK(ndr_pull_CIMSTRINGS(ndr, NDR_SCALARS, &r->__DERIVATION)); + NDR_CHECK(ndr_pull_WbemQualifiers(ndr, NDR_SCALARS, &r->qualifiers)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->__PROPERTY_COUNT)); + NDR_PULL_ALLOC_N(ndr, r->properties, r->__PROPERTY_COUNT); + _mem_save_properties_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->properties, 0); + for (cntr_properties_0 = 0; cntr_properties_0 < r->__PROPERTY_COUNT; cntr_properties_0++) { + NDR_CHECK(ndr_pull_WbemProperty(ndr, NDR_SCALARS, &(r->properties)[cntr_properties_0])); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_properties_0, 0); + + NDR_PULL_NEED_BYTES(ndr, r->data_size); + + NDR_PULL_ALLOC_N(ndr, r->default_flags, r->__PROPERTY_COUNT); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->default_flags, ndr->offset)); + + NDR_PULL_ALLOC_N(ndr, r->default_values, r->__PROPERTY_COUNT); + memset(r->default_values, 0, sizeof(*r->default_values) * r->__PROPERTY_COUNT); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->default_values, ndr->offset + ((r->__PROPERTY_COUNT + 3) >> 2))); + + ndr->offset += r->data_size; + } + if (ndr_flags & NDR_BUFFERS) { + if (r->__CLASS) { + TALLOC_CTX *_mem_save___CLASS_0; + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->__CLASS)); + _mem_save___CLASS_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->__CLASS, 0); + NDR_CHECK(ndr_pull_CIMSTRING(ndr, NDR_SCALARS, &r->__CLASS)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save___CLASS_0, 0); + ndr->offset = _relative_save_offset; + } + NDR_CHECK(ndr_pull_CIMSTRINGS(ndr, NDR_BUFFERS, &r->__DERIVATION)); + NDR_CHECK(ndr_pull_WbemQualifiers(ndr, NDR_BUFFERS, &r->qualifiers)); + _mem_save_properties_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->properties, 0); + for (cntr_properties_0 = 0; cntr_properties_0 < r->__PROPERTY_COUNT; cntr_properties_0++) { + NDR_CHECK(ndr_pull_WbemProperty(ndr, NDR_BUFFERS, &(r->properties)[cntr_properties_0].property)); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_properties_0, 0); + { + uint32_t ofs; + NDR_CHECK(ndr_token_retrieve(&ndr->relative_list, r->default_flags, &ofs)); + for (i = 0; i < r->__PROPERTY_COUNT; ++i) { + r->properties[i].default_flags = 0; + copy_bits(ndr->data + ofs, 2*r->properties[i].property.desc->nr, &r->properties[i].default_flags, 0, 2); + } + } + { + uint32_t ofs; + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_token_retrieve(&ndr->relative_list, r->default_values, &ofs)); + for (i=0; i < r->__PROPERTY_COUNT; ++i) { + if (r->properties[i].default_flags & DEFAULT_FLAG_EMPTY) continue; + NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->properties[i].default_values, r->properties[i].property.desc->cimtype & CIM_TYPEMASK)); + ndr->offset = ofs + r->properties[i].property.desc->offset; + NDR_CHECK(ndr_pull_CIMVAR(ndr, NDR_SCALARS|NDR_BUFFERS, &r->properties[i].default_values)); + } + ndr->offset = _relative_save_offset; + } + } + ndr->flags = _flags_save_STRUCT; + } + return NDR_ERR_SUCCESS; +} diff --git a/source4/librpc/ndr/ndr_wmi.h b/source4/librpc/ndr/ndr_wmi.h new file mode 100644 index 0000000000..0dbf3844ba --- /dev/null +++ b/source4/librpc/ndr/ndr_wmi.h @@ -0,0 +1,6 @@ +typedef const char *CIMSTRING; +enum ndr_err_code ndr_pull_WbemClassObject_Object(struct ndr_pull *ndr, int ndr_flags, struct WbemClassObject *r); +enum ndr_err_code ndr_pull_WbemClassObject(struct ndr_pull *ndr, int ndr_flags, struct WbemClassObject *r); +enum ndr_err_code ndr_push_WbemClassObject(struct ndr_push *ndr, int ndr_flags, const struct WbemClassObject *r); +enum ndr_err_code ndr_pull_CIMSTRING(struct ndr_pull *ndr, int ndr_flags, CIMSTRING *r); +enum ndr_err_code ndr_push_CIMSTRING(struct ndr_push *ndr, int ndr_flags, const CIMSTRING *r); -- cgit