Beispiel #1
0
        public override int GetDocumentation(int memid, IntPtr strName, IntPtr strDocString, IntPtr dwHelpContext, IntPtr strHelpFile)
        {
            if (memid == (int)KnownDispatchMemberIDs.MEMBERID_NIL)
            {
                if (strName != IntPtr.Zero)
                {
                    RdMarshal.WriteIntPtr(strName, Marshal.StringToBSTR("_ArtificialContainer"));
                }
                if (strDocString != IntPtr.Zero)
                {
                    RdMarshal.WriteIntPtr(strDocString, IntPtr.Zero);
                }
                if (dwHelpContext != IntPtr.Zero)
                {
                    RdMarshal.WriteInt32(dwHelpContext, 0);
                }
                if (strHelpFile != IntPtr.Zero)
                {
                    RdMarshal.WriteIntPtr(strHelpFile, IntPtr.Zero);
                }

                return((int)KnownComHResults.S_OK);
            }
            return((int)KnownComHResults.TYPE_E_ELEMENTNOTFOUND);
        }
Beispiel #2
0
 public override void ReleaseTLibAttr(IntPtr pTLibAttr)
 {
     if (pTLibAttr != IntPtr.Zero)
     {
         RdMarshal.FreeHGlobal(pTLibAttr);
     }
 }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        /// <summary>
        /// Gets the control <see cref="ComTypes.ITypeInfo"/> by looking for the
        /// corresponding getter on the form interface and returning its retval type
        /// </summary>
        /// <param name="controlName">the name of the control</param>
        /// <returns>
        /// <see cref="ITypeInfoWrapper"/> representing the type of control,
        /// typically the coclass, but this is host dependent
        /// </returns>
        public static ITypeInfoWrapper GetControlTypeFromInterface(ITypeInfoWrapper rootInterface, string controlName)
        {
            // TODO should encapsulate handling of raw datatypes
            foreach (var func in rootInterface.Funcs)
            {
                using (func)
                {
                    // Controls are exposed as getters on the interface.
                    //     can either be    ControlType* get_ControlName()
                    //     or               HRESULT get_ControlName(ControlType** Out)

                    if ((func.Name == controlName) &&
                        (func.ProcKind == PROCKIND.PROCKIND_GET) &&
                        (func.ParamCount == 0) &&
                        (func.FuncDesc.elemdescFunc.tdesc.vt == (short)VarEnum.VT_PTR))
                    {
                        var retValElement = StructHelper.ReadStructureUnsafe <ComTypes.ELEMDESC>(func.FuncDesc.elemdescFunc.tdesc.lpValue);
                        if (retValElement.tdesc.vt == (short)VarEnum.VT_USERDEFINED)
                        {
                            var hr = rootInterface.GetSafeRefTypeInfo((int)retValElement.tdesc.lpValue, out var retVal);
                            if (ComHelper.HRESULT_FAILED(hr))
                            {
                                throw RdMarshal.GetExceptionForHR(hr);
                            }
                            return(retVal);
                        }
                    }
                    else if ((func.Name == controlName) &&
                             (func.ProcKind == PROCKIND.PROCKIND_GET) &&
                             (func.ParamCount == 1) &&
                             (func.FuncDesc.elemdescFunc.tdesc.vt == (short)VarEnum.VT_HRESULT))
                    {
                        // Get details of the first argument
                        var retValElementOuterPtr = StructHelper.ReadStructureUnsafe <ComTypes.ELEMDESC>(func.FuncDesc.lprgelemdescParam);
                        if (retValElementOuterPtr.tdesc.vt == (short)VarEnum.VT_PTR)
                        {
                            var retValElementInnerPtr = StructHelper.ReadStructureUnsafe <ComTypes.ELEMDESC>(retValElementOuterPtr.tdesc.lpValue);
                            if (retValElementInnerPtr.tdesc.vt == (short)VarEnum.VT_PTR)
                            {
                                var retValElement = StructHelper.ReadStructureUnsafe <ComTypes.ELEMDESC>(retValElementInnerPtr.tdesc.lpValue);

                                if (retValElement.tdesc.vt == (short)VarEnum.VT_USERDEFINED)
                                {
                                    var hr = rootInterface.GetSafeRefTypeInfo((int)retValElement.tdesc.lpValue, out var retVal);
                                    if (ComHelper.HRESULT_FAILED(hr))
                                    {
                                        throw RdMarshal.GetExceptionForHR(hr);
                                    }
                                    return(retVal);
                                }
                            }
                        }
                    }
                }
            }

            throw new ArgumentException($"TypeInfoWrapper::GetControlType failed. '{controlName}' control not found.");
        }
