diff --git a/dlls/rpcrt4/ndr_typelib.c b/dlls/rpcrt4/ndr_typelib.c index e99eb3e9a6e..37926dfb994 100644 --- a/dlls/rpcrt4/ndr_typelib.c +++ b/dlls/rpcrt4/ndr_typelib.c @@ -189,6 +189,24 @@ static unsigned char get_array_fc(ITypeInfo *typeinfo, TYPEDESC *desc) return FC_BOGUS_ARRAY; } +static size_t write_struct_tfs(ITypeInfo *typeinfo, unsigned char *str, + size_t *len, TYPEATTR *attr) +{ + unsigned char fc = get_struct_fc(typeinfo, attr); + size_t off = *len; + + if (fc != FC_STRUCT) + FIXME("fc %02x not implemented\n", fc); + + WRITE_CHAR (str, *len, FC_STRUCT); + WRITE_CHAR (str, *len, attr->cbAlignment - 1); + WRITE_SHORT(str, *len, attr->cbSizeInstance); + WRITE_CHAR (str, *len, FC_PAD); + WRITE_CHAR (str, *len, FC_END); + + return off; +} + static size_t write_array_tfs(ITypeInfo *typeinfo, unsigned char *str, size_t *len, ARRAYDESC *desc) { @@ -264,6 +282,14 @@ static size_t write_pointer_tfs(ITypeInfo *typeinfo, unsigned char *str, WRITE_CHAR(str, *len, FC_ENUM32); WRITE_CHAR(str, *len, FC_PAD); break; + case TKIND_RECORD: + assert(!toplevel); /* toplevel struct pointers should use IsSimpleRef */ + ref = write_struct_tfs(refinfo, str, len, attr); + off = *len; + WRITE_CHAR (str, *len, FC_UP); + WRITE_CHAR (str, *len, 0); + WRITE_SHORT(str, *len, ref - *len); + break; case TKIND_INTERFACE: case TKIND_DISPATCH: write_ip_tfs(str, len, &attr->guid); @@ -309,6 +335,8 @@ static size_t write_pointer_tfs(ITypeInfo *typeinfo, unsigned char *str, static size_t write_type_tfs(ITypeInfo *typeinfo, unsigned char *str, size_t *len, TYPEDESC *desc, BOOL toplevel, BOOL onstack) { + ITypeInfo *refinfo; + TYPEATTR *attr; size_t off; TRACE("vt %d%s\n", desc->vt, toplevel ? " (toplevel)" : ""); @@ -319,6 +347,25 @@ static size_t write_type_tfs(ITypeInfo *typeinfo, unsigned char *str, return write_pointer_tfs(typeinfo, str, len, desc->lptdesc, toplevel, onstack); case VT_CARRAY: return write_array_tfs(typeinfo, str, len, desc->lpadesc); + case VT_USERDEFINED: + ITypeInfo_GetRefTypeInfo(typeinfo, desc->hreftype, &refinfo); + ITypeInfo_GetTypeAttr(refinfo, &attr); + + switch (attr->typekind) + { + case TKIND_RECORD: + off = write_struct_tfs(refinfo, str, len, attr); + break; + default: + FIXME("unhandled kind %u\n", attr->typekind); + off = *len; + WRITE_SHORT(str, *len, 0); + break; + } + + ITypeInfo_ReleaseTypeAttr(refinfo, attr); + ITypeInfo_Release(refinfo); + break; default: /* base types are always embedded directly */ assert(!get_base_type(desc->vt));