public override int GetTypeAttr(IntPtr ppTypeAttr) { var hr = _target_ITypeInfo.GetTypeAttr(ppTypeAttr); if (ComHelper.HRESULT_FAILED(hr)) { return(HandleBadHRESULT(hr)); } var pTypeAttr = StructHelper.ReadStructureUnsafe <IntPtr>(ppTypeAttr); var typeAttr = StructHelper.ReadStructureUnsafe <ComTypes.TYPEATTR>(pTypeAttr); typeAttr.typekind = PatchTypeKind((TYPEKIND_VBE)typeAttr.typekind); // A proper type library would not have any variables defined in the modules. // However, a VBA module can have those and that can trip up CLR's parser. To // work around this, we lie to any ComTypes.ITypeInfo consumer that there's no // variables. If we need for VBA-specific work, we need to consult // ITypeInfoWrapper.Vars instead. if (typeAttr.typekind == ComTypes.TYPEKIND.TKIND_MODULE && typeAttr.cVars > 0) { typeAttr.cVars = (short)Consts.Count; } RdMarshal.StructureToPtr <ComTypes.TYPEATTR>(typeAttr, pTypeAttr, true); return(hr); }
public override int GetLibAttr(IntPtr ppTLibAttr) { var output = RdMarshal.AllocHGlobal(Marshal.SizeOf(typeof(ComTypes.TYPELIBATTR))); RdMarshal.StructureToPtr(_libAttribs, output, false); RdMarshal.WriteIntPtr(ppTLibAttr, output); return((int)KnownComHResults.S_OK); }
public override int GetVarDesc(int index, IntPtr ppVarDesc) { var safeIndex = _consts != null && _consts.Count > 0 ? _consts.MappedIndex(index) : index; var hr = _target_ITypeInfo.GetVarDesc(safeIndex, ppVarDesc); if (ComHelper.HRESULT_FAILED(hr)) { return(HandleBadHRESULT(hr)); } var pVarDesc = StructHelper.ReadStructureUnsafe <IntPtr>(ppVarDesc); var varDesc = StructHelper.ReadStructureUnsafe <ComTypes.VARDESC>(pVarDesc); if (varDesc.memid == (int)KnownDispatchMemberIDs.MEMBERID_NIL) { // constants are not reported correctly in VBA type infos. They all have MEMBERID_NIL set. // we will provide fake DispIds and names to satisfy parsers. Shit but works for now. varDesc.memid = (int)(_ourConstantsDispatchMemberIDRangeStart + safeIndex); RdMarshal.StructureToPtr(varDesc, pVarDesc, true); } else { // Unlike GetFuncDesc, we can't get the wVarFlags for fields from the alternative VBA ITypeInfo // because GetVarDesc() hard crashes on the alternative typeinfo /* * if (target_ITypeInfoAlternate != null) * { * using (var varDescPtr2 = AddressableVariables.CreatePtrTo<ComTypes.VARDESC>()) * { * var hr2 = target_ITypeInfoAlternate.GetVarDesc(index, varDescPtr2.Address); * var varDesc2 = varDescPtr2.Value.Value; // dereference the ptr, then the content * VarDesc.wVarFlags = varDesc2.wVarFlags; * RdMarshal.StructureToPtr(VarDesc, pVarDesc, false); * } * } */ } return(hr); }
public override int GetFuncDesc(int index, IntPtr ppFuncDesc) { var hr = _target_ITypeInfo.GetFuncDesc(index, ppFuncDesc); if (ComHelper.HRESULT_FAILED(hr)) { return(HandleBadHRESULT(hr)); } if (_target_ITypeInfoAlternate != null) { var pFuncDesc = StructHelper.ReadStructureUnsafe <IntPtr>(ppFuncDesc); var funcDesc = StructHelper.ReadStructureUnsafe <ComTypes.FUNCDESC>(pFuncDesc); // Populate wFuncFlags from the alternative typeinfo provided by VBA // The alternative typeinfo is not as useful as the main typeinfo for most things, but does expose wFuncFlags // The list of functions appears to be in the same order as the main typeinfo. using (var funcDescAlternatePtr = AddressableVariables.CreatePtrTo <ComTypes.FUNCDESC>()) { var hr2 = _target_ITypeInfoAlternate.GetFuncDesc(index, funcDescAlternatePtr.Address); if (!ComHelper.HRESULT_FAILED(hr2)) { var funcDescAlternate = funcDescAlternatePtr.Value.Value; // dereference the ptr, then the content //sanity check if (funcDescAlternate.memid == funcDesc.memid) { funcDesc.wFuncFlags = funcDescAlternate.wFuncFlags; } else { Debug.Assert(false, $"The sanity check failed; {nameof(funcDesc.memid)}: {funcDesc.memid} and {nameof(funcDescAlternate.memid)}: {funcDescAlternate.memid}"); } _target_ITypeInfoAlternate.ReleaseFuncDesc(funcDescAlternatePtr.Value.Address); RdMarshal.StructureToPtr(funcDesc, pFuncDesc, true); } } } return(hr); }