Beispiel #6
0
        public override int GetRefTypeInfo(int hRef, IntPtr ppTI)
        {
            var hr = GetSafeRefTypeInfo(hRef, out var ti);

            if (ComHelper.HRESULT_FAILED(hr))
            {
                return(HandleBadHRESULT(hr));
            }

            RdMarshal.WriteIntPtr(ppTI, ti.GetCOMReferencePtr());
            return(hr);
        }
Beispiel #7
0
        public override int GetTypeInfo(int index, IntPtr ppTI)
        {
            if (index >= _containedTypeInfos.Count)
            {
                return((int)KnownComHResults.TYPE_E_ELEMENTNOTFOUND);
            }

            var ti = _containedTypeInfos[index];

            RdMarshal.WriteIntPtr(ppTI, ti.GetCOMReferencePtr());
            return((int)KnownComHResults.S_OK);
        }
Beispiel #8
0
        public override int GetDocumentation(int memid, IntPtr strName, IntPtr strDocString, IntPtr dwHelpContext, IntPtr strHelpFile)
        {
            if (IsDispatchMemberIDInOurConstantsRange(memid))
            {
                // this is very likely one of our simulated names from GetVarDesc()
                var fieldId = memid & _ourConstantsDispatchMemberIDIndexBitmask;
                if (strName != IntPtr.Zero)
                {
                    RdMarshal.WriteIntPtr(strName, Marshal.StringToBSTR("_constantFieldId" + fieldId));
                }
                if (strDocString != IntPtr.Zero)
                {
                    RdMarshal.WriteIntPtr(strDocString, IntPtr.Zero);
                }
                if (dwHelpContext != IntPtr.Zero)
                {
                    RdMarshal.WriteInt32(dwHelpContext, 0);
                }
                if (strHelpFile != IntPtr.Zero)
                {
                    RdMarshal.WriteIntPtr(strHelpFile, IntPtr.Zero);
                }
                return((int)KnownComHResults.S_OK);
            }

            if (memid == (int)KnownDispatchMemberIDs.MEMBERID_NIL)
            {
                // return the cached information here, to workaround the VBE bug for unnamed UserForm base classes causing an access violation
                if (strName != IntPtr.Zero)
                {
                    RdMarshal.WriteIntPtr(strName, RdMarshal.StringToBSTR(Name));
                }
                if (strDocString != IntPtr.Zero)
                {
                    RdMarshal.WriteIntPtr(strDocString, RdMarshal.StringToBSTR(DocString));
                }
                if (dwHelpContext != IntPtr.Zero)
                {
                    RdMarshal.WriteInt32(dwHelpContext, HelpContext);
                }
                if (strHelpFile != IntPtr.Zero)
                {
                    RdMarshal.WriteIntPtr(strHelpFile, RdMarshal.StringToBSTR(HelpFile));
                }
                return((int)KnownComHResults.S_OK);
            }
            else
            {
                var hr = _target_ITypeInfo.GetDocumentation(memid, strName, strDocString, dwHelpContext, strHelpFile);
                return(ComHelper.HRESULT_FAILED(hr) ? HandleBadHRESULT(hr) : hr);
            }
        }
        public override int GetTypeInfo(int index, IntPtr ppTI)
        {
            // We have to wrap the ITypeInfo returned by GetTypeInfo
            var hr = GetSafeTypeInfoByIndex(index, out var ti);

            if (ComHelper.HRESULT_FAILED(hr))
            {
                return(HandleBadHRESULT(hr));
            }

            RdMarshal.WriteIntPtr(ppTI, ti.GetCOMReferencePtr());
            return(hr);
        }
Beispiel #10
0
        public override int GetTypeInfoOfGuid(ref Guid guid, IntPtr ppTInfo)
        {
            var inGuid = guid;
            var ti     = _containedTypeInfos.Find(x => x.GUID == inGuid);

            if (ti == null)
            {
                return((int)KnownComHResults.TYPE_E_ELEMENTNOTFOUND);
            }

            RdMarshal.WriteIntPtr(ppTInfo, ti.GetCOMReferencePtr());
            return((int)KnownComHResults.S_OK);
        }
