Пример #1
0
        // Called by the runtime to execute the abstract instance function
        internal static unsafe void *CallComputeVtables(
            ComWrappersScenario scenario,
            ComWrappers?comWrappersImpl,
            object obj,
            CreateComInterfaceFlags flags,
            out int count
            )
        {
            ComWrappers?impl = null;

            switch (scenario)
            {
            case ComWrappersScenario.Instance:
                impl = comWrappersImpl;
                break;

            case ComWrappersScenario.TrackerSupportGlobalInstance:
                impl = s_globalInstanceForTrackerSupport;
                break;

            case ComWrappersScenario.MarshallingGlobalInstance:
                impl = s_globalInstanceForMarshalling;
                break;
            }

            if (impl is null)
            {
                count = -1;
                return(null);
            }

            return(impl.ComputeVtables(obj, flags, out count));
        }
Пример #2
0
        protected override unsafe ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count)
        {
            var entries = ComWrappersSupport.GetInterfaceTableEntries(obj);

            if (flags.HasFlag(CreateComInterfaceFlags.CallerDefinedIUnknown))
            {
                entries.Add(new ComInterfaceEntry
                {
                    IID    = typeof(IUnknownVftbl).GUID,
                    Vtable = IUnknownVftbl.AbiToProjectionVftblPtr
                });
            }

            entries.Add(new ComInterfaceEntry
            {
                IID    = typeof(IInspectable).GUID,
                Vtable = IInspectable.Vftbl.AbiToProjectionVftablePtr
            });

            count = entries.Count;
            ComInterfaceEntry *nativeEntries = (ComInterfaceEntry *)Marshal.AllocCoTaskMem(sizeof(ComInterfaceEntry) * count);

            for (int i = 0; i < count; i++)
            {
                nativeEntries[i] = entries[i];
            }

            ComInterfaceEntryCleanupTable.Add(obj, new VtableEntriesCleanupScout(nativeEntries));

            return(nativeEntries);
        }
Пример #3
0
 private static extern bool TryGetOrCreateComInterfaceForObjectInternal(
     ObjectHandleOnStack comWrappersImpl,
     long wrapperId,
     ObjectHandleOnStack instance,
     CreateComInterfaceFlags flags,
     out IntPtr retValue
     );
Пример #4
0
            protected unsafe override ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count)
            {
                Assert.IsTrue(obj is Test);

                IntPtr fpQueryInteface = default;
                IntPtr fpAddRef        = default;
                IntPtr fpRelease       = default;

                ComWrappers.GetIUnknownImpl(out fpQueryInteface, out fpAddRef, out fpRelease);

                var vtbl = new ITestVtbl()
                {
                    IUnknownImpl = new IUnknownVtbl()
                    {
                        QueryInterface = fpQueryInteface,
                        AddRef         = fpAddRef,
                        Release        = fpRelease
                    },
                    SetValue = Marshal.GetFunctionPointerForDelegate(ITestVtbl.pSetValue)
                };
                var vtblRaw = RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(ITestVtbl), sizeof(ITestVtbl));

                Marshal.StructureToPtr(vtbl, vtblRaw, false);

                var entryRaw = (ComInterfaceEntry *)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(ITestVtbl), sizeof(ComInterfaceEntry));

                entryRaw->IID    = typeof(ITest).GUID;
                entryRaw->Vtable = vtblRaw;

                count = 1;
                return(entryRaw);
            }
Пример #5
0
 protected override unsafe ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count)
 {
     // count = 0;
     // return null;
     count = 1;
     return(wrapperEntry);
 }
Пример #6
0
    protected override unsafe ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count)
    {
        Debug.Assert(obj is IDispatch);
        Debug.Assert(wrapperEntry != null);

        // Always return the same table mappings.
        count = 1;
        return(wrapperEntry);
    }
Пример #7
0
        protected override unsafe ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count)
        {
            Debug.Assert(obj is Interop.Ole32.IStream);
            Debug.Assert(s_wrapperEntry is not null);

            // Always return the same table mappings.
            count = 1;
            return(s_wrapperEntry);
        }
Пример #8
0
    protected override unsafe ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count)
    {
        Debug.Assert(obj is IDispatch);
        Debug.Assert(wrapperEntry != null);

        // Always return the same table mappings.
        // If the object supports more than the IDispatch interface that should be returned here.
        count = 1;
        return(wrapperEntry);
    }
