/// <remarks>
        /// Use only with VBA-supplied <see cref="ITypeInfo"/> which may return a <see cref="VARDESC"/> that do not conform to
        /// the MS-OAUT in describing the constants. See section 2.2.43 at: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-oaut/ae7791d2-4399-4dff-b7c6-b0d4f3dce982
        ///
        /// To further complicate the situation, on 64-bit platform, the <see cref="VARDESC.DESCUNION.oInst"/> is a 32-bit integer whereas
        /// the <see cref="VARDESC.DESCUNION.lpvarValue"/> is a pointer. On 32-bit platform, the sizes of 2 members are exactly same so no
        /// problem. But on 64-bit platform, setting the <c>oInst</c>to 0 does not necessarily zero-initialize the entire region. Thus, the
        /// upper 32-bit part of the <c>lpvarValue</c> can contain garbage which will confound the simple null pointer check. Thus to guard
        /// against this, we will check the <c>oInst</c> value to see if it's zero.
        ///
        /// There is a small but non-zero chance that there might be a valid pointer that happens to be only in high half of the address...
        /// in that case, it'll be wrong but since VBA is always writing <see cref="VARKIND.VAR_STATIC"/> to the <see cref="VARDESC.varkind"/>
        /// field. To accommodate this unlikely possibility, we take advantage of VBA's other failure to comply with MS-OAUT specifications:
        /// None of its constants has a valid member ID. Normally they are assigned <c>MEMBER_NIL</c> which makes them useless for enumeration. To
        /// accommodate this, the TypeInfoWrapper in Rubberduck.VBEditor project will generate unique member IDs for those constants. Thus, we can use
        /// the same range to infer that it's a constant assigned by the TypeInfoWrapper.
        /// </remarks>
        /// <param name="varDesc">The <see cref="VARDESC"/> from a VBA <see cref="ITypeInfo"/></param>
        /// <returns>True if this is most likely a constant. False when it's definitely not.</returns>
        public static bool IsValidVBAConstant(this VARDESC varDesc)
        {
            // TODO: Move the function to a better home and avoid duplication of constants (see TypeInfoWrapper)
            const int _ourConstantsDispatchMemberIDRangeStart        = unchecked ((int)0xFEDC0000);
            const int _ourConstantsDispatchMemberIDRangeBitmaskCheck = unchecked ((int)0xFFFF0000);

            return((varDesc.memid & _ourConstantsDispatchMemberIDRangeBitmaskCheck) >= _ourConstantsDispatchMemberIDRangeStart &&
                   varDesc.varkind == VARKIND.VAR_STATIC &&
                   varDesc.desc.oInst != 0);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Helper method for retrieving type attributes for a given type info
        /// This method needs to also return the native pointer to be released when we're done with our VARDESC.
        /// It's not really possible to copy everything to a managed struct and then release the ptr immediately
        /// here, since VARDESCs contain other native pointers we may need to access.
        /// </summary>
        internal static void GetVarDescForVarIndex(ITypeInfo typeInfo, int varIndex, out VARDESC varDesc, out IntPtr varDescHandle)
        {
            typeInfo.GetVarDesc(varIndex, out IntPtr pVarDesc);

            // GetVarDesc should never return null, this is just to be safe
            if (pVarDesc == IntPtr.Zero)
            {
                throw new COMException(
                          ResourceUtilities.GetResourceString("ResolveComReference.CannotRetrieveTypeInformation"));
            }

            varDesc       = (VARDESC)Marshal.PtrToStructure(pVarDesc, typeof(VARDESC));
            varDescHandle = pVarDesc;
        }
Exemplo n.º 3
0
 public FieldInfo(VARDESC vardesc, ITypeInfo info, IVbaTypeRepository repo)
 {
     Name       = ComHelper.GetMemberName(info, vardesc);
     Type       = repo.GetVbaType(vardesc.elemdescVar.tdesc, info);
     IsConstant = ComHelper.IsConstant(vardesc);
     if (IsConstant)
     {
         Value = ComHelper.GetConstantValue(vardesc);
     }
     else
     {
         // TODO handle other cases here.  May need reference to parent type.
         IsField = true;
     }
 }
Exemplo n.º 4
0
        public void GetVarDesc(int index, out IntPtr ppVarDesc)
        {
            // Fail BEFORE allocating the handle to avoid leaks. If the real COM object fails in this method
            // and doesn't return the handle or clean it up itself there's not much we can do to avoid the leak.
            _faultInjector.FailurePointThrow(MockTypeLibrariesFailurePoints.ITypeInfo_GetVarDesc);

            ppVarDesc = _memoryHelper.AllocateHandle(Marshal.SizeOf <VARDESC>());

            _memoryHelper.EnterSubAllocationScope(ppVarDesc);
            VARDESC varDesc = new VARDESC();

            varDesc.elemdescVar.tdesc = _definedVariables[index].CreateTypeDesc(new IntPtr(index + s_HREF_VARS_OFFSET), _memoryHelper);
            _memoryHelper.ExitSubAllocationScope();

            Marshal.StructureToPtr(varDesc, ppVarDesc, false);
        }
Exemplo n.º 5
0
        static void             DealWithTypeInfo(UCOMITypeInfo it)
        {
            // Get the names from ITypeInfo
            string name;
            string docstring;
            Int32  ctxt;
            string helpfile;

            // TypeInfo name
            it.GetDocumentation(-1, out name, out docstring, out ctxt, out helpfile);
            IntPtr pa;

            it.GetTypeAttr(out pa);
            TYPEATTR ta = (TYPEATTR)Marshal.PtrToStructure(pa, typeof(TYPEATTR));

            DealWithName(name, ta.guid);

            // Deal with funcs
            for (int i = 0; i < ta.cFuncs; i++)
            {
                IntPtr pfd;
                it.GetFuncDesc(i, out pfd);
                FUNCDESC fd = (FUNCDESC)Marshal.PtrToStructure(pfd, typeof(FUNCDESC));
                it.GetDocumentation(fd.memid, out name, out docstring, out ctxt, out helpfile);
                DealWithName(name, Guid.Empty);
            }

            // Deal with vars
            for (int i = 0; i < ta.cVars; i++)
            {
                IntPtr pvd;
                it.GetVarDesc(i, out pvd);
                VARDESC vd = (VARDESC)Marshal.PtrToStructure(pvd, typeof(VARDESC));
                it.GetDocumentation(vd.memid, out name, out docstring, out ctxt, out helpfile);
                DealWithName(name, Guid.Empty);
            }
        }
Exemplo n.º 6
0
 public VarDesc(ITypeInfo typeinfo, int index)
 {
     m_typeinfo = typeinfo;
     m_ipVarDesc = TypeLibResourceManager.GetDaemon().GetVarDesc(typeinfo, index);
     m_vardesc = (VARDESC)Marshal.PtrToStructure(m_ipVarDesc, typeof(VARDESC));
 }
Exemplo n.º 7
0
 public unsafe int RemoteGetVarDesc(uint index, VARDESC** ppVarDesc, CLEANLOCALSTORAGE* pDummy)
 {
     ITypeInfo_vtbl** @this = (ITypeInfo_vtbl**)reference;
     ITypeInfo_vtbl* vtbl = *@this;
     if (vtbl == null)
         throw new InvalidComObjectException();
     Delegate genericDelegate = Marshal.GetDelegateForFunctionPointer(vtbl->method_6, typeof(delegate_6));
     delegate_6 method = (delegate_6)genericDelegate;
     return method(@this, index, ppVarDesc, pDummy);
 }
Exemplo n.º 8
0
 public unsafe int RemoteBind(char* szName, uint lHashVal, ushort wFlags, ITypeInfo* ppTInfo, DESCKIND* pDescKind, FUNCDESC** ppFuncDesc, VARDESC** ppVarDesc, ITypeComp* ppTypeComp, CLEANLOCALSTORAGE* pDummy)
 {
     ITypeComp_vtbl** @this = (ITypeComp_vtbl**)reference;
     ITypeComp_vtbl* vtbl = *@this;
     if (vtbl == null)
         throw new InvalidComObjectException();
     Delegate genericDelegate = Marshal.GetDelegateForFunctionPointer(vtbl->method_3, typeof(delegate_3));
     delegate_3 method = (delegate_3)genericDelegate;
     return method(@this, szName, lHashVal, wFlags, ppTInfo, pDescKind, ppFuncDesc, ppVarDesc, ppTypeComp, pDummy);
 }