Beispiel #11
0
        public override int GetTypeInfoType(int index, IntPtr pTKind)
        {
            if (index >= _containedTypeInfos.Count)
            {
                return((int)KnownComHResults.TYPE_E_ELEMENTNOTFOUND);
            }

            var ti = _containedTypeInfos[index];

            var typeKind = TypeInfoWrapper.PatchTypeKind(ti.TypeKind);

            RdMarshal.WriteInt32(pTKind, (int)typeKind);

            return((int)KnownComHResults.S_OK);
        }
        public override int GetTypeInfoType(int index, IntPtr pTKind)
        {
            var hr = _target_ITypeLib.GetTypeInfoType(index, pTKind);

            if (ComHelper.HRESULT_FAILED(hr))
            {
                return(HandleBadHRESULT(hr));
            }

            var tKind = RdMarshal.ReadInt32(pTKind);

            tKind = (int)TypeInfoWrapper.PatchTypeKind((TYPEKIND_VBE)tKind);
            RdMarshal.WriteInt32(pTKind, tKind);

            return(hr);
        }
Beispiel #13
0
        public override int GetContainingTypeLib(IntPtr ppTLB, IntPtr pIndex)
        {
            // even though pIndex is described as a non-optional OUT argument, mscorlib sometimes calls this with a nullptr from the C++ side.
            if (pIndex == IntPtr.Zero)
            {
                RdMarshal.WriteIntPtr(ppTLB, IntPtr.Zero);
                return((int)KnownComHResults.E_INVALIDARG);
            }

            RdMarshal.WriteIntPtr(ppTLB, RdMarshal.GetComInterfaceForObject(_container, typeof(ITypeLibInternal)));
            if (pIndex != IntPtr.Zero)
            {
                RdMarshal.WriteInt32(pIndex, ContainerIndex);
            }

            return((int)KnownComHResults.S_OK);
        }
Beispiel #14
0
        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);
        }
Beispiel #15
0
        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);
        }
        public override int GetTypeInfoOfGuid(ref Guid guid, IntPtr ppTInfo)
        {
            var hr = _target_ITypeLib.GetTypeInfoOfGuid(guid, ppTInfo);

            if (ComHelper.HRESULT_FAILED(hr))
            {
                return(HandleBadHRESULT(hr));
            }

            var pTInfo = RdMarshal.ReadIntPtr(ppTInfo);

            using (var outVal = TypeApiFactory.GetTypeInfoWrapper(pTInfo)) // takes ownership of the COM reference [pTInfo]
            {
                RdMarshal.WriteIntPtr(ppTInfo, outVal.GetCOMReferencePtr());

                _cachedTypeInfos = _cachedTypeInfos ?? new DisposableList <ITypeInfoWrapper>();
                _cachedTypeInfos.Add(outVal);
            }

            return(hr);
        }
        /// <summary>
        /// Executes a procedure inside a standard module in a VBA project
        /// </summary>
        /// <param name="name">the name of the procedure to invoke</param>
        /// <param name="args">arguments to pass to the procedure</param>
        /// <remarks>the returned object can be a COM object, and the callee is responsible for releasing it appropriately</remarks>
        /// <returns>an object representing the return value from the procedure, or null if none.</returns>
        public object StdModExecute(string name, object[] args = null)
        {
            // We search for the dispId using the real type info rather than using staticModule.GetIdsOfNames,
            // as we can then also include PRIVATE scoped procedures.
            var func = _parent.Funcs.Find(name, PROCKIND.PROCKIND_PROC);

            if (func == null)
            {
                throw new ArgumentException($"StdModExecute failed.  Couldn't find procedure named '{name}'");
            }

            var staticModule = GetStdModAccessor();

            try
            {
                return(IDispatchHelper.Invoke(staticModule, func.FuncDesc.memid, IDispatchHelper.InvokeKind.DISPATCH_METHOD, args));
            }
            finally
            {
                RdMarshal.ReleaseComObject(staticModule);
            }
        }
Beispiel #18
0
        public override int GetNames(int memid, IntPtr rgBstrNames, int cMaxNames, IntPtr pcNames)
        {
            if (IsDispatchMemberIDInOurConstantsRange(memid))
            {
                // this is most likely one of our simulated names from GetVarDesc()
                var fieldId = memid & _ourConstantsDispatchMemberIDIndexBitmask;
                if ((rgBstrNames != IntPtr.Zero) && (cMaxNames >= 1))
                {
                    // output 1 string to the array
                    RdMarshal.WriteIntPtr(rgBstrNames, RdMarshal.StringToBSTR("_constantFieldId" + fieldId));
                    if (pcNames != IntPtr.Zero)
                    {
                        RdMarshal.WriteInt32(pcNames, 1);
                    }
                    return((int)KnownComHResults.S_OK);
                }
            }

            var hr = _target_ITypeInfo.GetNames(memid, rgBstrNames, cMaxNames, pcNames);

            return(ComHelper.HRESULT_FAILED(hr) ? HandleBadHRESULT(hr) : hr);
        }
 public IntPtr GetCOMReferencePtr()
 => RdMarshal.GetComInterfaceForObject(this, typeof(ITypeLibInternal));