Пример #9
0
        /// <summary>
        /// Create a COM representation of the supplied object that can be passed to a non-managed environment.
        /// </summary>
        /// <param name="instance">The managed object to expose outside the .NET runtime.</param>
        /// <param name="flags">Flags used to configure the generated interface.</param>
        /// <returns>The generated COM interface that can be passed outside the .NET runtime.</returns>
        public IntPtr GetOrCreateComInterfaceForObject(object instance, CreateComInterfaceFlags flags)
        {
            if (instance == null)
            {
                throw new ArgumentNullException(nameof(instance));
            }

            ComWrappers impl = this;

            return(GetOrCreateComInterfaceForObjectInternal(ObjectHandleOnStack.Create(ref impl), ObjectHandleOnStack.Create(ref instance), flags));
        }
Пример #10
0
        /// <summary>
        /// Create a COM representation of the supplied object that can be passed to a non-managed environment.
        /// </summary>
        /// <param name="instance">The managed object to expose outside the .NET runtime.</param>
        /// <param name="flags">Flags used to configure the generated interface.</param>
        /// <returns>The generated COM interface that can be passed outside the .NET runtime.</returns>
        public IntPtr GetOrCreateComInterfaceForObject(object instance, CreateComInterfaceFlags flags)
        {
            IntPtr ptr;

            if (!TryGetOrCreateComInterfaceForObjectInternal(this, instance, flags, out ptr))
            {
                throw new ArgumentException();
            }

            return(ptr);
        }
Пример #11
0
        protected override unsafe ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count)
        {
            if (obj is Interop.Ole32.IStream)
            {
                count = 1;
                return(s_streamEntry);
            }

            if (obj is Interop.Shell32.IFileDialogEvents)
            {
                count = 1;
                return(s_fileDialogEventsEntry);
            }

            if (obj is Ole32.IDropSource)
            {
                count = 1;
                return(s_dropSourceEntry);
            }

            if (obj is Interop.Ole32.IDropTarget)
            {
                count = 1;
                return(s_dropTargetEntry);
            }

            if (obj is IEnumString)
            {
                count = 1;
                return(s_enumStringEntry);
            }

            if (obj is IEnumFORMATETC)
            {
                count = 1;
                return(s_enumFormatEtcEntry);
            }

            if (obj is IDataObject)
            {
                count = 1;
                return(s_dataObjectEntry);
            }

            throw new NotImplementedException($"ComWrappers for type {obj.GetType()} not implemented.");
        }
Пример #12
0
            protected unsafe override ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count)
            {
                LastComputeVtablesObject = obj;

                if (ReturnInvalid)
                {
                    count = -1;
                    return(null);
                }

                if (obj is Test)
                {
                    return(ComputeVtablesForTestObject((Test)obj, out count));
                }
                else if (string.Equals(ManagedServerTypeName, obj.GetType().Name))
                {
                    IntPtr fpQueryInteface = default;
                    IntPtr fpAddRef        = default;
                    IntPtr fpRelease       = default;
                    ComWrappers.GetIUnknownImpl(out fpQueryInteface, out fpAddRef, out fpRelease);

                    var vtbl = new IUnknownVtbl()
                    {
                        QueryInterface = fpQueryInteface,
                        AddRef         = fpAddRef,
                        Release        = fpRelease
                    };
                    var vtblRaw = RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(IUnknownVtbl), sizeof(IUnknownVtbl));
                    Marshal.StructureToPtr(vtbl, vtblRaw, false);

                    // Including interfaces to allow QI, but not actually returning a valid vtable, since it is not needed for the tests here.
                    var entryRaw = (ComInterfaceEntry *)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(IUnknownVtbl), sizeof(ComInterfaceEntry));
                    entryRaw[0].IID    = typeof(Server.Contract.IConsumeNETServer).GUID;
                    entryRaw[0].Vtable = vtblRaw;

                    count = 1;
                    return(entryRaw);
                }

                count = -1;
                return(null);
            }
