int message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type) { _cleanup_netlink_message_unref_ sd_netlink_message *m = NULL; const NLType *nl_type; size_t size; int r; r = type_system_get_type(&type_system_root, &nl_type, type); if (r < 0) return r; if (type_get_type(nl_type) != NETLINK_TYPE_NESTED) return -EINVAL; r = message_new_empty(rtnl, &m); if (r < 0) return r; size = NLMSG_SPACE(type_get_size(nl_type)); assert(size >= sizeof(struct nlmsghdr)); m->hdr = malloc0(size); if (!m->hdr) return -ENOMEM; m->hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; type_get_type_system(nl_type, &m->containers[0].type_system); m->hdr->nlmsg_len = size; m->hdr->nlmsg_type = type; *ret = m; m = NULL; return 0; }
static void clear_output_vars( const var_list_t *args ) { const var_t *arg; if (!args) return; LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry ) { if (is_attr(arg->attrs, ATTR_IN)) continue; if (!is_attr(arg->attrs, ATTR_OUT)) continue; if (is_ptr(arg->type)) { if (type_get_type(type_pointer_get_ref(arg->type)) == TYPE_BASIC) continue; if (type_get_type(type_pointer_get_ref(arg->type)) == TYPE_ENUM) continue; } print_proxy( "if (%s) MIDL_memset( %s, 0, sizeof( *%s ));\n", arg->name, arg->name, arg->name ); } }
int sd_netlink_message_rewind(sd_netlink_message *m) { const NLType *nl_type; uint16_t type; size_t size; unsigned i; int r; assert_return(m, -EINVAL); /* don't allow appending to message once parsed */ if (!m->sealed) rtnl_message_seal(m); for (i = 1; i <= m->n_containers; i++) m->containers[i].attributes = mfree(m->containers[i].attributes); m->n_containers = 0; if (m->containers[0].attributes) /* top-level attributes have already been parsed */ return 0; assert(m->hdr); r = type_system_get_type(&type_system_root, &nl_type, m->hdr->nlmsg_type); if (r < 0) return r; type = type_get_type(nl_type); size = type_get_size(nl_type); if (type == NETLINK_TYPE_NESTED) { const NLTypeSystem *type_system; type_get_type_system(nl_type, &type_system); m->containers[0].type_system = type_system; r = netlink_container_parse(m, &m->containers[m->n_containers], type_system_get_count(type_system), (struct rtattr*)((uint8_t*)NLMSG_DATA(m->hdr) + NLMSG_ALIGN(size)), NLMSG_PAYLOAD(m->hdr, size)); if (r < 0) return r; } return 0; }
static int message_attribute_has_type(sd_netlink_message *m, size_t *out_size, uint16_t attribute_type, uint16_t data_type) { const NLType *type; int r; assert(m); r = type_system_get_type(m->containers[m->n_containers].type_system, &type, attribute_type); if (r < 0) return r; if (type_get_type(type) != data_type) return -EINVAL; if (out_size) *out_size = type_get_size(type); return 0; }
static unsigned short builtin_vt(const type_t *t) { const char *kw = t->name; struct oatype key; const struct oatype *kwp; key.kw = kw; #ifdef KW_BSEARCH kwp = bsearch(&key, oatypes, NTYPES, sizeof(oatypes[0]), kw_cmp_func); #else { unsigned int i; for (kwp=NULL, i=0; i < NTYPES; i++) if (!kw_cmp_func(&key, &oatypes[i])) { kwp = &oatypes[i]; break; } } #endif if (kwp) { return kwp->vt; } if (is_string_type (t->attrs, t)) { const type_t *elem_type; if (is_array(t)) elem_type = type_array_get_element(t); else elem_type = type_pointer_get_ref(t); if (type_get_type(elem_type) == TYPE_BASIC) { switch (type_basic_get_type(elem_type)) { case TYPE_BASIC_CHAR: return VT_LPSTR; case TYPE_BASIC_WCHAR: return VT_LPWSTR; default: break; } } } return 0; }
int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short type_id) { const NLType *nl_type; const NLTypeSystem *type_system; void *container; uint16_t type; size_t size; int r; assert_return(m, -EINVAL); assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -EINVAL); r = type_system_get_type(m->containers[m->n_containers].type_system, &nl_type, type_id); if (r < 0) return r; type = type_get_type(nl_type); if (type == NETLINK_TYPE_NESTED) { r = type_system_get_type_system(m->containers[m->n_containers].type_system, &type_system, type_id); if (r < 0) return r; } else if (type == NETLINK_TYPE_UNION) { const NLTypeSystemUnion *type_system_union; r = type_system_get_type_system_union(m->containers[m->n_containers].type_system, &type_system_union, type_id); if (r < 0) return r; switch (type_system_union->match_type) { case NL_MATCH_SIBLING: { const char *key; r = sd_netlink_message_read_string(m, type_system_union->match, &key); if (r < 0) return r; r = type_system_union_get_type_system(type_system_union, &type_system, key); if (r < 0) return r; break; } case NL_MATCH_PROTOCOL: { int family; r = sd_rtnl_message_get_family(m, &family); if (r < 0) return r; r = type_system_union_protocol_get_type_system(type_system_union, &type_system, family); if (r < 0) return r; break; } default: assert_not_reached("sd-netlink: invalid type system union type"); } } else return -EINVAL; r = netlink_message_read_internal(m, type_id, &container, NULL); if (r < 0) return r; else size = (size_t)r; m->n_containers ++; r = netlink_container_parse(m, &m->containers[m->n_containers], type_system_get_count(type_system), container, size); if (r < 0) { m->n_containers --; return r; } m->containers[m->n_containers].type_system = type_system; return 0; }
unsigned short get_type_vt(type_t *t) { unsigned short vt; chat("get_type_vt: %p type->name %s\n", t, t->name); if (t->name) { vt = builtin_vt(t); if (vt) return vt; } if (type_is_alias(t) && is_attr(t->attrs, ATTR_PUBLIC)) return VT_USERDEFINED; switch (type_get_type(t)) { case TYPE_BASIC: switch (type_basic_get_type(t)) { case TYPE_BASIC_BYTE: return VT_UI1; case TYPE_BASIC_CHAR: case TYPE_BASIC_INT8: if (type_basic_get_sign(t) > 0) return VT_UI1; else return VT_I1; case TYPE_BASIC_WCHAR: return VT_I2; /* mktyplib seems to parse wchar_t as short */ case TYPE_BASIC_INT16: if (type_basic_get_sign(t) > 0) return VT_UI2; else return VT_I2; case TYPE_BASIC_INT: if (type_basic_get_sign(t) > 0) return VT_UINT; else return VT_INT; case TYPE_BASIC_INT32: case TYPE_BASIC_ERROR_STATUS_T: if (type_basic_get_sign(t) > 0) return VT_UI4; else return VT_I4; case TYPE_BASIC_INT64: case TYPE_BASIC_HYPER: if (type_basic_get_sign(t) > 0) return VT_UI8; else return VT_I8; case TYPE_BASIC_INT3264: if (typelib_kind == SYS_WIN64) { if (type_basic_get_sign(t) > 0) return VT_UI8; else return VT_I8; } else { if (type_basic_get_sign(t) > 0) return VT_UI4; else return VT_I4; } case TYPE_BASIC_FLOAT: return VT_R4; case TYPE_BASIC_DOUBLE: return VT_R8; case TYPE_BASIC_HANDLE: error("handles can't be used in typelibs\n"); } break; case TYPE_POINTER: return VT_PTR; case TYPE_ARRAY: if (type_array_is_decl_as_ptr(t)) { if (match(type_array_get_element(t)->name, "SAFEARRAY")) return VT_SAFEARRAY; } else error("get_type_vt: array types not supported\n"); return VT_PTR; case TYPE_INTERFACE: if(match(t->name, "IUnknown")) return VT_UNKNOWN; if(match(t->name, "IDispatch")) return VT_DISPATCH; return VT_USERDEFINED; case TYPE_ENUM: case TYPE_STRUCT: case TYPE_COCLASS: case TYPE_MODULE: case TYPE_UNION: case TYPE_ENCAPSULATED_UNION: return VT_USERDEFINED; case TYPE_VOID: return VT_VOID; case TYPE_ALIAS: /* aliases should be filtered out by the type_get_type call above */ assert(0); break; case TYPE_FUNCTION: error("get_type_vt: functions not supported\n"); break; case TYPE_BITFIELD: error("get_type_vt: bitfields not supported\n"); break; } return 0; }
int is_array(const type_t *t) { return type_get_type(t) == TYPE_ARRAY; }
int is_ptr(const type_t *t) { return type_get_type(t) == TYPE_POINTER; }
static void free_variable( const var_t *arg, const char *local_var_prefix ) { unsigned int type_offset = arg->typestring_offset; type_t *type = arg->type; write_parameter_conf_or_var_exprs(proxy, indent, local_var_prefix, PHASE_FREE, arg, FALSE); switch (typegen_detect_type(type, arg->attrs, TDT_IGNORE_STRINGS)) { case TGT_ENUM: case TGT_BASIC: break; case TGT_STRUCT: if (get_struct_fc(type) != RPC_FC_STRUCT) print_proxy("/* FIXME: %s code for %s struct type 0x%x missing */\n", __FUNCTION__, arg->name, get_struct_fc(type) ); break; case TGT_IFACE_POINTER: case TGT_POINTER: case TGT_ARRAY: print_proxy( "NdrClearOutParameters( &__frame->_StubMsg, "); fprintf(proxy, "&__MIDL_TypeFormatString.Format[%u], ", type_offset ); fprintf(proxy, "(void *)%s );\n", arg->name ); break; default: print_proxy("/* FIXME: %s code for %s type %d missing */\n", __FUNCTION__, arg->name, type_get_type(type) ); } }
static void free_variable( const var_t *arg, const char *local_var_prefix ) { unsigned int type_offset = arg->type->typestring_offset; expr_t *iid; type_t *type = arg->type; expr_t *size = get_size_is_expr(type, arg->name); if (size) { print_proxy( "__frame->_StubMsg.MaxCount = " ); write_expr(proxy, size, 0, 1, NULL, NULL, local_var_prefix); fprintf(proxy, ";\n\n"); print_proxy( "NdrClearOutParameters( &__frame->_StubMsg, "); fprintf(proxy, "&__MIDL_TypeFormatString.Format[%u], ", type_offset ); fprintf(proxy, "(void*)%s );\n", arg->name ); return; } switch (typegen_detect_type(type, arg->attrs, TDT_IGNORE_STRINGS)) { case TGT_ENUM: case TGT_BASIC: break; case TGT_STRUCT: if (get_struct_fc(type) != RPC_FC_STRUCT) print_proxy("/* FIXME: %s code for %s struct type 0x%x missing */\n", __FUNCTION__, arg->name, get_struct_fc(type) ); break; case TGT_IFACE_POINTER: iid = get_attrp( arg->attrs, ATTR_IIDIS ); if( iid ) { print_proxy( "__frame->_StubMsg.MaxCount = (ULONG_PTR) " ); write_expr(proxy, iid, 1, 1, NULL, NULL, local_var_prefix); print_proxy( ";\n\n" ); } /* fall through */ case TGT_POINTER: if (get_pointer_fc(type, arg->attrs, TRUE) == RPC_FC_FP) { print_proxy( "NdrClearOutParameters( &__frame->_StubMsg, "); fprintf(proxy, "&__MIDL_TypeFormatString.Format[%u], ", type_offset ); fprintf(proxy, "(void*)%s );\n", arg->name ); } else print_proxy("/* FIXME: %s code for %s type %d missing */\n", __FUNCTION__, arg->name, type_get_type(type) ); break; default: print_proxy("/* FIXME: %s code for %s type %d missing */\n", __FUNCTION__, arg->name, type_get_type(type) ); } }