diff options
author | Michal Strehovský <MichalStrehovsky@users.noreply.github.com> | 2017-12-21 01:10:14 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-12-21 01:10:14 +0300 |
commit | bf9c43ab14e6b03e55dd34c72a31bae97dd5fbef (patch) | |
tree | d0a4215f1f1fc80522f08c55d6c02d4f15b3bfd6 | |
parent | 64319b6ecd55094a8eb2cbc6b36bdbe6ab9ae612 (diff) | |
parent | ed675760469aae13ae39b2452fcf283e07e2cf63 (diff) |
Merge pull request #5138 from dotnet-bot/from-tfs
Merge changes from TFS
6 files changed, 142 insertions, 0 deletions
diff --git a/src/System.Private.Interop/src/Shared/ClassFactory.cs b/src/System.Private.Interop/src/Shared/ClassFactory.cs new file mode 100644 index 000000000..8de44d99e --- /dev/null +++ b/src/System.Private.Interop/src/Shared/ClassFactory.cs @@ -0,0 +1,70 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +// ---------------------------------------------------------------------------------- +// Interop library code +// --------------------------------------------------------------------------------- + +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.WindowsRuntime; +using System.Runtime.CompilerServices; +using System.Threading; +using System.Text; +using System.Runtime; +using Internal.NativeFormat; +using Internal.Runtime.CompilerServices; + +namespace System.Runtime.InteropServices +{ + [Guid("4ffdd514-7dec-47cf-a0ad-4971868d8455")] + public unsafe class ClassFactory : IClassFactory + { + private McgModule parent; + private RuntimeTypeHandle classType; + + public ClassFactory(McgModule parent, RuntimeTypeHandle classType) + { + this.parent = parent; + this.classType = classType; + } + + public int CreateInstance(IntPtr pUnkOuter, Guid* riid, IntPtr* ppv) + { + if (pUnkOuter != IntPtr.Zero) + { + // We do not currently support COM aggregation + return Interop.COM.CLASS_E_NOAGGREGATION; + } + + RuntimeTypeHandle interfaceTypeHandle = parent.GetTypeFromGuid(ref *riid); + if (interfaceTypeHandle.Equals(default(RuntimeTypeHandle))) + { + return Interop.COM.E_NOINTERFACE; + } + else + { + object result = InteropExtensions.RuntimeNewObject(classType); + *ppv = McgMarshal.ObjectToComInterface(result, interfaceTypeHandle); + if (*ppv == IntPtr.Zero) + { + return Interop.COM.E_NOINTERFACE; + } + else + { + return Interop.COM.S_OK; + } + } + } + + public int LockServer (int fLock) + { + return Interop.COM.E_NOTIMPL; + } + } +}
\ No newline at end of file diff --git a/src/System.Private.Interop/src/Shared/IClassFactory.cs b/src/System.Private.Interop/src/Shared/IClassFactory.cs new file mode 100644 index 000000000..cf02d761a --- /dev/null +++ b/src/System.Private.Interop/src/Shared/IClassFactory.cs @@ -0,0 +1,36 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +// ---------------------------------------------------------------------------------- +// Interop library code +// --------------------------------------------------------------------------------- + +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.WindowsRuntime; +using System.Runtime.CompilerServices; +using System.Threading; +using System.Text; +using System.Runtime; +using Internal.NativeFormat; +using Internal.Runtime.CompilerServices; + +namespace System.Runtime.InteropServices +{ + [ComImport] + [Guid("00000001-0000-0000-C000-000000000046")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public unsafe interface IClassFactory + { + [PreserveSig] + int CreateInstance(IntPtr pUnkOuter, Guid* riid, IntPtr* ppvObject); + + [PreserveSig] + int LockServer (int fLock); + } +}
\ No newline at end of file diff --git a/src/System.Private.Interop/src/Shared/Interop.Manual.cs b/src/System.Private.Interop/src/Shared/Interop.Manual.cs index 5c0e028dc..fe0861c0d 100644 --- a/src/System.Private.Interop/src/Shared/Interop.Manual.cs +++ b/src/System.Private.Interop/src/Shared/Interop.Manual.cs @@ -162,6 +162,9 @@ partial class Interop internal const int TYPE_E_TYPEMISMATCH = unchecked((int)0x80028CA0); internal const int DISP_E_OVERFLOW = unchecked((int)0x8002000A); + internal const int CLASS_E_NOAGGREGATION = unchecked((int)0x80040110); + internal const int CLASS_E_CLASSNOTAVAILABLE = unchecked((int)0x80040111); + /// <summary> /// Error indicates that you are accessing a CCW whose target object has already been garbage /// collected while the CCW still has non-0 jupiter ref counts diff --git a/src/System.Private.Interop/src/Shared/McgData.cs b/src/System.Private.Interop/src/Shared/McgData.cs index 40b9e9deb..de7777904 100644 --- a/src/System.Private.Interop/src/Shared/McgData.cs +++ b/src/System.Private.Interop/src/Shared/McgData.cs @@ -603,6 +603,11 @@ namespace System.Runtime.InteropServices /// hierarchy and also know which are the ones implemented by managed class /// </summary> public bool IsWinRTType; + + /// <summary> + /// The clsid of the COM class, or Guid.Empty if not available + /// </summary> + public Guid Clsid; } } diff --git a/src/System.Private.Interop/src/Shared/McgModule.cs b/src/System.Private.Interop/src/Shared/McgModule.cs index 63e097c2d..69bc6aa7a 100644 --- a/src/System.Private.Interop/src/Shared/McgModule.cs +++ b/src/System.Private.Interop/src/Shared/McgModule.cs @@ -912,6 +912,32 @@ namespace System.Runtime.InteropServices mcgGenericArgumentMarshalInfo = default(McgGenericArgumentMarshalInfo); return false; } + + static Guid s_IID_IClassFactory = new Guid(0x00000001, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); + + public unsafe int DllGetClassObjectImpl(Guid rclsid, Guid riid, IntPtr* ppv) + { + if (riid != s_IID_IClassFactory) + { + // Make sure we generate a CCW for IClassFactory + // IntPtr dummy = Marshal.GetComInterfaceForObject(new ClassFactory(null, typeof(IClassFactory).TypeHandle), typeof(IClassFactory)); + // Marshal.Release(dummy); + return Interop.COM.E_NOINTERFACE; + } + + // TODO: build a index similar as McgModule.m_guidMap + for (int i = 0; i < this.m_ccwTemplateData.Length; i++) + { + if (this.m_ccwTemplateData[i].Clsid == rclsid) + { + ClassFactory classFactory = new ClassFactory(this, this.m_ccwTemplateData[i].ClassType); + *ppv = McgMarshal.ObjectToComInterface(classFactory, typeof(IClassFactory).TypeHandle); + return Interop.COM.S_OK; + } + } + return Interop.COM.CLASS_E_CLASSNOTAVAILABLE; + } + #if ENABLE_WINRT static Guid s_IID_IActivationFactory = new Guid(0x00000035, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); diff --git a/src/System.Private.Interop/src/System.Private.Interop.Shared.projitems b/src/System.Private.Interop/src/System.Private.Interop.Shared.projitems index 8431beb95..394ff286f 100644 --- a/src/System.Private.Interop/src/System.Private.Interop.Shared.projitems +++ b/src/System.Private.Interop/src/System.Private.Interop.Shared.projitems @@ -16,11 +16,13 @@ <Compile Include="Shared\ComCallableObject.cs" /> <Compile Include="Shared\ComInterop.cs" /> + <Compile Include="Shared\ClassFactory.cs" /> <Compile Include="Shared\Dictionary.cs" /> <Compile Include="Shared\DictionaryBase.cs" /> <Compile Include="Shared\FixedHashTable.cs" /> <Compile Include="Shared\GCEventProvider.cs" /> <Compile Include="Shared\HashSet.cs" /> + <Compile Include="Shared\IClassFactory.cs" /> <Compile Include="Shared\InternalModule.cs" /> <Compile Include="Shared\Interop.Manual.cs" /> <Compile Include="Shared\List.cs" /> |