Пример #13
0
        /// <summary>
        /// Create a COM representation of the supplied object that can be passed to a non-managed environment.
        /// </summary>
        /// <param name="impl">The <see cref="ComWrappers" /> implementation to use when creating the COM representation.</param>
        /// <param name="instance">The managed object to expose outside the .NET runtime.</param>
        /// <param name="flags">Flags used to configure the generated interface.</param>
        /// <param name="retValue">The generated COM interface that can be passed outside the .NET runtime or IntPtr.Zero if it could not be created.</param>
        /// <returns>Returns <c>true</c> if a COM representation could be created, <c>false</c> otherwise</returns>
        /// <remarks>
        /// If <paramref name="impl" /> is <c>null</c>, the global instance (if registered) will be used.
        /// </remarks>
        private static bool TryGetOrCreateComInterfaceForObjectInternal(
            ComWrappers impl,
            object instance,
            CreateComInterfaceFlags flags,
            out IntPtr retValue
            )
        {
            if (instance == null)
            {
                throw new ArgumentNullException(nameof(instance));
            }

            return(TryGetOrCreateComInterfaceForObjectInternal(
                       ObjectHandleOnStack.Create(ref impl),
                       impl.id,
                       ObjectHandleOnStack.Create(ref instance),
                       flags,
                       out retValue
                       ));
        }
Пример #14
0
            protected unsafe override ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count)
            {
                switch (ComputeVtablesMode)
                {
                case FailureMode.ReturnInvalid:
                {
                    count = -1;
                    return(null);
                }

                case FailureMode.ThrowException:
                    throw new Exception()
                          {
                              HResult = ExceptionErrorCode
                          };

                default:
                    Assert.Fail("Invalid failure mode");
                    throw new Exception("UNREACHABLE");
                }
            }
Пример #15
0
        protected unsafe override ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count)
        {
            Assert.Equal(CreateComInterfaceFlags.None, flags);

            IntPtr fpQueryInterface = default;
            IntPtr fpAddRef         = default;
            IntPtr fpRelease        = default;

            ComWrappers.GetIUnknownImpl(out fpQueryInterface, out fpAddRef, out fpRelease);

            var vtblRaw = (IntPtr *)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(ComWrappersImpl), IntPtr.Size * 3);

            vtblRaw[0] = fpQueryInterface;
            vtblRaw[1] = fpAddRef;
            vtblRaw[2] = fpRelease;

            var entryRaw = (ComInterfaceEntry *)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(ComWrappersImpl), sizeof(ComInterfaceEntry));

            entryRaw->IID    = new Guid(IID_TestQueryInterface);
            entryRaw->Vtable = (IntPtr)vtblRaw;

            count = 1;
            return(entryRaw);
        }
 protected abstract unsafe ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count);
 public IntPtr GetOrCreateComInterfaceForObject(object instance, CreateComInterfaceFlags flags)
 {
     throw new PlatformNotSupportedException();
 }
Пример #18
0
 protected override unsafe ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count)
 {
     // passing the managed object to COM is not currently supported
     throw new NotImplementedException();
 }
Пример #19
0
        // Call to execute the abstract instance function
        internal static unsafe void *CallComputeVtables(ComWrappers?comWrappersImpl, object obj, CreateComInterfaceFlags flags, out int count)
        {
            ComWrappers?impl = comWrappersImpl ?? s_globalInstance;

            if (impl is null)
            {
                count = -1;
                return(null);
            }

            return(impl.ComputeVtables(obj, flags, out count));
        }
Пример #20
0
 protected override unsafe ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count)
 {
     throw new NotImplementedException();
 }
Пример #21
0
 protected override unsafe ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count)
 {
     // Always return the same table mappings.
     count = 1;
     return(wrapperEntry);
 }
Пример #22
0
 protected unsafe override ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count)
 {
     count = 0;
     return(null);
 }
Пример #23
0
 // Call to execute the abstract instance function
 internal static unsafe void *CallComputeVtables(ComWrappers?comWrappersImpl, object obj, CreateComInterfaceFlags flags, out int count)
 => (comWrappersImpl ?? s_globalInstance !).ComputeVtables(obj, flags, out count);
Пример #24
0
 private static extern IntPtr GetOrCreateComInterfaceForObjectInternal(ObjectHandleOnStack comWrappersImpl, ObjectHandleOnStack instance, CreateComInterfaceFlags flags);