summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/Runtime/InteropServices
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/src/System/Runtime/InteropServices')
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ArrayWithOffset.cs76
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/Attributes.cs1138
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/BStrWrapper.cs52
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/COMException.cs90
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/CallingConvention.cs22
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/CharSet.cs24
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComEventsHelper.cs202
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComEventsInfo.cs92
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComEventsMethod.cs246
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComEventsSink.cs286
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComMemberType.cs19
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IBindCtx.cs45
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IConnectionPoint.cs29
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IConnectionPointContainer.cs26
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumConnectionPoints.cs30
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumConnections.cs39
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumMoniker.cs30
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumString.cs30
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumVARIANT.cs34
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumerable.cs28
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumerator.cs34
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IExpando.cs31
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IMoniker.cs61
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IPersistFile.cs34
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IReflect.cs79
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IRunningObjectTable.cs34
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IStream.cs55
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeComp.cs49
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeInfo.cs335
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeInfo2.cs62
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeLib.cs68
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeLib2.cs42
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/CriticalHandle.cs275
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/CurrencyWrapper.cs44
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/DispatchWrapper.cs51
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ErrorWrapper.cs54
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/Expando/IExpando.cs39
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ExtensibleClassFactory.cs41
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ExternalException.cs80
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/GCHandleCookieTable.cs219
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/GcHandle.cs330
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/HandleRef.cs50
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ICustomAdapter.cs23
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ICustomFactory.cs17
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ICustomMarshaler.cs31
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ICustomQueryInterface.cs39
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/IException.cs84
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/IRegistrationServices.cs56
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ITypeLibConverter.cs146
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/InvalidComObjectException.cs40
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/InvalidOleVariantTypeException.cs39
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/LayoutKind.cs18
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/Marshal.cs2806
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/MarshalDirectiveException.cs40
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/NativeBuffer.cs175
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/NativeCallableAttribute.cs28
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/NativeMethods.cs65
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/NonPortable.cs209
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ObjectCreationDelegate.cs24
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/PInvokeMap.cs48
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/RegistrationServices.cs1087
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/RuntimeEnvironment.cs165
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/SEHException.cs54
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/SafeArrayRankMismatchException.cs41
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/SafeArrayTypeMismatchException.cs42
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/SafeBuffer.cs415
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/SafeHandle.cs317
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/SafeHeapHandle.cs115
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/StringBuffer.cs402
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventItfInfo.cs53
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventProviderWriter.cs773
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventSinkHelperWriter.cs297
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/NameSpaceExtractor.cs21
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/TCEAdapterGenerator.cs141
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/TypeLibConverter.cs595
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/UCOMIBindCtx.cs46
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/UCOMIConnectionPoint.cs30
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/UCOMIConnectionPointContainer.cs27
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/UCOMIEnumConnectionPoints.cs32
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/UCOMIEnumConnections.cs42
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/UCOMIEnumMoniker.cs33
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/UCOMIEnumString.cs32
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/UCOMIEnumVARIANT.cs35
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/UCOMIEnumerable.cs30
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/UCOMIEnumerator.cs32
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/UCOMIExpando.cs33
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/UCOMIMoniker.cs60
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/UCOMIPersistFile.cs36
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/UCOMIReflect.cs79
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/UCOMIRunningObjectTable.cs32
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/UCOMIStream.cs57
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/UCOMITypeComp.cs52
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/UCOMITypeInfo.cs330
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/UCOMITypeLib.cs71
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/UnknownWrapper.cs37
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/Variant.cs659
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/VariantWrapper.cs37
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/Attributes.cs123
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/BindableVectorToCollectionAdapter.cs108
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/BindableVectorToListAdapter.cs241
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIKeyValuePairImpl.cs66
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIPropertyValueImpl.cs555
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIReferenceImpl.cs406
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ConstantSplittableMap.cs288
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CustomPropertyImpl.cs138
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryKeyCollection.cs124
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryToMapAdapter.cs118
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryValueCollection.cs131
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/EnumeratorToIteratorAdapter.cs168
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/EventRegistrationToken.cs53
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/EventRegistrationTokenTable.cs255
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IActivationFactory.cs19
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IClosable.cs57
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ICustomProperty.cs52
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ICustomPropertyProvider.cs553
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IIterable.cs32
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IIterator.cs54
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IMap.cs59
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IMapViewToIReadOnlyDictionaryAdapter.cs324
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IPropertyValue.cs171
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IReadOnlyDictionaryToIMapViewAdapter.cs88
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IReadOnlyListToIVectorViewAdapter.cs141
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IReference.cs29
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IRestrictedErrorInfo.cs26
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IVector.cs113
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IVectorViewToIReadOnlyListAdapter.cs84
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IteratorToEnumeratorAdapter.cs210
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToBindableVectorAdapter.cs188
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToBindableVectorViewAdapter.cs94
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToVectorAdapter.cs255
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ManagedActivationFactory.cs76
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapToCollectionAdapter.cs192
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapToDictionaryAdapter.cs183
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapViewToReadOnlyCollectionAdapter.cs68
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/NativeMethods.cs65
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/PropertyValue.cs64
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/RuntimeClass.cs122
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorToCollectionAdapter.cs127
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorToListAdapter.cs170
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorViewToReadOnlyCollectionAdapter.cs47
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsFoundationEventHandler.cs15
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeBufferHelper.cs41
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMarshal.cs1335
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMetadata.cs216
144 files changed, 22877 insertions, 0 deletions
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ArrayWithOffset.cs b/src/mscorlib/src/System/Runtime/InteropServices/ArrayWithOffset.cs
new file mode 100644
index 0000000000..83eae1c59c
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ArrayWithOffset.cs
@@ -0,0 +1,76 @@
+// 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.
+
+namespace System.Runtime.InteropServices {
+
+ using System;
+ using System.Runtime.CompilerServices;
+ using System.Runtime.Versioning;
+
+ [Serializable]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public struct ArrayWithOffset
+ {
+ //private ArrayWithOffset()
+ //{
+ // throw new Exception();
+ //}
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+ public ArrayWithOffset(Object array, int offset)
+ {
+ m_array = array;
+ m_offset = offset;
+ m_count = 0;
+ m_count = CalculateCount();
+ }
+
+ public Object GetArray()
+ {
+ return m_array;
+ }
+
+ public int GetOffset()
+ {
+ return m_offset;
+ }
+
+ public override int GetHashCode()
+ {
+ return m_count + m_offset;
+ }
+
+ public override bool Equals(Object obj)
+ {
+ if (obj is ArrayWithOffset)
+ return Equals((ArrayWithOffset)obj);
+ else
+ return false;
+ }
+
+ public bool Equals(ArrayWithOffset obj)
+ {
+ return obj.m_array == m_array && obj.m_offset == m_offset && obj.m_count == m_count;
+ }
+
+ public static bool operator ==(ArrayWithOffset a, ArrayWithOffset b)
+ {
+ return a.Equals(b);
+ }
+
+ public static bool operator !=(ArrayWithOffset a, ArrayWithOffset b)
+ {
+ return !(a == b);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private extern int CalculateCount();
+
+ private Object m_array;
+ private int m_offset;
+ private int m_count;
+ }
+
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/Attributes.cs b/src/mscorlib/src/System/Runtime/InteropServices/Attributes.cs
new file mode 100644
index 0000000000..06c963a555
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/Attributes.cs
@@ -0,0 +1,1138 @@
+// 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.
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+namespace System.Runtime.InteropServices{
+
+ using System;
+ using System.Reflection;
+ using System.Diagnostics.Contracts;
+
+ [AttributeUsage(AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class UnmanagedFunctionPointerAttribute : Attribute
+ {
+ CallingConvention m_callingConvention;
+
+ public UnmanagedFunctionPointerAttribute(CallingConvention callingConvention) { m_callingConvention = callingConvention; }
+
+ public CallingConvention CallingConvention { get { return m_callingConvention; } }
+
+ public CharSet CharSet;
+ public bool BestFitMapping;
+ public bool ThrowOnUnmappableChar;
+
+ // This field is ignored and marshaling behaves as if it was true (for historical reasons).
+ public bool SetLastError;
+
+ // P/Invoke via delegate always preserves signature, HRESULT swapping is not supported.
+ //public bool PreserveSig;
+ }
+
+ [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Enum | AttributeTargets.Struct | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(false)]
+ public sealed class TypeIdentifierAttribute : Attribute
+ {
+ public TypeIdentifierAttribute() { }
+ public TypeIdentifierAttribute(string scope, string identifier) { Scope_ = scope; Identifier_ = identifier; }
+
+ public String Scope { get { return Scope_; } }
+ public String Identifier { get { return Identifier_; } }
+
+ internal String Scope_;
+ internal String Identifier_;
+ }
+
+ // To be used on methods that sink reverse P/Invoke calls.
+ // This attribute is a CoreCLR-only security measure, currently ignored by the desktop CLR.
+ [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
+ public sealed class AllowReversePInvokeCallsAttribute : Attribute
+ {
+ public AllowReversePInvokeCallsAttribute()
+ {
+ }
+ }
+
+ [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Event, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class DispIdAttribute : Attribute
+ {
+ internal int _val;
+ public DispIdAttribute(int dispId)
+ {
+ _val = dispId;
+ }
+ public int Value { get { return _val; } }
+ }
+
+ [Serializable]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public enum ComInterfaceType
+ {
+ InterfaceIsDual = 0,
+ InterfaceIsIUnknown = 1,
+ InterfaceIsIDispatch = 2,
+
+ [System.Runtime.InteropServices.ComVisible(false)]
+ InterfaceIsIInspectable = 3,
+ }
+
+ [AttributeUsage(AttributeTargets.Interface, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class InterfaceTypeAttribute : Attribute
+ {
+ internal ComInterfaceType _val;
+ public InterfaceTypeAttribute(ComInterfaceType interfaceType)
+ {
+ _val = interfaceType;
+ }
+ public InterfaceTypeAttribute(short interfaceType)
+ {
+ _val = (ComInterfaceType)interfaceType;
+ }
+ public ComInterfaceType Value { get { return _val; } }
+ }
+
+ [AttributeUsage(AttributeTargets.Class, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class ComDefaultInterfaceAttribute : Attribute
+ {
+ internal Type _val;
+
+ public ComDefaultInterfaceAttribute(Type defaultInterface)
+ {
+ _val = defaultInterface;
+ }
+
+ public Type Value { get { return _val; } }
+ }
+
+ [Serializable]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public enum ClassInterfaceType
+ {
+ None = 0,
+ AutoDispatch = 1,
+ AutoDual = 2
+ }
+
+ [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class ClassInterfaceAttribute : Attribute
+ {
+ internal ClassInterfaceType _val;
+ public ClassInterfaceAttribute(ClassInterfaceType classInterfaceType)
+ {
+ _val = classInterfaceType;
+
+ }
+ public ClassInterfaceAttribute(short classInterfaceType)
+ {
+ _val = (ClassInterfaceType)classInterfaceType;
+ }
+ public ClassInterfaceType Value { get { return _val; } }
+ }
+
+ [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Delegate | AttributeTargets.Enum | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Property, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class ComVisibleAttribute : Attribute
+ {
+ internal bool _val;
+ public ComVisibleAttribute(bool visibility)
+ {
+ _val = visibility;
+ }
+ public bool Value { get { return _val; } }
+ }
+
+ [AttributeUsage(AttributeTargets.Interface, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class TypeLibImportClassAttribute : Attribute
+ {
+ internal String _importClassName;
+ public TypeLibImportClassAttribute(Type importClass)
+ {
+ _importClassName = importClass.ToString();
+ }
+ public String Value { get { return _importClassName; } }
+ }
+
+ [AttributeUsage(AttributeTargets.Method, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class LCIDConversionAttribute : Attribute
+ {
+ internal int _val;
+ public LCIDConversionAttribute(int lcid)
+ {
+ _val = lcid;
+ }
+ public int Value { get {return _val;} }
+ }
+
+ [AttributeUsage(AttributeTargets.Method, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class ComRegisterFunctionAttribute : Attribute
+ {
+ public ComRegisterFunctionAttribute()
+ {
+ }
+ }
+
+ [AttributeUsage(AttributeTargets.Method, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class ComUnregisterFunctionAttribute : Attribute
+ {
+ public ComUnregisterFunctionAttribute()
+ {
+ }
+ }
+
+ [AttributeUsage(AttributeTargets.Class, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class ProgIdAttribute : Attribute
+ {
+ internal String _val;
+ public ProgIdAttribute(String progId)
+ {
+ _val = progId;
+ }
+ public String Value { get {return _val;} }
+ }
+
+ [AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class ImportedFromTypeLibAttribute : Attribute
+ {
+ internal String _val;
+ public ImportedFromTypeLibAttribute(String tlbFile)
+ {
+ _val = tlbFile;
+ }
+ public String Value { get {return _val;} }
+ }
+
+ [Obsolete("The IDispatchImplAttribute is deprecated.", false)]
+ [Serializable]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public enum IDispatchImplType
+ {
+ SystemDefinedImpl = 0,
+ InternalImpl = 1,
+ CompatibleImpl = 2,
+ }
+
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, Inherited = false)]
+ [Obsolete("This attribute is deprecated and will be removed in a future version.", false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class IDispatchImplAttribute : Attribute
+ {
+ internal IDispatchImplType _val;
+ public IDispatchImplAttribute(IDispatchImplType implType)
+ {
+ _val = implType;
+ }
+ public IDispatchImplAttribute(short implType)
+ {
+ _val = (IDispatchImplType)implType;
+ }
+ public IDispatchImplType Value { get {return _val;} }
+ }
+
+ [AttributeUsage(AttributeTargets.Class, Inherited = true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class ComSourceInterfacesAttribute : Attribute
+ {
+ internal String _val;
+ public ComSourceInterfacesAttribute(String sourceInterfaces)
+ {
+ _val = sourceInterfaces;
+ }
+ public ComSourceInterfacesAttribute(Type sourceInterface)
+ {
+ _val = sourceInterface.FullName;
+ }
+ public ComSourceInterfacesAttribute(Type sourceInterface1, Type sourceInterface2)
+ {
+ _val = sourceInterface1.FullName + "\0" + sourceInterface2.FullName;
+ }
+ public ComSourceInterfacesAttribute(Type sourceInterface1, Type sourceInterface2, Type sourceInterface3)
+ {
+ _val = sourceInterface1.FullName + "\0" + sourceInterface2.FullName + "\0" + sourceInterface3.FullName;
+ }
+ public ComSourceInterfacesAttribute(Type sourceInterface1, Type sourceInterface2, Type sourceInterface3, Type sourceInterface4)
+ {
+ _val = sourceInterface1.FullName + "\0" + sourceInterface2.FullName + "\0" + sourceInterface3.FullName + "\0" + sourceInterface4.FullName;
+ }
+ public String Value { get {return _val;} }
+ }
+
+ [AttributeUsage(AttributeTargets.All, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class ComConversionLossAttribute : Attribute
+ {
+ public ComConversionLossAttribute()
+ {
+ }
+ }
+
+[Serializable]
+[Flags()]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public enum TypeLibTypeFlags
+ {
+ FAppObject = 0x0001,
+ FCanCreate = 0x0002,
+ FLicensed = 0x0004,
+ FPreDeclId = 0x0008,
+ FHidden = 0x0010,
+ FControl = 0x0020,
+ FDual = 0x0040,
+ FNonExtensible = 0x0080,
+ FOleAutomation = 0x0100,
+ FRestricted = 0x0200,
+ FAggregatable = 0x0400,
+ FReplaceable = 0x0800,
+ FDispatchable = 0x1000,
+ FReverseBind = 0x2000,
+ }
+
+[Serializable]
+[Flags()]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public enum TypeLibFuncFlags
+ {
+ FRestricted = 0x0001,
+ FSource = 0x0002,
+ FBindable = 0x0004,
+ FRequestEdit = 0x0008,
+ FDisplayBind = 0x0010,
+ FDefaultBind = 0x0020,
+ FHidden = 0x0040,
+ FUsesGetLastError = 0x0080,
+ FDefaultCollelem = 0x0100,
+ FUiDefault = 0x0200,
+ FNonBrowsable = 0x0400,
+ FReplaceable = 0x0800,
+ FImmediateBind = 0x1000,
+ }
+
+[Serializable]
+[Flags()]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public enum TypeLibVarFlags
+ {
+ FReadOnly = 0x0001,
+ FSource = 0x0002,
+ FBindable = 0x0004,
+ FRequestEdit = 0x0008,
+ FDisplayBind = 0x0010,
+ FDefaultBind = 0x0020,
+ FHidden = 0x0040,
+ FRestricted = 0x0080,
+ FDefaultCollelem = 0x0100,
+ FUiDefault = 0x0200,
+ FNonBrowsable = 0x0400,
+ FReplaceable = 0x0800,
+ FImmediateBind = 0x1000,
+ }
+
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Enum | AttributeTargets.Struct, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class TypeLibTypeAttribute : Attribute
+ {
+ internal TypeLibTypeFlags _val;
+ public TypeLibTypeAttribute(TypeLibTypeFlags flags)
+ {
+ _val = flags;
+ }
+ public TypeLibTypeAttribute(short flags)
+ {
+ _val = (TypeLibTypeFlags)flags;
+ }
+ public TypeLibTypeFlags Value { get {return _val;} }
+ }
+
+ [AttributeUsage(AttributeTargets.Method, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class TypeLibFuncAttribute : Attribute
+ {
+ internal TypeLibFuncFlags _val;
+ public TypeLibFuncAttribute(TypeLibFuncFlags flags)
+ {
+ _val = flags;
+ }
+ public TypeLibFuncAttribute(short flags)
+ {
+ _val = (TypeLibFuncFlags)flags;
+ }
+ public TypeLibFuncFlags Value { get {return _val;} }
+ }
+
+ [AttributeUsage(AttributeTargets.Field, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class TypeLibVarAttribute : Attribute
+ {
+ internal TypeLibVarFlags _val;
+ public TypeLibVarAttribute(TypeLibVarFlags flags)
+ {
+ _val = flags;
+ }
+ public TypeLibVarAttribute(short flags)
+ {
+ _val = (TypeLibVarFlags)flags;
+ }
+ public TypeLibVarFlags Value { get {return _val;} }
+ }
+
+ [Serializable]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public enum VarEnum
+ {
+ VT_EMPTY = 0,
+ VT_NULL = 1,
+ VT_I2 = 2,
+ VT_I4 = 3,
+ VT_R4 = 4,
+ VT_R8 = 5,
+ VT_CY = 6,
+ VT_DATE = 7,
+ VT_BSTR = 8,
+ VT_DISPATCH = 9,
+ VT_ERROR = 10,
+ VT_BOOL = 11,
+ VT_VARIANT = 12,
+ VT_UNKNOWN = 13,
+ VT_DECIMAL = 14,
+ VT_I1 = 16,
+ VT_UI1 = 17,
+ VT_UI2 = 18,
+ VT_UI4 = 19,
+ VT_I8 = 20,
+ VT_UI8 = 21,
+ VT_INT = 22,
+ VT_UINT = 23,
+ VT_VOID = 24,
+ VT_HRESULT = 25,
+ VT_PTR = 26,
+ VT_SAFEARRAY = 27,
+ VT_CARRAY = 28,
+ VT_USERDEFINED = 29,
+ VT_LPSTR = 30,
+ VT_LPWSTR = 31,
+ VT_RECORD = 36,
+ VT_FILETIME = 64,
+ VT_BLOB = 65,
+ VT_STREAM = 66,
+ VT_STORAGE = 67,
+ VT_STREAMED_OBJECT = 68,
+ VT_STORED_OBJECT = 69,
+ VT_BLOB_OBJECT = 70,
+ VT_CF = 71,
+ VT_CLSID = 72,
+ VT_VECTOR = 0x1000,
+ VT_ARRAY = 0x2000,
+ VT_BYREF = 0x4000
+ }
+
+ [Serializable]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ // Note that this enum should remain in-sync with the CorNativeType enum in corhdr.h
+ public enum UnmanagedType
+ {
+ Bool = 0x2, // 4 byte boolean value (true != 0, false == 0)
+
+ I1 = 0x3, // 1 byte signed value
+
+ U1 = 0x4, // 1 byte unsigned value
+
+ I2 = 0x5, // 2 byte signed value
+
+ U2 = 0x6, // 2 byte unsigned value
+
+ I4 = 0x7, // 4 byte signed value
+
+ U4 = 0x8, // 4 byte unsigned value
+
+ I8 = 0x9, // 8 byte signed value
+
+ U8 = 0xa, // 8 byte unsigned value
+
+ R4 = 0xb, // 4 byte floating point
+
+ R8 = 0xc, // 8 byte floating point
+
+ Currency = 0xf, // A currency
+
+ BStr = 0x13, // OLE Unicode BSTR
+
+ LPStr = 0x14, // Ptr to SBCS string
+
+ LPWStr = 0x15, // Ptr to Unicode string
+
+ LPTStr = 0x16, // Ptr to OS preferred (SBCS/Unicode) string
+
+ ByValTStr = 0x17, // OS preferred (SBCS/Unicode) inline string (only valid in structs)
+
+ IUnknown = 0x19, // COM IUnknown pointer.
+
+ IDispatch = 0x1a, // COM IDispatch pointer
+
+ Struct = 0x1b, // Structure
+
+ Interface = 0x1c, // COM interface
+
+ SafeArray = 0x1d, // OLE SafeArray
+
+ ByValArray = 0x1e, // Array of fixed size (only valid in structs)
+
+ SysInt = 0x1f, // Hardware natural sized signed integer
+
+ SysUInt = 0x20,
+
+ VBByRefStr = 0x22,
+
+ AnsiBStr = 0x23, // OLE BSTR containing SBCS characters
+
+ TBStr = 0x24, // Ptr to OS preferred (SBCS/Unicode) BSTR
+
+ VariantBool = 0x25, // OLE defined BOOLEAN (2 bytes, true == -1, false == 0)
+
+ FunctionPtr = 0x26, // Function pointer
+
+ AsAny = 0x28, // Paired with Object type and does runtime marshalling determination
+
+ LPArray = 0x2a, // C style array
+
+ LPStruct = 0x2b, // Pointer to a structure
+
+ CustomMarshaler = 0x2c,
+
+ Error = 0x2d,
+
+ [System.Runtime.InteropServices.ComVisible(false)]
+ IInspectable = 0x2e,
+
+ [System.Runtime.InteropServices.ComVisible(false)]
+ HString = 0x2f, // Windows Runtime HSTRING
+
+ [System.Runtime.InteropServices.ComVisible(false)]
+ LPUTF8Str = 0x30, // UTF8 string
+ }
+
+ [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.ReturnValue, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public unsafe sealed class MarshalAsAttribute : Attribute
+ {
+ [System.Security.SecurityCritical] // auto-generated
+ internal static Attribute GetCustomAttribute(RuntimeParameterInfo parameter)
+ {
+ return GetCustomAttribute(parameter.MetadataToken, parameter.GetRuntimeModule());
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ internal static bool IsDefined(RuntimeParameterInfo parameter)
+ {
+ return GetCustomAttribute(parameter) != null;
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ internal static Attribute GetCustomAttribute(RuntimeFieldInfo field)
+ {
+ return GetCustomAttribute(field.MetadataToken, field.GetRuntimeModule()); ;
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ internal static bool IsDefined(RuntimeFieldInfo field)
+ {
+ return GetCustomAttribute(field) != null;
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ internal static Attribute GetCustomAttribute(int token, RuntimeModule scope)
+ {
+ UnmanagedType unmanagedType, arraySubType;
+ VarEnum safeArraySubType;
+ int sizeParamIndex = 0, sizeConst = 0;
+ string marshalTypeName = null, marshalCookie = null, safeArrayUserDefinedTypeName = null;
+ int iidParamIndex = 0;
+ ConstArray nativeType = ModuleHandle.GetMetadataImport(scope.GetNativeHandle()).GetFieldMarshal(token);
+
+ if (nativeType.Length == 0)
+ return null;
+
+ MetadataImport.GetMarshalAs(nativeType,
+ out unmanagedType, out safeArraySubType, out safeArrayUserDefinedTypeName, out arraySubType, out sizeParamIndex,
+ out sizeConst, out marshalTypeName, out marshalCookie, out iidParamIndex);
+
+ RuntimeType safeArrayUserDefinedType = safeArrayUserDefinedTypeName == null || safeArrayUserDefinedTypeName.Length == 0 ? null :
+ RuntimeTypeHandle.GetTypeByNameUsingCARules(safeArrayUserDefinedTypeName, scope);
+ RuntimeType marshalTypeRef = null;
+
+ try
+ {
+ marshalTypeRef = marshalTypeName == null ? null : RuntimeTypeHandle.GetTypeByNameUsingCARules(marshalTypeName, scope);
+ }
+ catch (System.TypeLoadException)
+ {
+ // The user may have supplied a bad type name string causing this TypeLoadException
+ // Regardless, we return the bad type name
+ Contract.Assert(marshalTypeName != null);
+ }
+
+ return new MarshalAsAttribute(
+ unmanagedType, safeArraySubType, safeArrayUserDefinedType, arraySubType,
+ (short)sizeParamIndex, sizeConst, marshalTypeName, marshalTypeRef, marshalCookie, iidParamIndex);
+ }
+
+ internal MarshalAsAttribute(UnmanagedType val, VarEnum safeArraySubType, RuntimeType safeArrayUserDefinedSubType, UnmanagedType arraySubType,
+ short sizeParamIndex, int sizeConst, string marshalType, RuntimeType marshalTypeRef, string marshalCookie, int iidParamIndex)
+ {
+ _val = val;
+ SafeArraySubType = safeArraySubType;
+ SafeArrayUserDefinedSubType = safeArrayUserDefinedSubType;
+ IidParameterIndex = iidParamIndex;
+ ArraySubType = arraySubType;
+ SizeParamIndex = sizeParamIndex;
+ SizeConst = sizeConst;
+ MarshalType = marshalType;
+ MarshalTypeRef = marshalTypeRef;
+ MarshalCookie = marshalCookie;
+ }
+
+ internal UnmanagedType _val;
+ public MarshalAsAttribute(UnmanagedType unmanagedType)
+ {
+ _val = unmanagedType;
+ }
+ public MarshalAsAttribute(short unmanagedType)
+ {
+ _val = (UnmanagedType)unmanagedType;
+ }
+ public UnmanagedType Value { get { return _val; } }
+
+ // Fields used with SubType = SafeArray.
+ public VarEnum SafeArraySubType;
+ public Type SafeArrayUserDefinedSubType;
+
+ // Field used with iid_is attribute (interface pointers).
+ public int IidParameterIndex;
+
+ // Fields used with SubType = ByValArray and LPArray.
+ // Array size = parameter(PI) * PM + C
+ public UnmanagedType ArraySubType;
+ public short SizeParamIndex; // param index PI
+ public int SizeConst; // constant C
+
+ // Fields used with SubType = CustomMarshaler
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public String MarshalType; // Name of marshaler class
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public Type MarshalTypeRef; // Type of marshaler class
+ public String MarshalCookie; // cookie to pass to marshaler
+ }
+
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class ComImportAttribute : Attribute
+ {
+ internal static Attribute GetCustomAttribute(RuntimeType type)
+ {
+ if ((type.Attributes & TypeAttributes.Import) == 0)
+ return null;
+
+ return new ComImportAttribute();
+ }
+
+ internal static bool IsDefined(RuntimeType type)
+ {
+ return (type.Attributes & TypeAttributes.Import) != 0;
+ }
+
+ public ComImportAttribute()
+ {
+ }
+ }
+
+ [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Struct | AttributeTargets.Delegate, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class GuidAttribute : Attribute
+ {
+ internal String _val;
+ public GuidAttribute(String guid)
+ {
+ _val = guid;
+ }
+ public String Value { get { return _val; } }
+ }
+
+ [AttributeUsage(AttributeTargets.Method, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class PreserveSigAttribute : Attribute
+ {
+ internal static Attribute GetCustomAttribute(RuntimeMethodInfo method)
+ {
+ if ((method.GetMethodImplementationFlags() & MethodImplAttributes.PreserveSig) == 0)
+ return null;
+
+ return new PreserveSigAttribute();
+ }
+
+ internal static bool IsDefined(RuntimeMethodInfo method)
+ {
+ return (method.GetMethodImplementationFlags() & MethodImplAttributes.PreserveSig) != 0;
+ }
+
+ public PreserveSigAttribute()
+ {
+ }
+ }
+
+ [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class InAttribute : Attribute
+ {
+ internal static Attribute GetCustomAttribute(RuntimeParameterInfo parameter)
+ {
+ return parameter.IsIn ? new InAttribute() : null;
+ }
+ internal static bool IsDefined(RuntimeParameterInfo parameter)
+ {
+ return parameter.IsIn;
+ }
+
+ public InAttribute()
+ {
+ }
+ }
+
+ [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class OutAttribute : Attribute
+ {
+ internal static Attribute GetCustomAttribute(RuntimeParameterInfo parameter)
+ {
+ return parameter.IsOut ? new OutAttribute() : null;
+ }
+ internal static bool IsDefined(RuntimeParameterInfo parameter)
+ {
+ return parameter.IsOut;
+ }
+
+ public OutAttribute()
+ {
+ }
+ }
+
+ [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class OptionalAttribute : Attribute
+ {
+ internal static Attribute GetCustomAttribute(RuntimeParameterInfo parameter)
+ {
+ return parameter.IsOptional ? new OptionalAttribute() : null;
+ }
+ internal static bool IsDefined(RuntimeParameterInfo parameter)
+ {
+ return parameter.IsOptional;
+ }
+
+ public OptionalAttribute()
+ {
+ }
+ }
+
+ [Flags]
+ public enum DllImportSearchPath
+ {
+ UseDllDirectoryForDependencies = 0x100,
+ ApplicationDirectory = 0x200,
+ UserDirectories = 0x400,
+ System32 = 0x800,
+ SafeDirectories = 0x1000,
+ AssemblyDirectory = 0x2,
+ LegacyBehavior = 0x0
+ }
+
+ [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Method, AllowMultiple = false)]
+ [System.Runtime.InteropServices.ComVisible(false)]
+ public sealed class DefaultDllImportSearchPathsAttribute : Attribute
+ {
+ internal DllImportSearchPath _paths;
+ public DefaultDllImportSearchPathsAttribute(DllImportSearchPath paths)
+ {
+ _paths = paths;
+ }
+
+ public DllImportSearchPath Paths { get { return _paths; } }
+ }
+
+ [AttributeUsage(AttributeTargets.Method, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public unsafe sealed class DllImportAttribute : Attribute
+ {
+ [System.Security.SecurityCritical] // auto-generated
+ internal static Attribute GetCustomAttribute(RuntimeMethodInfo method)
+ {
+ if ((method.Attributes & MethodAttributes.PinvokeImpl) == 0)
+ return null;
+
+ MetadataImport scope = ModuleHandle.GetMetadataImport(method.Module.ModuleHandle.GetRuntimeModule());
+ string entryPoint, dllName = null;
+ int token = method.MetadataToken;
+ PInvokeAttributes flags = 0;
+
+ scope.GetPInvokeMap(token, out flags, out entryPoint, out dllName);
+
+ CharSet charSet = CharSet.None;
+
+ switch (flags & PInvokeAttributes.CharSetMask)
+ {
+ case PInvokeAttributes.CharSetNotSpec: charSet = CharSet.None; break;
+ case PInvokeAttributes.CharSetAnsi: charSet = CharSet.Ansi; break;
+ case PInvokeAttributes.CharSetUnicode: charSet = CharSet.Unicode; break;
+ case PInvokeAttributes.CharSetAuto: charSet = CharSet.Auto; break;
+
+ // Invalid: default to CharSet.None
+ default: break;
+ }
+
+ CallingConvention callingConvention = CallingConvention.Cdecl;
+
+ switch (flags & PInvokeAttributes.CallConvMask)
+ {
+ case PInvokeAttributes.CallConvWinapi: callingConvention = CallingConvention.Winapi; break;
+ case PInvokeAttributes.CallConvCdecl: callingConvention = CallingConvention.Cdecl; break;
+ case PInvokeAttributes.CallConvStdcall: callingConvention = CallingConvention.StdCall; break;
+ case PInvokeAttributes.CallConvThiscall: callingConvention = CallingConvention.ThisCall; break;
+ case PInvokeAttributes.CallConvFastcall: callingConvention = CallingConvention.FastCall; break;
+
+ // Invalid: default to CallingConvention.Cdecl
+ default: break;
+ }
+
+ bool exactSpelling = (flags & PInvokeAttributes.NoMangle) != 0;
+ bool setLastError = (flags & PInvokeAttributes.SupportsLastError) != 0;
+ bool bestFitMapping = (flags & PInvokeAttributes.BestFitMask) == PInvokeAttributes.BestFitEnabled;
+ bool throwOnUnmappableChar = (flags & PInvokeAttributes.ThrowOnUnmappableCharMask) == PInvokeAttributes.ThrowOnUnmappableCharEnabled;
+ bool preserveSig = (method.GetMethodImplementationFlags() & MethodImplAttributes.PreserveSig) != 0;
+
+ return new DllImportAttribute(
+ dllName, entryPoint, charSet, exactSpelling, setLastError, preserveSig,
+ callingConvention, bestFitMapping, throwOnUnmappableChar);
+ }
+
+ internal static bool IsDefined(RuntimeMethodInfo method)
+ {
+ return (method.Attributes & MethodAttributes.PinvokeImpl) != 0;
+ }
+
+
+ internal DllImportAttribute(
+ string dllName, string entryPoint, CharSet charSet, bool exactSpelling, bool setLastError, bool preserveSig,
+ CallingConvention callingConvention, bool bestFitMapping, bool throwOnUnmappableChar)
+ {
+ _val = dllName;
+ EntryPoint = entryPoint;
+ CharSet = charSet;
+ ExactSpelling = exactSpelling;
+ SetLastError = setLastError;
+ PreserveSig = preserveSig;
+ CallingConvention = callingConvention;
+ BestFitMapping = bestFitMapping;
+ ThrowOnUnmappableChar = throwOnUnmappableChar;
+ }
+
+ internal String _val;
+
+ public DllImportAttribute(String dllName)
+ {
+ _val = dllName;
+ }
+ public String Value { get { return _val; } }
+
+ public String EntryPoint;
+ public CharSet CharSet;
+ public bool SetLastError;
+ public bool ExactSpelling;
+ public bool PreserveSig;
+ public CallingConvention CallingConvention;
+ public bool BestFitMapping;
+ public bool ThrowOnUnmappableChar;
+
+ }
+
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public unsafe sealed class StructLayoutAttribute : Attribute
+ {
+ private const int DEFAULT_PACKING_SIZE = 8;
+
+ [System.Security.SecurityCritical] // auto-generated
+ internal static Attribute GetCustomAttribute(RuntimeType type)
+ {
+ if (!IsDefined(type))
+ return null;
+
+ int pack = 0, size = 0;
+ LayoutKind layoutKind = LayoutKind.Auto;
+ switch (type.Attributes & TypeAttributes.LayoutMask)
+ {
+ case TypeAttributes.ExplicitLayout: layoutKind = LayoutKind.Explicit; break;
+ case TypeAttributes.AutoLayout: layoutKind = LayoutKind.Auto; break;
+ case TypeAttributes.SequentialLayout: layoutKind = LayoutKind.Sequential; break;
+ default: Contract.Assume(false); break;
+ }
+
+ CharSet charSet = CharSet.None;
+ switch (type.Attributes & TypeAttributes.StringFormatMask)
+ {
+ case TypeAttributes.AnsiClass: charSet = CharSet.Ansi; break;
+ case TypeAttributes.AutoClass: charSet = CharSet.Auto; break;
+ case TypeAttributes.UnicodeClass: charSet = CharSet.Unicode; break;
+ default: Contract.Assume(false); break;
+ }
+ type.GetRuntimeModule().MetadataImport.GetClassLayout(type.MetadataToken, out pack, out size);
+
+ // Metadata parameter checking should not have allowed 0 for packing size.
+ // The runtime later converts a packing size of 0 to 8 so do the same here
+ // because it's more useful from a user perspective.
+ if (pack == 0)
+ pack = DEFAULT_PACKING_SIZE;
+
+ return new StructLayoutAttribute(layoutKind, pack, size, charSet);
+ }
+
+ internal static bool IsDefined(RuntimeType type)
+ {
+ if (type.IsInterface || type.HasElementType || type.IsGenericParameter)
+ return false;
+
+ return true;
+ }
+
+ internal LayoutKind _val;
+
+ internal StructLayoutAttribute(LayoutKind layoutKind, int pack, int size, CharSet charSet)
+ {
+ _val = layoutKind;
+ Pack = pack;
+ Size = size;
+ CharSet = charSet;
+ }
+
+ public StructLayoutAttribute(LayoutKind layoutKind)
+ {
+ _val = layoutKind;
+ }
+ public StructLayoutAttribute(short layoutKind)
+ {
+ _val = (LayoutKind)layoutKind;
+ }
+ public LayoutKind Value { get { return _val; } }
+ public int Pack;
+ public int Size;
+ public CharSet CharSet;
+ }
+
+ [AttributeUsage(AttributeTargets.Field, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public unsafe sealed class FieldOffsetAttribute : Attribute
+ {
+ [System.Security.SecurityCritical] // auto-generated
+ internal static Attribute GetCustomAttribute(RuntimeFieldInfo field)
+ {
+ int fieldOffset;
+
+ if (field.DeclaringType != null &&
+ field.GetRuntimeModule().MetadataImport.GetFieldOffset(field.DeclaringType.MetadataToken, field.MetadataToken, out fieldOffset))
+ return new FieldOffsetAttribute(fieldOffset);
+
+ return null;
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ internal static bool IsDefined(RuntimeFieldInfo field)
+ {
+ return GetCustomAttribute(field) != null;
+ }
+
+ internal int _val;
+ public FieldOffsetAttribute(int offset)
+ {
+ _val = offset;
+ }
+ public int Value { get { return _val; } }
+ }
+
+ [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class ComAliasNameAttribute : Attribute
+ {
+ internal String _val;
+ public ComAliasNameAttribute(String alias)
+ {
+ _val = alias;
+ }
+ public String Value { get {return _val;} }
+ }
+
+ [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Interface, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class AutomationProxyAttribute : Attribute
+ {
+ internal bool _val;
+ public AutomationProxyAttribute(bool val)
+ {
+ _val = val;
+ }
+ public bool Value { get {return _val;} }
+ }
+
+ [AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple = true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class PrimaryInteropAssemblyAttribute : Attribute
+ {
+ internal int _major;
+ internal int _minor;
+
+ public PrimaryInteropAssemblyAttribute(int major, int minor)
+ {
+ _major = major;
+ _minor = minor;
+ }
+
+ public int MajorVersion { get {return _major;} }
+ public int MinorVersion { get {return _minor;} }
+ }
+
+ [AttributeUsage(AttributeTargets.Interface, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class CoClassAttribute : Attribute
+ {
+ internal Type _CoClass;
+
+ public CoClassAttribute(Type coClass)
+ {
+ _CoClass = coClass;
+ }
+
+ public Type CoClass { get { return _CoClass; } }
+ }
+
+ [AttributeUsage(AttributeTargets.Interface, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class ComEventInterfaceAttribute : Attribute
+ {
+ internal Type _SourceInterface;
+ internal Type _EventProvider;
+
+ public ComEventInterfaceAttribute(Type SourceInterface, Type EventProvider)
+ {
+ _SourceInterface = SourceInterface;
+ _EventProvider = EventProvider;
+ }
+
+ public Type SourceInterface { get {return _SourceInterface;} }
+ public Type EventProvider { get {return _EventProvider;} }
+ }
+
+ [AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class TypeLibVersionAttribute : Attribute
+ {
+ internal int _major;
+ internal int _minor;
+
+ public TypeLibVersionAttribute(int major, int minor)
+ {
+ _major = major;
+ _minor = minor;
+ }
+
+ public int MajorVersion { get {return _major;} }
+ public int MinorVersion { get {return _minor;} }
+ }
+
+ [AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class ComCompatibleVersionAttribute : Attribute
+ {
+ internal int _major;
+ internal int _minor;
+ internal int _build;
+ internal int _revision;
+
+ public ComCompatibleVersionAttribute(int major, int minor, int build, int revision)
+ {
+ _major = major;
+ _minor = minor;
+ _build = build;
+ _revision = revision;
+ }
+
+ public int MajorVersion { get {return _major;} }
+ public int MinorVersion { get {return _minor;} }
+ public int BuildNumber { get {return _build;} }
+ public int RevisionNumber { get {return _revision;} }
+ }
+
+ [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Struct, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class BestFitMappingAttribute : Attribute
+ {
+ internal bool _bestFitMapping;
+
+ public BestFitMappingAttribute(bool BestFitMapping)
+ {
+ _bestFitMapping = BestFitMapping;
+ }
+
+ public bool BestFitMapping { get { return _bestFitMapping; } }
+ public bool ThrowOnUnmappableChar;
+ }
+
+ [AttributeUsage(AttributeTargets.Module, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class DefaultCharSetAttribute : Attribute
+ {
+ internal CharSet _CharSet;
+
+ public DefaultCharSetAttribute(CharSet charSet)
+ {
+ _CharSet = charSet;
+ }
+
+ public CharSet CharSet { get { return _CharSet; } }
+ }
+
+ [Obsolete("This attribute has been deprecated. Application Domains no longer respect Activation Context boundaries in IDispatch calls.", false)]
+ [AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class SetWin32ContextInIDispatchAttribute : Attribute
+ {
+ public SetWin32ContextInIDispatchAttribute()
+ {
+ }
+ }
+
+ [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
+ [System.Runtime.InteropServices.ComVisible(false)]
+ public sealed class ManagedToNativeComInteropStubAttribute : Attribute
+ {
+ internal Type _classType;
+ internal String _methodName;
+
+ public ManagedToNativeComInteropStubAttribute(Type classType, String methodName)
+ {
+ _classType = classType;
+ _methodName = methodName;
+ }
+
+ public Type ClassType { get { return _classType; } }
+ public String MethodName { get { return _methodName; } }
+ }
+
+}
+
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/BStrWrapper.cs b/src/mscorlib/src/System/Runtime/InteropServices/BStrWrapper.cs
new file mode 100644
index 0000000000..58e93a87ea
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/BStrWrapper.cs
@@ -0,0 +1,52 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: Wrapper that is converted to a variant with VT_BSTR.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices {
+
+ using System;
+ using System.Security;
+ using System.Security.Permissions;
+
+ [Serializable]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class BStrWrapper
+ {
+ [System.Security.SecuritySafeCritical] // auto-generated
+#pragma warning disable 618
+ [SecurityPermissionAttribute(SecurityAction.Demand,Flags=SecurityPermissionFlag.UnmanagedCode)]
+#pragma warning restore 618
+ public BStrWrapper(String value)
+ {
+ m_WrappedObject = value;
+ }
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+#pragma warning disable 618
+ [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+#pragma warning restore 618
+ public BStrWrapper(Object value)
+ {
+ m_WrappedObject = (String)value;
+ }
+
+ public String WrappedObject
+ {
+ get
+ {
+ return m_WrappedObject;
+ }
+ }
+
+ private String m_WrappedObject;
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/COMException.cs b/src/mscorlib/src/System/Runtime/InteropServices/COMException.cs
new file mode 100644
index 0000000000..95b925c3f4
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/COMException.cs
@@ -0,0 +1,90 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: Exception class for all errors from COM Interop where we don't
+** recognize the HResult.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices {
+ using System;
+ using System.Runtime.Serialization;
+ using System.Globalization;
+ using System.Security;
+ using Microsoft.Win32;
+
+ // Exception for COM Interop errors where we don't recognize the HResult.
+ //
+ [ComVisible(true)]
+ [Serializable]
+ public class COMException : ExternalException {
+ public COMException()
+ : base(Environment.GetResourceString("Arg_COMException"))
+ {
+ SetErrorCode(__HResults.E_FAIL);
+ }
+
+ public COMException(String message)
+ : base(message)
+ {
+ SetErrorCode(__HResults.E_FAIL);
+ }
+
+ public COMException(String message, Exception inner)
+ : base(message, inner) {
+ SetErrorCode(__HResults.E_FAIL);
+ }
+
+ public COMException(String message,int errorCode)
+ : base(message) {
+ SetErrorCode(errorCode);
+ }
+
+ [SecuritySafeCritical]
+ internal COMException(int hresult)
+ : base(Win32Native.GetMessage(hresult))
+ {
+ SetErrorCode(hresult);
+ }
+
+ internal COMException(String message, int hresult, Exception inner)
+ : base(message, inner)
+ {
+ SetErrorCode(hresult);
+ }
+
+ protected COMException(SerializationInfo info, StreamingContext context) : base(info, context) {
+ }
+
+ public override String ToString() {
+ String message = Message;
+ String s;
+ String _className = GetType().ToString();
+ s = _className + " (0x" + HResult.ToString("X8", CultureInfo.InvariantCulture) + ")";
+
+ if (!(message == null || message.Length <= 0)) {
+ s = s + ": " + message;
+ }
+
+ Exception _innerException = InnerException;
+
+ if (_innerException!=null) {
+ s = s + " ---> " + _innerException.ToString();
+ }
+
+
+ if (StackTrace != null)
+ s += Environment.NewLine + StackTrace;
+
+ return s;
+ }
+
+
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/CallingConvention.cs b/src/mscorlib/src/System/Runtime/InteropServices/CallingConvention.cs
new file mode 100644
index 0000000000..cf4eb48af0
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/CallingConvention.cs
@@ -0,0 +1,22 @@
+// 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.
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+namespace System.Runtime.InteropServices {
+
+ using System;
+ // Used for the CallingConvention named argument to the DllImport attribute
+ [Serializable]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public enum CallingConvention
+ {
+ Winapi = 1,
+ Cdecl = 2,
+ StdCall = 3,
+ ThisCall = 4,
+ FastCall = 5,
+ }
+
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/CharSet.cs b/src/mscorlib/src/System/Runtime/InteropServices/CharSet.cs
new file mode 100644
index 0000000000..3c0710a558
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/CharSet.cs
@@ -0,0 +1,24 @@
+// 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.
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+namespace System.Runtime.InteropServices {
+ using System;
+ // Use this in P/Direct function prototypes to specify
+ // which character set to use when marshalling Strings.
+ // Using Ansi will marshal the strings as 1 byte char*'s.
+ // Using Unicode will marshal the strings as 2 byte wchar*'s.
+ // Generally you probably want to use Auto, which does the
+ // right thing 99% of the time.
+ [Serializable]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public enum CharSet
+ {
+ None = 1, // User didn't specify how to marshal strings.
+ Ansi = 2, // Strings should be marshalled as ANSI 1 byte chars.
+ Unicode = 3, // Strings should be marshalled as Unicode 2 byte chars.
+ Auto = 4, // Marshal Strings in the right way for the target system.
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComEventsHelper.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComEventsHelper.cs
new file mode 100644
index 0000000000..0bf616d94c
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComEventsHelper.cs
@@ -0,0 +1,202 @@
+// 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.
+
+
+/*============================================================
+**
+**
+** Purpose: ComEventHelpers APIs allow binding
+** managed delegates to COM's connection point based events.
+**
+**/
+namespace System.Runtime.InteropServices {
+ //
+ // #ComEventsFeature
+ //
+ // code:#ComEventsFeature defines two public methods allowing to add/remove .NET delegates handling
+ // events from COM objects. Those methods are defined as part of code:ComEventsHelper static class
+ // * code:ComEventsHelper.Combine - will create/reuse-an-existing COM event sink and register the
+ // specified delegate to be raised when corresponding COM event is raised
+ // * code:ComEventsHelper.Remove
+ //
+ //
+ // To bind an event handler to the COM object you need to provide the following data:
+ // * rcw - the instance of the COM object you want to bind to
+ // * iid - Guid of the source interface you want the sink to implement
+ // * dispid - dispatch identifier of the event on the source interface you are interested in
+ // * d - delegate to invoked when corresponding COM event is raised.
+ //
+ // #ComEventsArchitecture:
+ // In COM world, events are handled by so-called event sinks. What these are? COM-based Object Models
+ // (OMs) define "source" interfaces that need to be implemented by the COM clients to receive events. So,
+ // event sinks are COM objects implementing a source interfaces. Once an event sink is passed to the COM
+ // server (through a mechanism known as 'binding/advising to connection point'), COM server will be
+ // calling source interface methods to "fire events" (advising, connection points, firing events etc. -
+ // is all COM jargon).
+ //
+ // There are few interesting obervations about source interfaces. Usually source interfaces are defined
+ // as 'dispinterface' - meaning that only late-bound invocations on this interface are allowed. Even
+ // though it is not illegal to use early bound invocations on source interfaces - the practice is
+ // discouraged because of versioning concerns.
+ //
+ // Notice also that each COM server object might define multiple source interfaces and hence have
+ // multiple connection points (each CP handles exactly one source interface). COM objects that want to
+ // fire events are required to implement IConnectionPointContainer interface which is used by the COM
+ // clients to discovery connection poitns - objects implementing IConnectionPoint interface. Once
+ // connection point is found - clients can bind to it using IConnectionPoint::Advise (see
+ // code:ComEventsSink.Advise).
+ //
+ // The idea behind code:#ComEventsFeature is to write a "universal event sink" COM component that is
+ // generic enough to handle all late-bound event firings and invoke corresponding COM delegates (through
+ // reflection).
+ //
+ // When delegate is registered (using code:ComEventsHelper.Combine) we will verify we have corresponding
+ // event sink created and bound.
+ //
+ // But what happens when COM events are fired? code:ComEventsSink.Invoke implements IDispatch::Invoke method
+ // and this is the entry point that is called. Once our event sink is invoked, we need to find the
+ // corresponding delegate to invoke . We need to match the dispid of the call that is coming in to a
+ // dispid of .NET delegate that has been registered for this object. Once this is found we do call the
+ // delegates using reflection (code:ComEventsMethod.Invoke).
+ //
+ // #ComEventsArgsMarshalling
+ // Notice, that we may not have a delegate registered against every method on the source interface. If we
+ // were to marshal all the input parameters for methods that do not reach user code - we would end up
+ // generatic RCWs that are not reachable for user code (the inconvenience it might create is there will
+ // be RCWs that users can not call Marshal.ReleaseComObject on to explicitly manage the lifetime of these
+ // COM objects). The above behavior was one of the shortcoimings of legacy TLBIMP's implementation of COM
+ // event sinking. In our code we will not marshal any data if there is no delegate registered to handle
+ // the event. (code:ComEventsMethod.Invoke)
+ //
+ // #ComEventsFinalization:
+ // Additional area of interest is when COM sink should be unadvised from the connection point. Legacy
+ // TLBIMP's implementation of COM event sinks will unadvises the sink when corresponding RCW is GCed.
+ // This is achieved by rooting the event sinks in a finalizable object stored in RCW's property bag
+ // (using Marshal.SetComObjectData). Hence, once RCW is no longer reachable - the finalizer is called and
+ // it would unadvise all the event sinks. We are employing the same strategy here. See storing an
+ // instance in the RCW at code:ComEventsInfo.FromObject and undadvsing the sinks at
+ // code:ComEventsInfo.~ComEventsInfo
+ //
+ // Classes of interest:
+ // * code:ComEventsHelpers - defines public methods but there are also a number of internal classes that
+ // implement the actual COM event sink:
+ // * code:ComEventsInfo - represents a finalizable container for all event sinks for a particular RCW.
+ // Lifetime of this instance corresponds to the lifetime of the RCW object
+ // * code:ComEventsSink - represents a single event sink. Maintains an internal pointer to the next
+ // instance (in a singly linked list). A collection of code:ComEventsSink is stored at
+ // code:ComEventsInfo._sinks
+ // * code:ComEventsMethod - represents a single method from the source interface which has .NET delegates
+ // attached to it. Maintains an internal pointer to the next instance (in a singly linked list). A
+ // collection of code:ComEventMethod is stored at code:ComEventsSink._methods
+ //
+ // #ComEventsRetValIssue:
+ // Issue: normally, COM events would not return any value. However, it may happen as described in
+ // http://support.microsoft.com/kb/810228. Such design might represent a problem for us - e.g. what is
+ // the return value of a chain of delegates - is it the value of the last call in the chain or the the
+ // first one? As the above KB article indicates, in cases where OM has events returning values, it is
+ // suggested that people implement their event sink by explicitly implementing the source interface. This
+ // means that the problem is already quite complex and we should not be dealing with it - see
+ // code:ComEventsMethod.Invoke
+
+ using System;
+ using System.Runtime.Remoting;
+
+ /// <summary>
+ /// The static methods provided in ComEventsHelper allow using .NET delegates to subscribe to events
+ /// raised COM objects.
+ /// </summary>
+ public static class ComEventsHelper {
+
+ /// <summary>
+ /// Adds a delegate to the invocation list of events originating from the COM object.
+ /// </summary>
+ /// <param name="rcw">COM object firing the events the caller would like to respond to</param>
+ /// <param name="iid">identifier of the source interface used by COM object to fire events</param>
+ /// <param name="dispid">dispatch identifier of the method on the source interface</param>
+ /// <param name="d">delegate to invoke when specifed COM event is fired</param>
+ [System.Security.SecurityCritical]
+ public static void Combine(object rcw, Guid iid, int dispid, System.Delegate d) {
+
+ rcw = UnwrapIfTransparentProxy(rcw);
+
+ lock (rcw) {
+ ComEventsInfo eventsInfo = ComEventsInfo.FromObject(rcw);
+
+ ComEventsSink sink = eventsInfo.FindSink(ref iid);
+ if (sink == null) {
+ sink = eventsInfo.AddSink(ref iid);
+ }
+
+
+ ComEventsMethod method = sink.FindMethod(dispid);
+ if (method == null) {
+ method = sink.AddMethod(dispid);
+ }
+
+ method.AddDelegate(d);
+ }
+ }
+
+ /// <summary>
+ /// Removes a delegate from the invocation list of events originating from the COM object.
+ /// </summary>
+ /// <param name="rcw">COM object the delegate is attached to</param>
+ /// <param name="iid">identifier of the source interface used by COM object to fire events</param>
+ /// <param name="dispid">dispatch identifier of the method on the source interface</param>
+ /// <param name="d">delegate to remove from the invocation list</param>
+ /// <returns></returns>
+ [System.Security.SecurityCritical]
+ public static Delegate Remove(object rcw, Guid iid, int dispid, System.Delegate d) {
+
+ rcw = UnwrapIfTransparentProxy(rcw);
+
+ lock (rcw) {
+
+ ComEventsInfo eventsInfo = ComEventsInfo.Find(rcw);
+ if (eventsInfo == null)
+ return null;
+ ComEventsSink sink = eventsInfo.FindSink(ref iid);
+ if (sink == null)
+ return null;
+ ComEventsMethod method = sink.FindMethod(dispid);
+ if (method == null)
+ return null;
+
+ method.RemoveDelegate(d);
+
+ if (method.Empty) {
+ // removed the last event handler for this dispid - need to remove dispid handler
+ method = sink.RemoveMethod(method);
+ }
+ if (method == null) {
+ // removed last dispid handler for this sink - need to remove the sink
+ sink = eventsInfo.RemoveSink(sink);
+ }
+ if (sink == null) {
+ // removed last sink for this rcw - need to remove all traces of event info
+ Marshal.SetComObjectData(rcw, typeof(ComEventsInfo), null);
+ GC.SuppressFinalize(eventsInfo);
+ }
+
+ return d;
+ }
+ }
+
+ [System.Security.SecurityCritical]
+ internal static object UnwrapIfTransparentProxy(object rcw) {
+#if FEATURE_REMOTING
+ if (RemotingServices.IsTransparentProxy(rcw)) {
+ IntPtr punk = Marshal.GetIUnknownForObject(rcw);
+ try {
+ rcw = Marshal.GetObjectForIUnknown(punk);
+ } finally {
+ Marshal.Release(punk);
+ }
+ }
+#endif
+ return rcw;
+ }
+ }
+
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComEventsInfo.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComEventsInfo.cs
new file mode 100644
index 0000000000..6feb52445d
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComEventsInfo.cs
@@ -0,0 +1,92 @@
+// 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.
+
+
+/*============================================================
+**
+**
+** Purpose: part of ComEventHelpers APIs which allow binding
+** managed delegates to COM's connection point based events.
+**
+**/
+
+namespace System.Runtime.InteropServices {
+
+ using System;
+ using ComTypes = System.Runtime.InteropServices.ComTypes;
+
+ // see code:ComEventsHelper#ComEventsArchitecture
+ [System.Security.SecurityCritical]
+ internal class ComEventsInfo {
+
+
+#region fields
+
+ private ComEventsSink _sinks;
+ private object _rcw;
+
+#endregion
+
+
+#region ctor/dtor
+
+ ComEventsInfo(object rcw) {
+ _rcw = rcw;
+ }
+
+ [System.Security.SecuritySafeCritical]
+ ~ComEventsInfo() {
+ // see code:ComEventsHelper#ComEventsFinalization
+ _sinks = ComEventsSink.RemoveAll(_sinks);
+ }
+
+#endregion
+
+
+#region static methods
+
+ [System.Security.SecurityCritical]
+ internal static ComEventsInfo Find(object rcw) {
+ return (ComEventsInfo)Marshal.GetComObjectData(rcw, typeof(ComEventsInfo));
+ }
+
+ // it is caller's responsibility to call this method under lock(rcw)
+ [System.Security.SecurityCritical]
+ internal static ComEventsInfo FromObject(object rcw) {
+ ComEventsInfo eventsInfo = Find(rcw);
+ if (eventsInfo == null) {
+ eventsInfo = new ComEventsInfo(rcw);
+ Marshal.SetComObjectData(rcw, typeof(ComEventsInfo), eventsInfo);
+ }
+ return eventsInfo;
+ }
+
+#endregion
+
+
+#region internal methods
+
+ internal ComEventsSink FindSink(ref Guid iid) {
+ return ComEventsSink.Find(_sinks, ref iid);
+ }
+
+ // it is caller's responsibility to call this method under lock(rcw)
+ internal ComEventsSink AddSink(ref Guid iid) {
+ ComEventsSink sink = new ComEventsSink(_rcw, iid);
+ _sinks = ComEventsSink.Add(_sinks, sink);
+
+ return _sinks;
+ }
+
+ // it is caller's responsibility to call this method under lock(rcw)
+ [System.Security.SecurityCritical]
+ internal ComEventsSink RemoveSink(ComEventsSink sink) {
+ _sinks = ComEventsSink.Remove(_sinks, sink);
+ return _sinks;
+ }
+
+#endregion
+
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComEventsMethod.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComEventsMethod.cs
new file mode 100644
index 0000000000..2da0c5eea3
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComEventsMethod.cs
@@ -0,0 +1,246 @@
+// 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.
+
+
+/*============================================================
+**
+**
+** Purpose: part of ComEventHelpers APIs which allow binding
+** managed delegates to COM's connection point based events.
+**
+**/
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using System.Reflection;
+
+
+namespace System.Runtime.InteropServices {
+
+ // see code:ComEventsHelper#ComEventsArchitecture
+ internal class ComEventsMethod {
+
+ // This delegate wrapper class handles dynamic invocation of delegates. The reason for the wrapper's
+ // existence is that under certain circumstances we need to coerce arguments to types expected by the
+ // delegates signature. Normally, reflection (Delegate.DynamicInvoke) handles types coercion
+ // correctly but one known case is when the expected signature is 'ref Enum' - in this case
+ // reflection by design does not do the coercion. Since we need to be compatible with COM interop
+ // handling of this scenario - we are pre-processing delegate's signature by looking for 'ref enums'
+ // and cache the types required for such coercion.
+ internal class DelegateWrapper {
+ private Delegate _d;
+
+ private bool _once = false;
+ private int _expectedParamsCount;
+ private Type[] _cachedTargetTypes;
+
+ public DelegateWrapper(Delegate d) {
+ _d = d;
+ }
+
+ public Delegate Delegate {
+ get { return _d; }
+ set { _d = value; }
+ }
+
+ public object Invoke(object[] args) {
+ if (_d == null)
+ return null;
+
+ if (_once == false) {
+ PreProcessSignature();
+ _once = true;
+ }
+
+ if (_cachedTargetTypes != null && _expectedParamsCount == args.Length) {
+ for (int i = 0; i < _expectedParamsCount; i++) {
+ if (_cachedTargetTypes[i] != null) {
+ args[i] = Enum.ToObject(_cachedTargetTypes[i], args[i]);
+ }
+ }
+ }
+
+ return _d.DynamicInvoke(args);
+ }
+
+ private void PreProcessSignature() {
+ ParameterInfo[] parameters = _d.Method.GetParameters();
+ _expectedParamsCount = parameters.Length;
+
+ Type[] enumTypes = new Type[_expectedParamsCount];
+
+ bool needToHandleCoercion = false;
+
+ for (int i = 0; i < _expectedParamsCount; i++) {
+ ParameterInfo pi = parameters[i];
+ // recognize only 'ref Enum' signatures and cache
+ // both enum type and the underlying type.
+ if (pi.ParameterType.IsByRef &&
+ pi.ParameterType.HasElementType &&
+ pi.ParameterType.GetElementType().IsEnum) {
+
+ needToHandleCoercion = true;
+ enumTypes[i] = pi.ParameterType.GetElementType();
+ }
+ }
+
+ if (needToHandleCoercion == true) {
+ _cachedTargetTypes = enumTypes;
+ }
+ }
+ }
+
+ #region private fields
+
+ /// <summary>
+ /// Invoking ComEventsMethod means invoking a multi-cast delegate attached to it.
+ /// Since multicast delegate's built-in chaining supports only chaining instances of the same type,
+ /// we need to complement this design by using an explicit linked list data structure.
+ /// </summary>
+ private DelegateWrapper [] _delegateWrappers;
+
+ private int _dispid;
+ private ComEventsMethod _next;
+
+ #endregion
+
+
+ #region ctor
+
+ internal ComEventsMethod(int dispid) {
+ _delegateWrappers = null;
+ _dispid = dispid;
+ }
+
+ #endregion
+
+
+ #region static internal methods
+
+ internal static ComEventsMethod Find(ComEventsMethod methods, int dispid) {
+ while (methods != null && methods._dispid != dispid) {
+ methods = methods._next;
+ }
+ return methods;
+ }
+
+ internal static ComEventsMethod Add(ComEventsMethod methods, ComEventsMethod method) {
+ method._next = methods;
+ return method;
+ }
+
+ internal static ComEventsMethod Remove(ComEventsMethod methods, ComEventsMethod method) {
+ if (methods == method) {
+ methods = methods._next;
+ } else {
+ ComEventsMethod current = methods;
+ while (current != null && current._next != method)
+ current = current._next;
+ if (current != null)
+ current._next = method._next;
+ }
+
+ return methods;
+ }
+
+ #endregion
+
+
+ #region public properties / methods
+
+ internal int DispId {
+ get { return _dispid; }
+ }
+
+ internal bool Empty {
+ get { return _delegateWrappers == null || _delegateWrappers.Length == 0; }
+ }
+
+ internal void AddDelegate(Delegate d) {
+ int count = 0;
+ if (_delegateWrappers != null) {
+ count = _delegateWrappers.Length;
+ }
+
+ for (int i = 0; i < count; i++) {
+ if (_delegateWrappers[i].Delegate.GetType() == d.GetType()) {
+ _delegateWrappers[i].Delegate = Delegate.Combine(_delegateWrappers[i].Delegate, d);
+ return;
+ }
+ }
+
+ DelegateWrapper [] newDelegateWrappers = new DelegateWrapper[count + 1];
+ if (count > 0) {
+ _delegateWrappers.CopyTo(newDelegateWrappers, 0);
+ }
+
+ DelegateWrapper wrapper = new DelegateWrapper(d);
+ newDelegateWrappers[count] = wrapper;
+
+ _delegateWrappers = newDelegateWrappers;
+ }
+
+ internal void RemoveDelegate(Delegate d) {
+
+ int count = _delegateWrappers.Length;
+ int removeIdx = -1;
+
+ for (int i = 0; i < count; i++) {
+ if (_delegateWrappers[i].Delegate.GetType() == d.GetType()) {
+ removeIdx = i;
+ break;
+ }
+ }
+
+ if (removeIdx < 0)
+ return;
+
+ Delegate newDelegate = Delegate.Remove(_delegateWrappers[removeIdx].Delegate, d);
+ if (newDelegate != null) {
+ _delegateWrappers[removeIdx].Delegate = newDelegate;
+ return;
+ }
+
+ // now remove the found entry from the _delegates array
+
+ if (count == 1) {
+ _delegateWrappers = null;
+ return;
+ }
+
+ DelegateWrapper [] newDelegateWrappers = new DelegateWrapper[count - 1];
+ int j = 0;
+ while (j < removeIdx) {
+ newDelegateWrappers[j] = _delegateWrappers[j];
+ j++;
+ }
+ while (j < count-1) {
+ newDelegateWrappers[j] = _delegateWrappers[j + 1];
+ j++;
+ }
+
+ _delegateWrappers = newDelegateWrappers;
+ }
+
+ internal object Invoke(object[] args) {
+ BCLDebug.Assert(Empty == false, "event sink is executed but delegates list is empty");
+
+ // Issue: see code:ComEventsHelper#ComEventsRetValIssue
+ object result = null;
+ DelegateWrapper[] invocationList = _delegateWrappers;
+ foreach (DelegateWrapper wrapper in invocationList) {
+ if (wrapper == null || wrapper.Delegate == null)
+ continue;
+
+ result = wrapper.Invoke(args);
+ }
+
+ return result;
+ }
+
+ #endregion
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComEventsSink.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComEventsSink.cs
new file mode 100644
index 0000000000..a414eff3a1
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComEventsSink.cs
@@ -0,0 +1,286 @@
+// 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.
+
+
+/*============================================================
+**
+**
+** Purpose: part of ComEventHelpers APIs which allow binding
+** managed delegates to COM's connection point based events.
+**
+**/
+
+namespace System.Runtime.InteropServices {
+ using System;
+ using System.Diagnostics;
+
+ // see code:ComEventsHelper#ComEventsArchitecture
+ [System.Security.SecurityCritical]
+ internal class ComEventsSink : NativeMethods.IDispatch, ICustomQueryInterface
+ {
+#region private fields
+
+ private Guid _iidSourceItf;
+ private ComTypes.IConnectionPoint _connectionPoint;
+ private int _cookie;
+ private ComEventsMethod _methods;
+ private ComEventsSink _next;
+
+#endregion
+
+
+#region ctor
+
+ internal ComEventsSink(object rcw, Guid iid) {
+ _iidSourceItf = iid;
+ this.Advise(rcw);
+ }
+
+#endregion
+
+
+#region static members
+
+ internal static ComEventsSink Find(ComEventsSink sinks, ref Guid iid) {
+
+ ComEventsSink sink = sinks;
+ while (sink != null && sink._iidSourceItf != iid) {
+ sink = sink._next;
+ }
+
+ return sink;
+ }
+
+ internal static ComEventsSink Add(ComEventsSink sinks, ComEventsSink sink) {
+ sink._next = sinks;
+ return sink;
+ }
+
+ [System.Security.SecurityCritical]
+ internal static ComEventsSink RemoveAll(ComEventsSink sinks) {
+ while (sinks != null) {
+ sinks.Unadvise();
+ sinks = sinks._next;
+ }
+
+ return null;
+ }
+
+ [System.Security.SecurityCritical]
+ internal static ComEventsSink Remove(ComEventsSink sinks, ComEventsSink sink) {
+ BCLDebug.Assert(sinks != null, "removing event sink from empty sinks collection");
+ BCLDebug.Assert(sink != null, "specify event sink is null");
+
+ if (sink == sinks) {
+ sinks = sinks._next;
+ } else {
+ ComEventsSink current = sinks;
+ while (current != null && current._next != sink)
+ current = current._next;
+
+ if (current != null) {
+ current._next = sink._next;
+ }
+ }
+
+ sink.Unadvise();
+
+ return sinks;
+ }
+
+#endregion
+
+
+#region public methods
+
+ public ComEventsMethod RemoveMethod(ComEventsMethod method) {
+ _methods = ComEventsMethod.Remove(_methods, method);
+ return _methods;
+ }
+
+ public ComEventsMethod FindMethod(int dispid) {
+ return ComEventsMethod.Find(_methods, dispid);
+ }
+
+ public ComEventsMethod AddMethod(int dispid) {
+ ComEventsMethod method = new ComEventsMethod(dispid);
+ _methods = ComEventsMethod.Add(_methods, method);
+ return method;
+ }
+
+#endregion
+
+
+#region IDispatch Members
+
+ [System.Security.SecurityCritical]
+ void NativeMethods.IDispatch.GetTypeInfoCount(out uint pctinfo) {
+ pctinfo = 0;
+ }
+
+ [System.Security.SecurityCritical]
+ void NativeMethods.IDispatch.GetTypeInfo(uint iTInfo, int lcid, out IntPtr info) {
+ throw new NotImplementedException();
+ }
+
+ [System.Security.SecurityCritical]
+ void NativeMethods.IDispatch.GetIDsOfNames(ref Guid iid, string[] names, uint cNames, int lcid, int[] rgDispId) {
+ throw new NotImplementedException();
+ }
+
+ private const VarEnum VT_BYREF_VARIANT = VarEnum.VT_BYREF | VarEnum.VT_VARIANT;
+ private const VarEnum VT_TYPEMASK = (VarEnum) 0x0fff;
+ private const VarEnum VT_BYREF_TYPEMASK = VT_TYPEMASK | VarEnum.VT_BYREF;
+
+ private static unsafe Variant *GetVariant(Variant *pSrc)
+ {
+ if (pSrc->VariantType == VT_BYREF_VARIANT)
+ {
+ // For VB6 compatibility reasons, if the VARIANT is a VT_BYREF | VT_VARIANT that
+ // contains another VARIANT with VT_BYREF | VT_VARIANT, then we need to extract the
+ // inner VARIANT and use it instead of the outer one. Note that if the inner VARIANT
+ // is VT_BYREF | VT_VARIANT | VT_ARRAY, it will pass the below test too.
+ Variant *pByRefVariant = (Variant *)pSrc->AsByRefVariant;
+ if ((pByRefVariant->VariantType & VT_BYREF_TYPEMASK) == VT_BYREF_VARIANT)
+ return (Variant *)pByRefVariant;
+ }
+
+ return pSrc;
+ }
+
+ [System.Security.SecurityCritical]
+ unsafe void NativeMethods.IDispatch.Invoke(
+ int dispid,
+ ref Guid riid,
+ int lcid,
+ ComTypes.INVOKEKIND wFlags,
+ ref ComTypes.DISPPARAMS pDispParams,
+ IntPtr pvarResult,
+ IntPtr pExcepInfo,
+ IntPtr puArgErr) {
+
+ ComEventsMethod method = FindMethod(dispid);
+ if (method == null)
+ return;
+
+ // notice the unsafe pointers we are using. This is to avoid unnecessary
+ // arguments marshalling. see code:ComEventsHelper#ComEventsArgsMarshalling
+
+ object [] args = new object[pDispParams.cArgs];
+ int [] byrefsMap = new int[pDispParams.cArgs];
+ bool [] usedArgs = new bool[pDispParams.cArgs];
+
+ Variant* pvars = (Variant*)pDispParams.rgvarg;
+ int* pNamedArgs = (int*)pDispParams.rgdispidNamedArgs;
+
+ // copy the named args (positional) as specified
+ int i;
+ int pos;
+ for (i = 0; i < pDispParams.cNamedArgs; i++) {
+ pos = pNamedArgs[i];
+
+ Variant* pvar = GetVariant(&pvars[i]);
+ args[pos] = pvar->ToObject();
+ usedArgs[pos] = true;
+
+ if (pvar->IsByRef) {
+ byrefsMap[pos] = i;
+ } else {
+ byrefsMap[pos] = -1;
+ }
+ }
+
+ // copy the rest of the arguments in the reverse order
+ pos = 0;
+ for (; i < pDispParams.cArgs; i++) {
+ // find the next unassigned argument
+ while (usedArgs[pos]) {
+ ++pos;
+ }
+
+ Variant* pvar = GetVariant(&pvars[pDispParams.cArgs - 1 - i]);
+ args[pos] = pvar->ToObject();
+
+ if (pvar->IsByRef)
+ byrefsMap[pos] = pDispParams.cArgs - 1 - i;
+ else
+ byrefsMap[pos] = -1;
+
+ pos++;
+ }
+
+ // Do the actual delegate invocation
+ object result;
+ result = method.Invoke(args);
+
+ // convert result to VARIANT
+ if (pvarResult != IntPtr.Zero) {
+ Marshal.GetNativeVariantForObject(result, pvarResult);
+ }
+
+ // Now we need to marshal all the byrefs back
+ for (i = 0; i < pDispParams.cArgs; i++) {
+ int idxToPos = byrefsMap[i];
+ if (idxToPos == -1)
+ continue;
+
+ GetVariant(&pvars[idxToPos])->CopyFromIndirect(args[i]);
+ }
+ }
+
+#endregion
+
+ static Guid IID_IManagedObject = new Guid("{C3FCC19E-A970-11D2-8B5A-00A0C9B7C9C4}");
+
+ [System.Security.SecurityCritical]
+ CustomQueryInterfaceResult ICustomQueryInterface.GetInterface(ref Guid iid, out IntPtr ppv) {
+ ppv = IntPtr.Zero;
+ if (iid == this._iidSourceItf || iid == typeof(NativeMethods.IDispatch).GUID) {
+ ppv = Marshal.GetComInterfaceForObject(this, typeof(NativeMethods.IDispatch), CustomQueryInterfaceMode.Ignore);
+ return CustomQueryInterfaceResult.Handled;
+ }
+ else if (iid == IID_IManagedObject)
+ {
+ return CustomQueryInterfaceResult.Failed;
+ }
+
+ return CustomQueryInterfaceResult.NotHandled;
+ }
+
+#region private methods
+
+
+ private void Advise(object rcw) {
+ BCLDebug.Assert(_connectionPoint == null, "comevent sink is already advised");
+
+ ComTypes.IConnectionPointContainer cpc = (ComTypes.IConnectionPointContainer)rcw;
+ ComTypes.IConnectionPoint cp;
+ cpc.FindConnectionPoint(ref _iidSourceItf, out cp);
+
+ object sinkObject = this;
+
+ cp.Advise(sinkObject, out _cookie);
+
+ _connectionPoint = cp;
+ }
+
+ [System.Security.SecurityCritical]
+ private void Unadvise() {
+ BCLDebug.Assert(_connectionPoint != null, "can not unadvise from empty connection point");
+
+ try {
+ _connectionPoint.Unadvise(_cookie);
+ Marshal.ReleaseComObject(_connectionPoint);
+ } catch (System.Exception) {
+ // swallow all exceptions on unadvise
+ // the host may not be available at this point
+ } finally {
+ _connectionPoint = null;
+ }
+
+ }
+
+#endregion
+ };
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComMemberType.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComMemberType.cs
new file mode 100644
index 0000000000..3be2a56da5
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComMemberType.cs
@@ -0,0 +1,19 @@
+// 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.
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+namespace System.Runtime.InteropServices {
+
+ using System;
+
+ [Serializable]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public enum ComMemberType
+ {
+ Method = 0,
+ PropGet = 1,
+ PropSet = 2
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IBindCtx.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IBindCtx.cs
new file mode 100644
index 0000000000..aac3f59d0f
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IBindCtx.cs
@@ -0,0 +1,45 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: IBindCtx interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices.ComTypes
+{
+ using System;
+
+ [StructLayout(LayoutKind.Sequential)]
+
+ public struct BIND_OPTS
+ {
+ public int cbStruct;
+ public int grfFlags;
+ public int grfMode;
+ public int dwTickCountDeadline;
+ }
+
+ [Guid("0000000e-0000-0000-C000-000000000046")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface IBindCtx
+ {
+ void RegisterObjectBound([MarshalAs(UnmanagedType.Interface)] Object punk);
+ void RevokeObjectBound([MarshalAs(UnmanagedType.Interface)] Object punk);
+ void ReleaseBoundObjects();
+ void SetBindOptions([In()] ref BIND_OPTS pbindopts);
+ void GetBindOptions(ref BIND_OPTS pbindopts);
+ void GetRunningObjectTable(out IRunningObjectTable pprot);
+ void RegisterObjectParam([MarshalAs(UnmanagedType.LPWStr)] String pszKey, [MarshalAs(UnmanagedType.Interface)] Object punk);
+ void GetObjectParam([MarshalAs(UnmanagedType.LPWStr)] String pszKey, [MarshalAs(UnmanagedType.Interface)] out Object ppunk);
+ void EnumObjectParam(out IEnumString ppenum);
+ [PreserveSig]
+ int RevokeObjectParam([MarshalAs(UnmanagedType.LPWStr)] String pszKey);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IConnectionPoint.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IConnectionPoint.cs
new file mode 100644
index 0000000000..f70973e60d
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IConnectionPoint.cs
@@ -0,0 +1,29 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: IConnectionPoint interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices.ComTypes
+{
+ using System;
+
+ [Guid("B196B286-BAB4-101A-B69C-00AA00341D07")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface IConnectionPoint
+ {
+ void GetConnectionInterface(out Guid pIID);
+ void GetConnectionPointContainer(out IConnectionPointContainer ppCPC);
+ void Advise([MarshalAs(UnmanagedType.Interface)] Object pUnkSink, out int pdwCookie);
+ void Unadvise(int dwCookie);
+ void EnumConnections(out IEnumConnections ppEnum);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IConnectionPointContainer.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IConnectionPointContainer.cs
new file mode 100644
index 0000000000..fffff3c170
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IConnectionPointContainer.cs
@@ -0,0 +1,26 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: IConnectionPointContainer interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices.ComTypes
+{
+ using System;
+
+ [Guid("B196B284-BAB4-101A-B69C-00AA00341D07")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface IConnectionPointContainer
+ {
+ void EnumConnectionPoints(out IEnumConnectionPoints ppEnum);
+ void FindConnectionPoint([In] ref Guid riid, out IConnectionPoint ppCP);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumConnectionPoints.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumConnectionPoints.cs
new file mode 100644
index 0000000000..d667925b7e
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumConnectionPoints.cs
@@ -0,0 +1,30 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: IEnumConnectionPoints interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices.ComTypes
+{
+ using System;
+
+ [Guid("B196B285-BAB4-101A-B69C-00AA00341D07")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface IEnumConnectionPoints
+ {
+ [PreserveSig]
+ int Next(int celt, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0), Out] IConnectionPoint[] rgelt, IntPtr pceltFetched);
+ [PreserveSig]
+ int Skip(int celt);
+ void Reset();
+ void Clone(out IEnumConnectionPoints ppenum);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumConnections.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumConnections.cs
new file mode 100644
index 0000000000..8a2b4f0e6f
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumConnections.cs
@@ -0,0 +1,39 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: IEnumConnections interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices.ComTypes
+{
+ using System;
+
+ [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+
+ public struct CONNECTDATA
+ {
+ [MarshalAs(UnmanagedType.Interface)]
+ public Object pUnk;
+ public int dwCookie;
+ }
+
+ [Guid("B196B287-BAB4-101A-B69C-00AA00341D07")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface IEnumConnections
+ {
+ [PreserveSig]
+ int Next(int celt, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0), Out] CONNECTDATA[] rgelt, IntPtr pceltFetched);
+ [PreserveSig]
+ int Skip(int celt);
+ void Reset();
+ void Clone(out IEnumConnections ppenum);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumMoniker.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumMoniker.cs
new file mode 100644
index 0000000000..57994b66bc
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumMoniker.cs
@@ -0,0 +1,30 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: IEnumMoniker interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices.ComTypes
+{
+ using System;
+
+ [Guid("00000102-0000-0000-C000-000000000046")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface IEnumMoniker
+ {
+ [PreserveSig]
+ int Next(int celt, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0), Out] IMoniker[] rgelt, IntPtr pceltFetched);
+ [PreserveSig]
+ int Skip(int celt);
+ void Reset();
+ void Clone(out IEnumMoniker ppenum);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumString.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumString.cs
new file mode 100644
index 0000000000..f1e9233581
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumString.cs
@@ -0,0 +1,30 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: IEnumString interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices.ComTypes
+{
+ using System;
+
+ [Guid("00000101-0000-0000-C000-000000000046")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface IEnumString
+ {
+ [PreserveSig]
+ int Next(int celt, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 0), Out] String[] rgelt, IntPtr pceltFetched);
+ [PreserveSig]
+ int Skip(int celt);
+ void Reset();
+ void Clone(out IEnumString ppenum);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumVARIANT.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumVARIANT.cs
new file mode 100644
index 0000000000..ea9b74b7c1
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumVARIANT.cs
@@ -0,0 +1,34 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: IEnumVARIANT interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices.ComTypes
+{
+ using System;
+
+ [Guid("00020404-0000-0000-C000-000000000046")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface IEnumVARIANT
+ {
+ [PreserveSig]
+ int Next(int celt, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0), Out] object[] rgVar, IntPtr pceltFetched);
+
+ [PreserveSig]
+ int Skip(int celt);
+
+ [PreserveSig]
+ int Reset();
+
+ IEnumVARIANT Clone();
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumerable.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumerable.cs
new file mode 100644
index 0000000000..1a13399a88
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumerable.cs
@@ -0,0 +1,28 @@
+// 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.
+
+/*==========================================================================
+**
+** Interface: IEnumerable
+**
+**
+** Purpose:
+** This interface is redefined here since the original IEnumerable interface
+** has all its methods marked as ecall's since it is a managed standard
+** interface. This interface is used from within the runtime to make a call
+** on the COM server directly when it implements the IEnumerable interface.
+**
+**
+==========================================================================*/
+namespace System.Runtime.InteropServices.ComTypes
+{
+ using System;
+
+ [Guid("496B0ABE-CDEE-11d3-88E8-00902754C43A")]
+ internal interface IEnumerable
+ {
+ [DispId(-4)]
+ System.Collections.IEnumerator GetEnumerator();
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumerator.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumerator.cs
new file mode 100644
index 0000000000..aea2017b1e
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumerator.cs
@@ -0,0 +1,34 @@
+// 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.
+
+/*==========================================================================
+**
+** Interface: IEnumerator
+**
+**
+** Purpose:
+** This interface is redefined here since the original IEnumerator interface
+** has all its methods marked as ecall's since it is a managed standard
+** interface. This interface is used from within the runtime to make a call
+** on the COM server directly when it implements the IEnumerator interface.
+**
+**
+==========================================================================*/
+namespace System.Runtime.InteropServices.ComTypes
+{
+ using System;
+
+ [Guid("496B0ABF-CDEE-11d3-88E8-00902754C43A")]
+ internal interface IEnumerator
+ {
+ bool MoveNext();
+
+ Object Current
+ {
+ get;
+ }
+
+ void Reset();
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IExpando.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IExpando.cs
new file mode 100644
index 0000000000..ad4ed0b8be
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IExpando.cs
@@ -0,0 +1,31 @@
+// 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.
+
+/*==========================================================================
+**
+** Interface: IExpando
+**
+**
+** Purpose:
+** This interface is redefined here since the original IExpando interface
+** has all its methods marked as ecall's since it is a managed standard
+** interface. This interface is used from within the runtime to make a call
+** on the COM server directly when it implements the IExpando interface.
+**
+**
+==========================================================================*/
+namespace System.Runtime.InteropServices.ComTypes
+{
+ using System;
+ using System.Reflection;
+
+ [Guid("AFBF15E6-C37C-11d2-B88E-00A0C9B471B8")]
+ internal interface IExpando : IReflect
+ {
+ FieldInfo AddField(String name);
+ PropertyInfo AddProperty(String name);
+ MethodInfo AddMethod(String name, Delegate method);
+ void RemoveMember(MemberInfo m);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IMoniker.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IMoniker.cs
new file mode 100644
index 0000000000..caee5e7fa3
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IMoniker.cs
@@ -0,0 +1,61 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: IMoniker interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices.ComTypes
+{
+ using System;
+
+ [StructLayout(LayoutKind.Sequential)]
+
+ public struct FILETIME
+ {
+ public int dwLowDateTime;
+ public int dwHighDateTime;
+ }
+
+ [Guid("0000000f-0000-0000-C000-000000000046")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface IMoniker
+ {
+ // IPersist portion
+ void GetClassID(out Guid pClassID);
+
+ // IPersistStream portion
+ [PreserveSig]
+ int IsDirty();
+ void Load(IStream pStm);
+ void Save(IStream pStm, [MarshalAs(UnmanagedType.Bool)] bool fClearDirty);
+ void GetSizeMax(out Int64 pcbSize);
+
+ // IMoniker portion
+ void BindToObject(IBindCtx pbc, IMoniker pmkToLeft, [In()] ref Guid riidResult, [MarshalAs(UnmanagedType.Interface)] out Object ppvResult);
+ void BindToStorage(IBindCtx pbc, IMoniker pmkToLeft, [In()] ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out Object ppvObj);
+ void Reduce(IBindCtx pbc, int dwReduceHowFar, ref IMoniker ppmkToLeft, out IMoniker ppmkReduced);
+ void ComposeWith(IMoniker pmkRight, [MarshalAs(UnmanagedType.Bool)] bool fOnlyIfNotGeneric, out IMoniker ppmkComposite);
+ void Enum([MarshalAs(UnmanagedType.Bool)] bool fForward, out IEnumMoniker ppenumMoniker);
+ [PreserveSig]
+ int IsEqual(IMoniker pmkOtherMoniker);
+ void Hash(out int pdwHash);
+ [PreserveSig]
+ int IsRunning(IBindCtx pbc, IMoniker pmkToLeft, IMoniker pmkNewlyRunning);
+ void GetTimeOfLastChange(IBindCtx pbc, IMoniker pmkToLeft, out FILETIME pFileTime);
+ void Inverse(out IMoniker ppmk);
+ void CommonPrefixWith(IMoniker pmkOther, out IMoniker ppmkPrefix);
+ void RelativePathTo(IMoniker pmkOther, out IMoniker ppmkRelPath);
+ void GetDisplayName(IBindCtx pbc, IMoniker pmkToLeft, [MarshalAs(UnmanagedType.LPWStr)] out String ppszDisplayName);
+ void ParseDisplayName(IBindCtx pbc, IMoniker pmkToLeft, [MarshalAs(UnmanagedType.LPWStr)] String pszDisplayName, out int pchEaten, out IMoniker ppmkOut);
+ [PreserveSig]
+ int IsSystemMoniker(out int pdwMksys);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IPersistFile.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IPersistFile.cs
new file mode 100644
index 0000000000..a9f118a354
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IPersistFile.cs
@@ -0,0 +1,34 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: IPersistFile interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices.ComTypes
+{
+ using System;
+
+ [Guid("0000010b-0000-0000-C000-000000000046")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface IPersistFile
+ {
+ // IPersist portion
+ void GetClassID(out Guid pClassID);
+
+ // IPersistFile portion
+ [PreserveSig]
+ int IsDirty();
+ void Load([MarshalAs(UnmanagedType.LPWStr)] String pszFileName, int dwMode);
+ void Save([MarshalAs(UnmanagedType.LPWStr)] String pszFileName, [MarshalAs(UnmanagedType.Bool)] bool fRemember);
+ void SaveCompleted([MarshalAs(UnmanagedType.LPWStr)] String pszFileName);
+ void GetCurFile([MarshalAs(UnmanagedType.LPWStr)] out String ppszFileName);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IReflect.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IReflect.cs
new file mode 100644
index 0000000000..c86f961d01
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IReflect.cs
@@ -0,0 +1,79 @@
+// 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.
+
+/*==========================================================================
+**
+** Interface: IReflect
+**
+**
+** Purpose:
+** This interface is redefined here since the original IReflect interface
+** has all its methods marked as ecall's since it is a managed standard
+** interface. This interface is used from within the runtime to make a call
+** on the COM server directly when it implements the IReflect interface.
+**
+**
+==========================================================================*/
+namespace System.Runtime.InteropServices.ComTypes
+{
+ using System;
+ using System.Reflection;
+ using CultureInfo = System.Globalization.CultureInfo;
+
+ [Guid("AFBF15E5-C37C-11d2-B88E-00A0C9B471B8")]
+ internal interface IReflect
+ {
+ MethodInfo GetMethod(String name,BindingFlags bindingAttr,Binder binder,
+ Type[] types,ParameterModifier[] modifiers);
+
+ MethodInfo GetMethod(String name,BindingFlags bindingAttr);
+
+ MethodInfo[] GetMethods(
+ BindingFlags bindingAttr);
+
+ FieldInfo GetField(
+ String name,
+ BindingFlags bindingAttr);
+
+ FieldInfo[] GetFields(
+ BindingFlags bindingAttr);
+
+ PropertyInfo GetProperty(
+ String name,
+ BindingFlags bindingAttr);
+
+ PropertyInfo GetProperty(
+ String name,
+ BindingFlags bindingAttr,
+ Binder binder,
+ Type returnType,
+ Type[] types,
+ ParameterModifier[] modifiers);
+
+ PropertyInfo[] GetProperties(
+ BindingFlags bindingAttr);
+
+ MemberInfo[] GetMember(
+ String name,
+ BindingFlags bindingAttr);
+
+ MemberInfo[] GetMembers(
+ BindingFlags bindingAttr);
+
+ Object InvokeMember(
+ String name,
+ BindingFlags invokeAttr,
+ Binder binder,
+ Object target,
+ Object[] args,
+ ParameterModifier[] modifiers,
+ CultureInfo culture,
+ String[] namedParameters);
+
+ Type UnderlyingSystemType
+ {
+ get;
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IRunningObjectTable.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IRunningObjectTable.cs
new file mode 100644
index 0000000000..bebbdec70c
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IRunningObjectTable.cs
@@ -0,0 +1,34 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: IRunningObjectTable interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices.ComTypes
+{
+ using System;
+
+ [Guid("00000010-0000-0000-C000-000000000046")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface IRunningObjectTable
+ {
+ int Register(int grfFlags, [MarshalAs(UnmanagedType.Interface)] Object punkObject, IMoniker pmkObjectName);
+ void Revoke(int dwRegister);
+ [PreserveSig]
+ int IsRunning(IMoniker pmkObjectName);
+ [PreserveSig]
+ int GetObject(IMoniker pmkObjectName, [MarshalAs(UnmanagedType.Interface)] out Object ppunkObject);
+ void NoteChangeTime(int dwRegister, ref FILETIME pfiletime);
+ [PreserveSig]
+ int GetTimeOfLastChange(IMoniker pmkObjectName, out FILETIME pfiletime);
+ void EnumRunning(out IEnumMoniker ppenumMoniker);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IStream.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IStream.cs
new file mode 100644
index 0000000000..616ecbfa18
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IStream.cs
@@ -0,0 +1,55 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: IStream interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices.ComTypes
+{
+ using System;
+
+ [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+
+ public struct STATSTG
+ {
+ public String pwcsName;
+ public int type;
+ public Int64 cbSize;
+ public FILETIME mtime;
+ public FILETIME ctime;
+ public FILETIME atime;
+ public int grfMode;
+ public int grfLocksSupported;
+ public Guid clsid;
+ public int grfStateBits;
+ public int reserved;
+ }
+
+ [Guid("0000000c-0000-0000-C000-000000000046")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface IStream
+ {
+ // ISequentialStream portion
+ void Read([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1), Out] Byte[] pv, int cb, IntPtr pcbRead);
+ void Write([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] Byte[] pv, int cb, IntPtr pcbWritten);
+
+ // IStream portion
+ void Seek(Int64 dlibMove, int dwOrigin, IntPtr plibNewPosition);
+ void SetSize(Int64 libNewSize);
+ void CopyTo(IStream pstm, Int64 cb, IntPtr pcbRead, IntPtr pcbWritten);
+ void Commit(int grfCommitFlags);
+ void Revert();
+ void LockRegion(Int64 libOffset, Int64 cb, int dwLockType);
+ void UnlockRegion(Int64 libOffset, Int64 cb, int dwLockType);
+ void Stat(out STATSTG pstatstg, int grfStatFlag);
+ void Clone(out IStream ppstm);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeComp.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeComp.cs
new file mode 100644
index 0000000000..f938ba91a7
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeComp.cs
@@ -0,0 +1,49 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: ITypeComp interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices.ComTypes
+{
+ using System;
+
+ [Serializable]
+ public enum DESCKIND
+ {
+ DESCKIND_NONE = 0,
+ DESCKIND_FUNCDESC = DESCKIND_NONE + 1,
+ DESCKIND_VARDESC = DESCKIND_FUNCDESC + 1,
+ DESCKIND_TYPECOMP = DESCKIND_VARDESC + 1,
+ DESCKIND_IMPLICITAPPOBJ = DESCKIND_TYPECOMP + 1,
+ DESCKIND_MAX = DESCKIND_IMPLICITAPPOBJ + 1
+ }
+
+ [StructLayout(LayoutKind.Explicit, CharSet=CharSet.Unicode)]
+
+ public struct BINDPTR
+ {
+ [FieldOffset(0)]
+ public IntPtr lpfuncdesc;
+ [FieldOffset(0)]
+ public IntPtr lpvardesc;
+ [FieldOffset(0)]
+ public IntPtr lptcomp;
+ }
+
+ [Guid("00020403-0000-0000-C000-000000000046")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface ITypeComp
+ {
+ void Bind([MarshalAs(UnmanagedType.LPWStr)] String szName, int lHashVal, Int16 wFlags, out ITypeInfo ppTInfo, out DESCKIND pDescKind, out BINDPTR pBindPtr);
+ void BindType([MarshalAs(UnmanagedType.LPWStr)] String szName, int lHashVal, out ITypeInfo ppTInfo, out ITypeComp ppTComp);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeInfo.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeInfo.cs
new file mode 100644
index 0000000000..7a12605f20
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeInfo.cs
@@ -0,0 +1,335 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: ITypeInfo interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices.ComTypes
+{
+ using System;
+
+ [Serializable]
+ public enum TYPEKIND
+ {
+ TKIND_ENUM = 0,
+ TKIND_RECORD = TKIND_ENUM + 1,
+ TKIND_MODULE = TKIND_RECORD + 1,
+ TKIND_INTERFACE = TKIND_MODULE + 1,
+ TKIND_DISPATCH = TKIND_INTERFACE + 1,
+ TKIND_COCLASS = TKIND_DISPATCH + 1,
+ TKIND_ALIAS = TKIND_COCLASS + 1,
+ TKIND_UNION = TKIND_ALIAS + 1,
+ TKIND_MAX = TKIND_UNION + 1
+ }
+
+[Serializable]
+[Flags()]
+ public enum TYPEFLAGS : short
+ {
+ TYPEFLAG_FAPPOBJECT = 0x1,
+ TYPEFLAG_FCANCREATE = 0x2,
+ TYPEFLAG_FLICENSED = 0x4,
+ TYPEFLAG_FPREDECLID = 0x8,
+ TYPEFLAG_FHIDDEN = 0x10,
+ TYPEFLAG_FCONTROL = 0x20,
+ TYPEFLAG_FDUAL = 0x40,
+ TYPEFLAG_FNONEXTENSIBLE = 0x80,
+ TYPEFLAG_FOLEAUTOMATION = 0x100,
+ TYPEFLAG_FRESTRICTED = 0x200,
+ TYPEFLAG_FAGGREGATABLE = 0x400,
+ TYPEFLAG_FREPLACEABLE = 0x800,
+ TYPEFLAG_FDISPATCHABLE = 0x1000,
+ TYPEFLAG_FREVERSEBIND = 0x2000,
+ TYPEFLAG_FPROXY = 0x4000
+ }
+
+[Serializable]
+[Flags()]
+ public enum IMPLTYPEFLAGS
+ {
+ IMPLTYPEFLAG_FDEFAULT = 0x1,
+ IMPLTYPEFLAG_FSOURCE = 0x2,
+ IMPLTYPEFLAG_FRESTRICTED = 0x4,
+ IMPLTYPEFLAG_FDEFAULTVTABLE = 0x8,
+ }
+
+ [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+
+ public struct TYPEATTR
+ {
+ // Constant used with the memid fields.
+ public const int MEMBER_ID_NIL = unchecked((int)0xFFFFFFFF);
+
+ // Actual fields of the TypeAttr struct.
+ public Guid guid;
+ public Int32 lcid;
+ public Int32 dwReserved;
+ public Int32 memidConstructor;
+ public Int32 memidDestructor;
+ public IntPtr lpstrSchema;
+ public Int32 cbSizeInstance;
+ public TYPEKIND typekind;
+ public Int16 cFuncs;
+ public Int16 cVars;
+ public Int16 cImplTypes;
+ public Int16 cbSizeVft;
+ public Int16 cbAlignment;
+ public TYPEFLAGS wTypeFlags;
+ public Int16 wMajorVerNum;
+ public Int16 wMinorVerNum;
+ public TYPEDESC tdescAlias;
+ public IDLDESC idldescType;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+
+ public struct FUNCDESC
+ {
+ public int memid; //MEMBERID memid;
+ public IntPtr lprgscode; // /* [size_is(cScodes)] */ SCODE RPC_FAR *lprgscode;
+ public IntPtr lprgelemdescParam; // /* [size_is(cParams)] */ ELEMDESC __RPC_FAR *lprgelemdescParam;
+ public FUNCKIND funckind; //FUNCKIND funckind;
+ public INVOKEKIND invkind; //INVOKEKIND invkind;
+ public CALLCONV callconv; //CALLCONV callconv;
+ public Int16 cParams; //short cParams;
+ public Int16 cParamsOpt; //short cParamsOpt;
+ public Int16 oVft; //short oVft;
+ public Int16 cScodes; //short cScodes;
+ public ELEMDESC elemdescFunc; //ELEMDESC elemdescFunc;
+ public Int16 wFuncFlags; //WORD wFuncFlags;
+ }
+
+[Serializable]
+[Flags()]
+ public enum IDLFLAG : short
+ {
+ IDLFLAG_NONE = PARAMFLAG.PARAMFLAG_NONE,
+ IDLFLAG_FIN = PARAMFLAG.PARAMFLAG_FIN,
+ IDLFLAG_FOUT = PARAMFLAG.PARAMFLAG_FOUT,
+ IDLFLAG_FLCID = PARAMFLAG.PARAMFLAG_FLCID,
+ IDLFLAG_FRETVAL = PARAMFLAG.PARAMFLAG_FRETVAL
+ }
+
+ [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+
+ public struct IDLDESC
+ {
+ public IntPtr dwReserved;
+ public IDLFLAG wIDLFlags;
+ }
+
+[Serializable]
+[Flags()]
+ public enum PARAMFLAG :short
+ {
+ PARAMFLAG_NONE = 0,
+ PARAMFLAG_FIN = 0x1,
+ PARAMFLAG_FOUT = 0x2,
+ PARAMFLAG_FLCID = 0x4,
+ PARAMFLAG_FRETVAL = 0x8,
+ PARAMFLAG_FOPT = 0x10,
+ PARAMFLAG_FHASDEFAULT = 0x20,
+ PARAMFLAG_FHASCUSTDATA = 0x40
+ }
+
+ [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+
+ public struct PARAMDESC
+ {
+ public IntPtr lpVarValue;
+ public PARAMFLAG wParamFlags;
+ }
+
+ [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+
+ public struct TYPEDESC
+ {
+ public IntPtr lpValue;
+ public Int16 vt;
+ }
+
+ [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+
+ public struct ELEMDESC
+ {
+ public TYPEDESC tdesc;
+
+ [System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit, CharSet=CharSet.Unicode)]
+
+ public struct DESCUNION
+ {
+ [FieldOffset(0)]
+ public IDLDESC idldesc;
+ [FieldOffset(0)]
+ public PARAMDESC paramdesc;
+ };
+ public DESCUNION desc;
+ }
+
+ [Serializable]
+ public enum VARKIND : int
+ {
+ VAR_PERINSTANCE = 0x0,
+ VAR_STATIC = 0x1,
+ VAR_CONST = 0x2,
+ VAR_DISPATCH = 0x3
+ }
+
+ [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+
+ public struct VARDESC
+ {
+ public int memid;
+ public String lpstrSchema;
+
+ [System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit, CharSet=CharSet.Unicode)]
+
+ public struct DESCUNION
+ {
+ [FieldOffset(0)]
+ public int oInst;
+ [FieldOffset(0)]
+ public IntPtr lpvarValue;
+ };
+
+ public DESCUNION desc;
+
+ public ELEMDESC elemdescVar;
+ public short wVarFlags;
+ public VARKIND varkind;
+ }
+
+ [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+
+ public struct DISPPARAMS
+ {
+ public IntPtr rgvarg;
+ public IntPtr rgdispidNamedArgs;
+ public int cArgs;
+ public int cNamedArgs;
+ }
+
+ [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+
+ public struct EXCEPINFO
+ {
+ public Int16 wCode;
+ public Int16 wReserved;
+ [MarshalAs(UnmanagedType.BStr)] public String bstrSource;
+ [MarshalAs(UnmanagedType.BStr)] public String bstrDescription;
+ [MarshalAs(UnmanagedType.BStr)] public String bstrHelpFile;
+ public int dwHelpContext;
+ public IntPtr pvReserved;
+ public IntPtr pfnDeferredFillIn;
+ public Int32 scode;
+ }
+
+ [Serializable]
+ public enum FUNCKIND : int
+ {
+ FUNC_VIRTUAL = 0,
+ FUNC_PUREVIRTUAL = 1,
+ FUNC_NONVIRTUAL = 2,
+ FUNC_STATIC = 3,
+ FUNC_DISPATCH = 4
+ }
+
+[Serializable]
+[Flags]
+ public enum INVOKEKIND : int
+ {
+ INVOKE_FUNC = 0x1,
+ INVOKE_PROPERTYGET = 0x2,
+ INVOKE_PROPERTYPUT = 0x4,
+ INVOKE_PROPERTYPUTREF = 0x8
+ }
+
+ [Serializable]
+ public enum CALLCONV : int
+ {
+ CC_CDECL =1,
+ CC_MSCPASCAL=2,
+ CC_PASCAL =CC_MSCPASCAL,
+ CC_MACPASCAL=3,
+ CC_STDCALL =4,
+ CC_RESERVED =5,
+ CC_SYSCALL =6,
+ CC_MPWCDECL =7,
+ CC_MPWPASCAL=8,
+ CC_MAX =9
+ }
+
+[Serializable]
+[Flags()]
+ public enum FUNCFLAGS : short
+ {
+ FUNCFLAG_FRESTRICTED= 0x1,
+ FUNCFLAG_FSOURCE = 0x2,
+ FUNCFLAG_FBINDABLE = 0x4,
+ FUNCFLAG_FREQUESTEDIT = 0x8,
+ FUNCFLAG_FDISPLAYBIND = 0x10,
+ FUNCFLAG_FDEFAULTBIND = 0x20,
+ FUNCFLAG_FHIDDEN = 0x40,
+ FUNCFLAG_FUSESGETLASTERROR= 0x80,
+ FUNCFLAG_FDEFAULTCOLLELEM= 0x100,
+ FUNCFLAG_FUIDEFAULT = 0x200,
+ FUNCFLAG_FNONBROWSABLE = 0x400,
+ FUNCFLAG_FREPLACEABLE = 0x800,
+ FUNCFLAG_FIMMEDIATEBIND = 0x1000
+ }
+
+[Serializable]
+[Flags()]
+ public enum VARFLAGS : short
+ {
+ VARFLAG_FREADONLY =0x1,
+ VARFLAG_FSOURCE =0x2,
+ VARFLAG_FBINDABLE =0x4,
+ VARFLAG_FREQUESTEDIT =0x8,
+ VARFLAG_FDISPLAYBIND =0x10,
+ VARFLAG_FDEFAULTBIND =0x20,
+ VARFLAG_FHIDDEN =0x40,
+ VARFLAG_FRESTRICTED =0x80,
+ VARFLAG_FDEFAULTCOLLELEM =0x100,
+ VARFLAG_FUIDEFAULT =0x200,
+ VARFLAG_FNONBROWSABLE =0x400,
+ VARFLAG_FREPLACEABLE =0x800,
+ VARFLAG_FIMMEDIATEBIND =0x1000
+ }
+
+ [Guid("00020401-0000-0000-C000-000000000046")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface ITypeInfo
+ {
+ void GetTypeAttr(out IntPtr ppTypeAttr);
+ void GetTypeComp(out ITypeComp ppTComp);
+ void GetFuncDesc(int index, out IntPtr ppFuncDesc);
+ void GetVarDesc(int index, out IntPtr ppVarDesc);
+ void GetNames(int memid, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2), Out] String[] rgBstrNames, int cMaxNames, out int pcNames);
+ void GetRefTypeOfImplType(int index, out int href);
+ void GetImplTypeFlags(int index, out IMPLTYPEFLAGS pImplTypeFlags);
+ void GetIDsOfNames([MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 1), In] String[] rgszNames, int cNames, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1), Out] int[] pMemId);
+ void Invoke([MarshalAs(UnmanagedType.IUnknown)] Object pvInstance, int memid, Int16 wFlags, ref DISPPARAMS pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, out int puArgErr);
+ void GetDocumentation(int index, out String strName, out String strDocString, out int dwHelpContext, out String strHelpFile);
+ void GetDllEntry(int memid, INVOKEKIND invKind, IntPtr pBstrDllName, IntPtr pBstrName, IntPtr pwOrdinal);
+ void GetRefTypeInfo(int hRef, out ITypeInfo ppTI);
+ void AddressOfMember(int memid, INVOKEKIND invKind, out IntPtr ppv);
+ void CreateInstance([MarshalAs(UnmanagedType.IUnknown)] Object pUnkOuter, [In] ref Guid riid, [MarshalAs(UnmanagedType.IUnknown), Out] out Object ppvObj);
+ void GetMops(int memid, out String pBstrMops);
+ void GetContainingTypeLib(out ITypeLib ppTLB, out int pIndex);
+ [PreserveSig]
+ void ReleaseTypeAttr(IntPtr pTypeAttr);
+ [PreserveSig]
+ void ReleaseFuncDesc(IntPtr pFuncDesc);
+ [PreserveSig]
+ void ReleaseVarDesc(IntPtr pVarDesc);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeInfo2.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeInfo2.cs
new file mode 100644
index 0000000000..a782b9edd6
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeInfo2.cs
@@ -0,0 +1,62 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: ITypeInfo2 interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices.ComTypes
+{
+ using System;
+
+ [Guid("00020412-0000-0000-C000-000000000046")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface ITypeInfo2 : ITypeInfo
+ {
+ new void GetTypeAttr(out IntPtr ppTypeAttr);
+ new void GetTypeComp(out ITypeComp ppTComp);
+ new void GetFuncDesc(int index, out IntPtr ppFuncDesc);
+ new void GetVarDesc(int index, out IntPtr ppVarDesc);
+ new void GetNames(int memid, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2), Out] String[] rgBstrNames, int cMaxNames, out int pcNames);
+ new void GetRefTypeOfImplType(int index, out int href);
+ new void GetImplTypeFlags(int index, out IMPLTYPEFLAGS pImplTypeFlags);
+ new void GetIDsOfNames([MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 1), In] String[] rgszNames, int cNames, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1), Out] int[] pMemId);
+ new void Invoke([MarshalAs(UnmanagedType.IUnknown)] Object pvInstance, int memid, Int16 wFlags, ref DISPPARAMS pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, out int puArgErr);
+ new void GetDocumentation(int index, out String strName, out String strDocString, out int dwHelpContext, out String strHelpFile);
+ new void GetDllEntry(int memid, INVOKEKIND invKind, IntPtr pBstrDllName, IntPtr pBstrName, IntPtr pwOrdinal);
+ new void GetRefTypeInfo(int hRef, out ITypeInfo ppTI);
+ new void AddressOfMember(int memid, INVOKEKIND invKind, out IntPtr ppv);
+ new void CreateInstance([MarshalAs(UnmanagedType.IUnknown)] Object pUnkOuter, [In] ref Guid riid, [MarshalAs(UnmanagedType.IUnknown), Out] out Object ppvObj);
+ new void GetMops(int memid, out String pBstrMops);
+ new void GetContainingTypeLib(out ITypeLib ppTLB, out int pIndex);
+ [PreserveSig]
+ new void ReleaseTypeAttr(IntPtr pTypeAttr);
+ [PreserveSig]
+ new void ReleaseFuncDesc(IntPtr pFuncDesc);
+ [PreserveSig]
+ new void ReleaseVarDesc(IntPtr pVarDesc);
+ void GetTypeKind(out TYPEKIND pTypeKind);
+ void GetTypeFlags(out int pTypeFlags);
+ void GetFuncIndexOfMemId(int memid, INVOKEKIND invKind, out int pFuncIndex);
+ void GetVarIndexOfMemId(int memid, out int pVarIndex);
+ void GetCustData(ref Guid guid, out Object pVarVal);
+ void GetFuncCustData(int index, ref Guid guid, out Object pVarVal);
+ void GetParamCustData(int indexFunc, int indexParam, ref Guid guid, out Object pVarVal);
+ void GetVarCustData(int index, ref Guid guid, out Object pVarVal);
+ void GetImplTypeCustData(int index, ref Guid guid, out Object pVarVal);
+ [LCIDConversionAttribute(1)]
+ void GetDocumentation2(int memid, out String pbstrHelpString, out int pdwHelpStringContext, out String pbstrHelpStringDll);
+ void GetAllCustData(IntPtr pCustData);
+ void GetAllFuncCustData(int index, IntPtr pCustData);
+ void GetAllParamCustData(int indexFunc, int indexParam, IntPtr pCustData);
+ void GetAllVarCustData(int index, IntPtr pCustData);
+ void GetAllImplTypeCustData(int index, IntPtr pCustData);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeLib.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeLib.cs
new file mode 100644
index 0000000000..c39b088c0b
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeLib.cs
@@ -0,0 +1,68 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: ITypeLib interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices.ComTypes
+{
+ using System;
+
+ [Serializable]
+ public enum SYSKIND
+ {
+ SYS_WIN16 = 0,
+ SYS_WIN32 = SYS_WIN16 + 1,
+ SYS_MAC = SYS_WIN32 + 1,
+ SYS_WIN64 = SYS_MAC + 1
+ }
+
+[Serializable]
+[Flags()]
+ public enum LIBFLAGS : short
+ {
+ LIBFLAG_FRESTRICTED = 0x1,
+ LIBFLAG_FCONTROL = 0x2,
+ LIBFLAG_FHIDDEN = 0x4,
+ LIBFLAG_FHASDISKIMAGE = 0x8
+ }
+
+ [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+ [Serializable]
+ public struct TYPELIBATTR
+ {
+ public Guid guid;
+ public int lcid;
+ public SYSKIND syskind;
+ public Int16 wMajorVerNum;
+ public Int16 wMinorVerNum;
+ public LIBFLAGS wLibFlags;
+ }
+
+ [Guid("00020402-0000-0000-C000-000000000046")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface ITypeLib
+ {
+ [PreserveSig]
+ int GetTypeInfoCount();
+ void GetTypeInfo(int index, out ITypeInfo ppTI);
+ void GetTypeInfoType(int index, out TYPEKIND pTKind);
+ void GetTypeInfoOfGuid(ref Guid guid, out ITypeInfo ppTInfo);
+ void GetLibAttr(out IntPtr ppTLibAttr);
+ void GetTypeComp(out ITypeComp ppTComp);
+ void GetDocumentation(int index, out String strName, out String strDocString, out int dwHelpContext, out String strHelpFile);
+ [return : MarshalAs(UnmanagedType.Bool)]
+ bool IsName([MarshalAs(UnmanagedType.LPWStr)] String szNameBuf, int lHashVal);
+ void FindName([MarshalAs(UnmanagedType.LPWStr)] String szNameBuf, int lHashVal, [MarshalAs(UnmanagedType.LPArray), Out] ITypeInfo[] ppTInfo, [MarshalAs(UnmanagedType.LPArray), Out] int[] rgMemId, ref Int16 pcFound);
+ [PreserveSig]
+ void ReleaseTLibAttr(IntPtr pTLibAttr);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeLib2.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeLib2.cs
new file mode 100644
index 0000000000..5a7d07c001
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeLib2.cs
@@ -0,0 +1,42 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: ITypeLib2 interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices.ComTypes
+{
+ using System;
+
+ [Guid("00020411-0000-0000-C000-000000000046")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface ITypeLib2 : ITypeLib
+ {
+ [PreserveSig]
+ new int GetTypeInfoCount();
+ new void GetTypeInfo(int index, out ITypeInfo ppTI);
+ new void GetTypeInfoType(int index, out TYPEKIND pTKind);
+ new void GetTypeInfoOfGuid(ref Guid guid, out ITypeInfo ppTInfo);
+ new void GetLibAttr(out IntPtr ppTLibAttr);
+ new void GetTypeComp(out ITypeComp ppTComp);
+ new void GetDocumentation(int index, out String strName, out String strDocString, out int dwHelpContext, out String strHelpFile);
+ [return : MarshalAs(UnmanagedType.Bool)]
+ new bool IsName([MarshalAs(UnmanagedType.LPWStr)] String szNameBuf, int lHashVal);
+ new void FindName([MarshalAs(UnmanagedType.LPWStr)] String szNameBuf, int lHashVal, [MarshalAs(UnmanagedType.LPArray), Out] ITypeInfo[] ppTInfo, [MarshalAs(UnmanagedType.LPArray), Out] int[] rgMemId, ref Int16 pcFound);
+ [PreserveSig]
+ new void ReleaseTLibAttr(IntPtr pTLibAttr);
+ void GetCustData(ref Guid guid, out Object pVarVal);
+ [LCIDConversionAttribute(1)]
+ void GetDocumentation2(int index, out String pbstrHelpString, out int pdwHelpStringContext, out String pbstrHelpStringDll);
+ void GetLibStatistics(IntPtr pcUniqueNames, out int pcchUniqueNames);
+ void GetAllCustData(IntPtr pCustData);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/CriticalHandle.cs b/src/mscorlib/src/System/Runtime/InteropServices/CriticalHandle.cs
new file mode 100644
index 0000000000..54fd6b0cdd
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/CriticalHandle.cs
@@ -0,0 +1,275 @@
+// 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.
+
+/*============================================================
+**
+**
+**
+** A specially designed handle wrapper to ensure we never leak
+** an OS handle. The runtime treats this class specially during
+** P/Invoke marshaling and finalization. Users should write
+** subclasses of CriticalHandle for each distinct handle type.
+** This class is similar to SafeHandle, but lacks the ref counting
+** behavior on marshaling that prevents handle recycling errors
+** or security holes. This lowers the overhead of using the handle
+** considerably, but leaves the onus on the caller to protect
+** themselves from any recycling effects.
+**
+** **** NOTE ****
+**
+** Since there are no ref counts tracking handle usage there is
+** no thread safety either. Your application must ensure that
+** usages of the handle do not cross with attempts to close the
+** handle (or tolerate such crossings). Normal GC mechanics will
+** prevent finalization until the handle class isn't used any more,
+** but explicit Close or Dispose operations may be initiated at any
+** time.
+**
+** Similarly, multiple calls to Close or Dispose on different
+** threads at the same time may cause the ReleaseHandle method to be
+** called more than once.
+**
+** In general (and as might be inferred from the lack of handle
+** recycle protection) you should be very cautious about exposing
+** CriticalHandle instances directly or indirectly to untrusted users.
+** At a minimum you should restrict their ability to queue multiple
+** operations against a single handle at the same time or block their
+** access to Close and Dispose unless you are very comfortable with the
+** semantics of passing an invalid (or possibly invalidated and
+** reallocated) to the unamanged routines you marshal your handle to
+** (and the effects of closing such a handle while those calls are in
+** progress). The runtime cannot protect you from undefined program
+** behvior that might result from such scenarios. You have been warned.
+**
+**
+===========================================================*/
+
+using System;
+using System.Reflection;
+using System.Threading;
+using System.Security.Permissions;
+using System.Runtime.CompilerServices;
+using System.Runtime.Versioning;
+using System.Runtime.ConstrainedExecution;
+using System.IO;
+
+/*
+ Problems addressed by the CriticalHandle class:
+ 1) Critical finalization - ensure we never leak OS resources in SQL. Done
+ without running truly arbitrary & unbounded amounts of managed code.
+ 2) Reduced graph promotion - during finalization, keep object graph small
+ 3) GC.KeepAlive behavior - P/Invoke vs. finalizer thread race condition (HandleRef)
+ 4) Enforcement of the above via the type system - Don't use IntPtr anymore.
+
+ Subclasses of CriticalHandle will implement the ReleaseHandle
+ abstract method used to execute any code required to free the
+ handle. This method will be prepared as a constrained execution
+ region at instance construction time (along with all the methods in
+ its statically determinable call graph). This implies that we won't
+ get any inconvenient jit allocation errors or rude thread abort
+ interrupts while releasing the handle but the user must still write
+ careful code to avoid injecting fault paths of their own (see the
+ CER spec for more details). In particular, any sub-methods you call
+ should be decorated with a reliability contract of the appropriate
+ level. In most cases this should be:
+ ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)
+ Also, any P/Invoke methods should use the
+ SuppressUnmanagedCodeSecurity attribute to avoid a runtime security
+ check that can also inject failures (even if the check is guaranteed
+ to pass).
+
+ Subclasses must also implement the IsInvalid property so that the
+ infrastructure can tell when critical finalization is actually required.
+ Again, this method is prepared ahead of time. It's envisioned that direct
+ subclasses of CriticalHandle will provide an IsInvalid implementation that suits
+ the general type of handle they support (null is invalid, -1 is invalid etc.)
+ and then these classes will be further derived for specific handle types.
+
+ Most classes using CriticalHandle should not provide a finalizer. If they do
+ need to do so (ie, for flushing out file buffers, needing to write some data
+ back into memory, etc), then they can provide a finalizer that will be
+ guaranteed to run before the CriticalHandle's critical finalizer.
+
+ Subclasses are expected to be written as follows (note that
+ SuppressUnmanagedCodeSecurity should always be used on any P/Invoke methods
+ invoked as part of ReleaseHandle, in order to switch the security check from
+ runtime to jit time and thus remove a possible failure path from the
+ invocation of the method):
+
+ internal sealed MyCriticalHandleSubclass : CriticalHandle {
+ // Called by P/Invoke when returning CriticalHandles
+ private MyCriticalHandleSubclass() : base(IntPtr.Zero)
+ {
+ }
+
+ // Do not provide a finalizer - CriticalHandle's critical finalizer will
+ // call ReleaseHandle for you.
+
+ public override bool IsInvalid {
+ get { return handle == IntPtr.Zero; }
+ }
+
+ [DllImport(Win32Native.KERNEL32), SuppressUnmanagedCodeSecurity, ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ private static extern bool CloseHandle(IntPtr handle);
+
+ override protected bool ReleaseHandle()
+ {
+ return CloseHandle(handle);
+ }
+ }
+
+ Then elsewhere to create one of these CriticalHandles, define a method
+ with the following type of signature (CreateFile follows this model).
+ Note that when returning a CriticalHandle like this, P/Invoke will call your
+ classes default constructor.
+
+ [DllImport(Win32Native.KERNEL32)]
+ private static extern MyCriticalHandleSubclass CreateHandle(int someState);
+
+ */
+
+namespace System.Runtime.InteropServices
+{
+
+// This class should not be serializable - it's a handle. We require unmanaged
+// code permission to subclass CriticalHandle to prevent people from writing a
+// subclass and suddenly being able to run arbitrary native code with the
+// same signature as CloseHandle. This is technically a little redundant, but
+// we'll do this to ensure we've cut off all attack vectors. Similarly, all
+// methods have a link demand to ensure untrusted code cannot directly edit
+// or alter a handle.
+[System.Security.SecurityCritical] // auto-generated_required
+#if !FEATURE_CORECLR
+[SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode=true)]
+#endif
+public abstract class CriticalHandle : CriticalFinalizerObject, IDisposable
+{
+ // ! Do not add or rearrange fields as the EE depends on this layout.
+ //------------------------------------------------------------------
+#if DEBUG
+ private String _stackTrace; // Where we allocated this CriticalHandle.
+#endif
+ protected IntPtr handle; // This must be protected so derived classes can use out params.
+ private bool _isClosed; // Set by SetHandleAsInvalid or Close/Dispose/finalization.
+
+ // Creates a CriticalHandle class. Users must then set the Handle property or allow P/Invoke marshaling to set it implicitly.
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
+ protected CriticalHandle(IntPtr invalidHandleValue)
+ {
+ handle = invalidHandleValue;
+ _isClosed = false;
+
+#if DEBUG
+ if (BCLDebug.SafeHandleStackTracesEnabled)
+ _stackTrace = Environment.GetStackTrace(null, false);
+ else
+ _stackTrace = "For a stack trace showing who allocated this CriticalHandle, set SafeHandleStackTraces to 1 and rerun your app.";
+#endif
+ }
+
+#if FEATURE_CORECLR
+ // Adding an empty default constructor for annotation purposes
+ private CriticalHandle(){}
+#endif
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ ~CriticalHandle()
+ {
+ Dispose(false);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ private void Cleanup()
+ {
+ if (IsClosed)
+ return;
+ _isClosed = true;
+
+ if (IsInvalid)
+ return;
+
+ // Save last error from P/Invoke in case the implementation of
+ // ReleaseHandle trashes it (important because this ReleaseHandle could
+ // occur implicitly as part of unmarshaling another P/Invoke).
+ int lastError = Marshal.GetLastWin32Error();
+
+ if (!ReleaseHandle())
+ FireCustomerDebugProbe();
+
+ Marshal.SetLastWin32Error(lastError);
+
+ GC.SuppressFinalize(this);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ private extern void FireCustomerDebugProbe();
+
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ protected void SetHandle(IntPtr handle) {
+ this.handle = handle;
+ }
+
+ // Returns whether the handle has been explicitly marked as closed
+ // (Close/Dispose) or invalid (SetHandleAsInvalid).
+ public bool IsClosed {
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ get { return _isClosed; }
+ }
+
+ // Returns whether the handle looks like an invalid value (i.e. matches one
+ // of the handle's designated illegal values). CriticalHandle itself doesn't
+ // know what an invalid handle looks like, so this method is abstract and
+ // must be provided by a derived type.
+ public abstract bool IsInvalid {
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ get;
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ public void Close() {
+ Dispose(true);
+ }
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ protected virtual void Dispose(bool disposing)
+ {
+ Cleanup();
+ }
+
+ // This should only be called for cases when you know for a fact that
+ // your handle is invalid and you want to record that information.
+ // An example is calling a syscall and getting back ERROR_INVALID_HANDLE.
+ // This method will normally leak handles!
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ public void SetHandleAsInvalid()
+ {
+ _isClosed = true;
+ GC.SuppressFinalize(this);
+ }
+
+ // Implement this abstract method in your derived class to specify how to
+ // free the handle. Be careful not write any code that's subject to faults
+ // in this method (the runtime will prepare the infrastructure for you so
+ // that no jit allocations etc. will occur, but don't allocate memory unless
+ // you can deal with the failure and still free the handle).
+ // The boolean returned should be true for success and false if a
+ // catastrophic error occurred and you wish to trigger a diagnostic for
+ // debugging purposes (the SafeHandleCriticalFailure MDA).
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ protected abstract bool ReleaseHandle();
+}
+
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/CurrencyWrapper.cs b/src/mscorlib/src/System/Runtime/InteropServices/CurrencyWrapper.cs
new file mode 100644
index 0000000000..1f7a9f18bf
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/CurrencyWrapper.cs
@@ -0,0 +1,44 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: Wrapper that is converted to a variant with VT_CURRENCY.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices {
+
+ using System;
+
+ [Serializable]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class CurrencyWrapper
+ {
+ public CurrencyWrapper(Decimal obj)
+ {
+ m_WrappedObject = obj;
+ }
+
+ public CurrencyWrapper(Object obj)
+ {
+ if (!(obj is Decimal))
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDecimal"), "obj");
+ m_WrappedObject = (Decimal)obj;
+ }
+
+ public Decimal WrappedObject
+ {
+ get
+ {
+ return m_WrappedObject;
+ }
+ }
+
+ private Decimal m_WrappedObject;
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/DispatchWrapper.cs b/src/mscorlib/src/System/Runtime/InteropServices/DispatchWrapper.cs
new file mode 100644
index 0000000000..1fc72f74c8
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/DispatchWrapper.cs
@@ -0,0 +1,51 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: Wrapper that is converted to a variant with VT_DISPATCH.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices {
+
+ using System;
+ using System.Security;
+ using System.Security.Permissions;
+
+ [Serializable]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class DispatchWrapper
+ {
+ [System.Security.SecuritySafeCritical] // auto-generated
+#pragma warning disable 618
+ [SecurityPermissionAttribute(SecurityAction.Demand,Flags=SecurityPermissionFlag.UnmanagedCode)]
+#pragma warning restore 618
+ public DispatchWrapper(Object obj)
+ {
+ if (obj != null)
+ {
+ // Make sure this guy has an IDispatch
+ IntPtr pdisp = Marshal.GetIDispatchForObject(obj);
+
+ // If we got here without throwing an exception, the QI for IDispatch succeeded.
+ Marshal.Release(pdisp);
+ }
+ m_WrappedObject = obj;
+ }
+
+ public Object WrappedObject
+ {
+ get
+ {
+ return m_WrappedObject;
+ }
+ }
+
+ private Object m_WrappedObject;
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ErrorWrapper.cs b/src/mscorlib/src/System/Runtime/InteropServices/ErrorWrapper.cs
new file mode 100644
index 0000000000..d63d69cabd
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ErrorWrapper.cs
@@ -0,0 +1,54 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: Wrapper that is converted to a variant with VT_ERROR.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices {
+
+ using System;
+ using System.Security.Permissions;
+
+ [Serializable]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class ErrorWrapper
+ {
+ public ErrorWrapper(int errorCode)
+ {
+ m_ErrorCode = errorCode;
+ }
+
+ public ErrorWrapper(Object errorCode)
+ {
+ if (!(errorCode is int))
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeInt32"), "errorCode");
+ m_ErrorCode = (int)errorCode;
+ }
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+#pragma warning disable 618
+ [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)]
+#pragma warning restore 618
+ public ErrorWrapper(Exception e)
+ {
+ m_ErrorCode = Marshal.GetHRForException(e);
+ }
+
+ public int ErrorCode
+ {
+ get
+ {
+ return m_ErrorCode;
+ }
+ }
+
+ private int m_ErrorCode;
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/Expando/IExpando.cs b/src/mscorlib/src/System/Runtime/InteropServices/Expando/IExpando.cs
new file mode 100644
index 0000000000..62b65d1aff
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/Expando/IExpando.cs
@@ -0,0 +1,39 @@
+// 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.
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+//
+// IExpando is an interface which allows Objects implemeningt this interface
+// support the ability to modify the object by adding and removing members,
+// represented by MemberInfo objects.
+//
+//
+// The IExpando Interface.
+namespace System.Runtime.InteropServices.Expando {
+
+ using System;
+ using System.Reflection;
+
+ [Guid("AFBF15E6-C37C-11d2-B88E-00A0C9B471B8")]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public interface IExpando : IReflect
+ {
+ // Add a new Field to the reflection object. The field has
+ // name as its name.
+ FieldInfo AddField(String name);
+
+ // Add a new Property to the reflection object. The property has
+ // name as its name.
+ PropertyInfo AddProperty(String name);
+
+ // Add a new Method to the reflection object. The method has
+ // name as its name and method is a delegate
+ // to the method.
+ MethodInfo AddMethod(String name, Delegate method);
+
+ // Removes the specified member.
+ void RemoveMember(MemberInfo m);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ExtensibleClassFactory.cs b/src/mscorlib/src/System/Runtime/InteropServices/ExtensibleClassFactory.cs
new file mode 100644
index 0000000000..62718de757
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ExtensibleClassFactory.cs
@@ -0,0 +1,41 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: Methods used to customize the creation of managed objects that
+** extend from unmanaged objects.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices {
+ using System.Runtime.InteropServices;
+ using System.Runtime.Remoting;
+ using System.Runtime.CompilerServices;
+ using System.Runtime.Versioning;
+
+ using System;
+[System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class ExtensibleClassFactory
+ {
+
+ // Prevent instantiation.
+ private ExtensibleClassFactory() {}
+
+ // Register a delegate that will be called whenever an instance of a managed
+ // type that extends from an unmanaged type needs to allocate the aggregated
+ // unmanaged object. This delegate is expected to allocate and aggregate the
+ // unmanaged object and is called in place of a CoCreateInstance. This
+ // routine must be called in the context of the static initializer for the
+ // class for which the callbacks will be made.
+ // It is not legal to register this callback from a class that has any
+ // parents that have already registered a callback.
+ [System.Security.SecuritySafeCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern void RegisterObjectCreationCallback(ObjectCreationDelegate callback);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ExternalException.cs b/src/mscorlib/src/System/Runtime/InteropServices/ExternalException.cs
new file mode 100644
index 0000000000..417cf94bd4
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ExternalException.cs
@@ -0,0 +1,80 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: Exception base class for all errors from Interop or Structured
+** Exception Handling code.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices {
+
+ using System;
+ using System.Globalization;
+ using System.Runtime.Serialization;
+ // Base exception for COM Interop errors &; Structured Exception Handler
+ // exceptions.
+ //
+ [System.Runtime.InteropServices.ComVisible(true)]
+ [Serializable]
+ public class ExternalException : SystemException {
+ public ExternalException()
+ : base(Environment.GetResourceString("Arg_ExternalException")) {
+ SetErrorCode(__HResults.E_FAIL);
+ }
+
+ public ExternalException(String message)
+ : base(message) {
+ SetErrorCode(__HResults.E_FAIL);
+ }
+
+ public ExternalException(String message, Exception inner)
+ : base(message, inner) {
+ SetErrorCode(__HResults.E_FAIL);
+ }
+
+ public ExternalException(String message,int errorCode)
+ : base(message) {
+ SetErrorCode(errorCode);
+ }
+
+ protected ExternalException(SerializationInfo info, StreamingContext context) : base(info, context) {
+ }
+
+ public virtual int ErrorCode {
+ get {
+ return HResult;
+ }
+ }
+
+#if !FEATURE_CORECLR // Breaks the subset-of-Orcas property
+ public override String ToString() {
+ String message = Message;
+ String s;
+ String _className = GetType().ToString();
+ s = _className + " (0x" + HResult.ToString("X8", CultureInfo.InvariantCulture) + ")";
+
+ if (!(String.IsNullOrEmpty(message))) {
+ s = s + ": " + message;
+ }
+
+ Exception _innerException = InnerException;
+
+ if (_innerException!=null) {
+ s = s + " ---> " + _innerException.ToString();
+ }
+
+
+ if (StackTrace != null)
+ s += Environment.NewLine + StackTrace;
+
+ return s;
+ }
+#endif // !FEATURE_CORECLR
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/GCHandleCookieTable.cs b/src/mscorlib/src/System/Runtime/InteropServices/GCHandleCookieTable.cs
new file mode 100644
index 0000000000..304f369879
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/GCHandleCookieTable.cs
@@ -0,0 +1,219 @@
+// 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.
+
+#if MDA_SUPPORTED
+
+namespace System.Runtime.InteropServices
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Threading;
+
+ using ObjectHandle = IntPtr;
+ using GCHandleCookie = IntPtr;
+
+ // Internal class used to map a GCHandle to an IntPtr. Instead of handing out the underlying CLR
+ // handle, we now hand out a cookie that can later be converted back to the CLR handle it
+ // is associated with.
+
+ // NOTE:
+ // this implementation uses a single lock between FindOrAddHandle and RemoveHandleIfPresent which
+ // could create some scalability issues when this MDA is turned on. if this is affecting perf
+ // then additional tuning work will be required.
+
+ internal class GCHandleCookieTable
+ {
+ private const int InitialHandleCount = 10;
+ private const int MaxListSize = 0xFFFFFF;
+ private const uint CookieMaskIndex = 0x00FFFFFF;
+ private const uint CookieMaskSentinal = 0xFF000000;
+
+ internal GCHandleCookieTable()
+ {
+ m_HandleList = new ObjectHandle[InitialHandleCount];
+ m_CycleCounts = new byte[InitialHandleCount];
+ m_HandleToCookieMap = new Dictionary<ObjectHandle, GCHandleCookie>(InitialHandleCount);
+ m_syncObject = new object();
+
+ for (int i = 0; i < InitialHandleCount; i++)
+ {
+ m_HandleList[i] = ObjectHandle.Zero;
+ m_CycleCounts[i] = 0;
+ }
+ }
+
+ // Retrieve a cookie for the passed in handle. If no cookie has yet been allocated for
+ // this handle, one will be created. This method is thread safe.
+ internal GCHandleCookie FindOrAddHandle(ObjectHandle handle)
+ {
+ // Don't accept a null object handle
+ if (handle == ObjectHandle.Zero)
+ return GCHandleCookie.Zero;
+
+ GCHandleCookie cookie = GCHandleCookie.Zero;
+
+ lock (m_syncObject)
+ {
+ // First see if we already have a cookie for this handle.
+ if (m_HandleToCookieMap.ContainsKey(handle))
+ return m_HandleToCookieMap[handle];
+
+ if ((m_FreeIndex < m_HandleList.Length) && (Volatile.Read(ref m_HandleList[m_FreeIndex]) == ObjectHandle.Zero))
+ {
+ Volatile.Write(ref m_HandleList[m_FreeIndex], handle);
+ cookie = GetCookieFromData((uint)m_FreeIndex, m_CycleCounts[m_FreeIndex]);
+
+ // Set our next guess just one higher as this index is now in use.
+ // it's ok if this sets m_FreeIndex > m_HandleList.Length as this condition is
+ // checked at the beginning of the if statement.
+ ++m_FreeIndex;
+ }
+ else
+ {
+ for (m_FreeIndex = 0; m_FreeIndex < MaxListSize; ++m_FreeIndex)
+ {
+ if (m_HandleList[m_FreeIndex] == ObjectHandle.Zero)
+ {
+ Volatile.Write(ref m_HandleList[m_FreeIndex], handle);
+ cookie = GetCookieFromData((uint)m_FreeIndex, m_CycleCounts[m_FreeIndex]);
+
+ // this will be our next guess for a free index.
+ // it's ok if this sets m_FreeIndex > m_HandleList.Length
+ // since we check for this condition in the if statement.
+ ++m_FreeIndex;
+ break;
+ }
+
+ if (m_FreeIndex + 1 == m_HandleList.Length)
+ GrowArrays();
+ }
+ }
+
+ if (cookie == GCHandleCookie.Zero)
+ throw new OutOfMemoryException(Environment.GetResourceString("OutOfMemory_GCHandleMDA"));
+
+ // This handle hasn't been added to the map yet so add it.
+ m_HandleToCookieMap.Add(handle, cookie);
+ }
+
+ return cookie;
+ }
+
+ // Get a handle.
+ internal ObjectHandle GetHandle(GCHandleCookie cookie)
+ {
+ ObjectHandle oh = ObjectHandle.Zero;
+
+ if (!ValidateCookie(cookie))
+ return ObjectHandle.Zero;
+
+ oh = Volatile.Read(ref m_HandleList[GetIndexFromCookie(cookie)]);
+
+ return oh;
+ }
+
+ // Remove the handle from the cookie table if it is present.
+ //
+ internal void RemoveHandleIfPresent(ObjectHandle handle)
+ {
+ if (handle == ObjectHandle.Zero)
+ return;
+
+ lock (m_syncObject)
+ {
+ if (m_HandleToCookieMap.ContainsKey(handle))
+ {
+ GCHandleCookie cookie = m_HandleToCookieMap[handle];
+
+ // Remove it from the array first
+ if (!ValidateCookie(cookie))
+ return;
+
+ int index = GetIndexFromCookie(cookie);
+
+ m_CycleCounts[index]++;
+ Volatile.Write(ref m_HandleList[index], ObjectHandle.Zero);
+
+ // Remove it from the hashtable last
+ m_HandleToCookieMap.Remove(handle);
+
+ // Update our guess
+ m_FreeIndex = index;
+ }
+ }
+ }
+
+ private bool ValidateCookie(GCHandleCookie cookie)
+ {
+ int index;
+ byte xorData;
+
+ GetDataFromCookie(cookie, out index, out xorData);
+
+ // Validate the index
+ if (index >= MaxListSize)
+ return false;
+
+ if (index >= m_HandleList.Length)
+ return false;
+
+ if (Volatile.Read(ref m_HandleList[index]) == ObjectHandle.Zero)
+ return false;
+
+ // Validate the xorData byte (this contains the cycle count and appdomain id).
+ byte ADID = (byte)(AppDomain.CurrentDomain.Id % 0xFF);
+ byte goodData = (byte)(Volatile.Read(ref m_CycleCounts[index]) ^ ADID);
+ if (xorData != goodData)
+ return false;
+
+ return true;
+ }
+
+ // Double the size of our arrays - must be called with the lock taken.
+ private void GrowArrays()
+ {
+ int CurrLength = m_HandleList.Length;
+
+ ObjectHandle[] newHandleList = new ObjectHandle[CurrLength * 2];
+ byte[] newCycleCounts = new byte[CurrLength * 2];
+
+ Array.Copy(m_HandleList, newHandleList, CurrLength);
+ Array.Copy(m_CycleCounts, newCycleCounts, CurrLength);
+
+ m_HandleList = newHandleList;
+ m_CycleCounts = newCycleCounts;
+ }
+
+ // Generate a cookie based on the index, cyclecount, and current domain id.
+ private GCHandleCookie GetCookieFromData(uint index, byte cycleCount)
+ {
+ byte ADID = (byte)(AppDomain.CurrentDomain.Id % 0xFF);
+ return (GCHandleCookie)(((cycleCount ^ ADID) << 24) + index + 1);
+ }
+
+ // Break down the cookie into its parts
+ private void GetDataFromCookie(GCHandleCookie cookie, out int index, out byte xorData)
+ {
+ uint intCookie = (uint)cookie;
+ index = (int)(intCookie & CookieMaskIndex) - 1;
+ xorData = (byte)((intCookie & CookieMaskSentinal) >> 24);
+ }
+
+ // Just get the index from the cookie
+ private int GetIndexFromCookie(GCHandleCookie cookie)
+ {
+ uint intCookie = (uint)cookie;
+ return (int)(intCookie & CookieMaskIndex) - 1;
+ }
+
+ private Dictionary<ObjectHandle, GCHandleCookie> m_HandleToCookieMap;
+ private volatile ObjectHandle[] m_HandleList;
+ private volatile byte[] m_CycleCounts;
+ private int m_FreeIndex;
+ private readonly object m_syncObject;
+ }
+}
+
+#endif
+
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/GcHandle.cs b/src/mscorlib/src/System/Runtime/InteropServices/GcHandle.cs
new file mode 100644
index 0000000000..58fea97cb8
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/GcHandle.cs
@@ -0,0 +1,330 @@
+// 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.
+
+namespace System.Runtime.InteropServices
+{
+ using System;
+ using System.Security.Permissions;
+ using System.Runtime.CompilerServices;
+ using System.Threading;
+ using System.Runtime.Versioning;
+ using System.Diagnostics.Contracts;
+
+ // These are the types of handles used by the EE.
+ // IMPORTANT: These must match the definitions in ObjectHandle.h in the EE.
+ // IMPORTANT: If new values are added to the enum the GCHandle::MaxHandleType
+ // constant must be updated.
+ [Serializable]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public enum GCHandleType
+ {
+ Weak = 0,
+ WeakTrackResurrection = 1,
+ Normal = 2,
+ Pinned = 3
+ }
+
+ // This class allows you to create an opaque, GC handle to any
+ // COM+ object. A GC handle is used when an object reference must be
+ // reachable from unmanaged memory. There are 3 kinds of roots:
+ // Normal - keeps the object from being collected.
+ // Weak - allows object to be collected and handle contents will be zeroed.
+ // Weak references are zeroed before the finalizer runs, so if the
+ // object is resurrected in the finalizer the weak reference is
+ // still zeroed.
+ // WeakTrackResurrection - Same as weak, but stays until after object is
+ // really gone.
+ // Pinned - same as normal, but allows the address of the actual object
+ // to be taken.
+ //
+
+ [StructLayout(LayoutKind.Sequential)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public struct GCHandle
+ {
+ // IMPORTANT: This must be kept in sync with the GCHandleType enum.
+ private const GCHandleType MaxHandleType = GCHandleType.Pinned;
+
+#if MDA_SUPPORTED
+ [System.Security.SecuritySafeCritical] // auto-generated
+ static GCHandle()
+ {
+ s_probeIsActive = Mda.IsInvalidGCHandleCookieProbeEnabled();
+ if (s_probeIsActive)
+ s_cookieTable = new GCHandleCookieTable();
+ }
+#endif
+
+ // Allocate a handle storing the object and the type.
+ [System.Security.SecurityCritical] // auto-generated
+ internal GCHandle(Object value, GCHandleType type)
+ {
+ // Make sure the type parameter is within the valid range for the enum.
+ if ((uint)type > (uint)MaxHandleType)
+ throw new ArgumentOutOfRangeException("type", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ Contract.EndContractBlock();
+
+ m_handle = InternalAlloc(value, type);
+
+ // Record if the handle is pinned.
+ if (type == GCHandleType.Pinned)
+ SetIsPinned();
+ }
+
+ // Used in the conversion functions below.
+ [System.Security.SecurityCritical] // auto-generated
+ internal GCHandle(IntPtr handle)
+ {
+ InternalCheckDomain(handle);
+ m_handle = handle;
+ }
+
+ // Creates a new GC handle for an object.
+ //
+ // value - The object that the GC handle is created for.
+ // type - The type of GC handle to create.
+ //
+ // returns a new GC handle that protects the object.
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static GCHandle Alloc(Object value)
+ {
+ return new GCHandle(value, GCHandleType.Normal);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static GCHandle Alloc(Object value, GCHandleType type)
+ {
+ return new GCHandle(value, type);
+ }
+
+
+ // Frees a GC handle.
+ [System.Security.SecurityCritical] // auto-generated_required
+ public void Free()
+ {
+ // Copy the handle instance member to a local variable. This is required to prevent
+ // race conditions releasing the handle.
+ IntPtr handle = m_handle;
+
+ // Free the handle if it hasn't already been freed.
+ if (handle != IntPtr.Zero && Interlocked.CompareExchange(ref m_handle, IntPtr.Zero, handle) == handle)
+ {
+#if MDA_SUPPORTED
+ // If this handle was passed out to unmanaged code, we need to remove it
+ // from the cookie table.
+ // NOTE: the entry in the cookie table must be released before the
+ // internal handle is freed to prevent a race with reusing GC handles.
+ if (s_probeIsActive)
+ s_cookieTable.RemoveHandleIfPresent(handle);
+#endif
+
+#if BIT64
+ InternalFree((IntPtr)(((long)handle) & ~1L));
+#else // BIT64 (32)
+ InternalFree((IntPtr)(((int)handle) & ~1));
+#endif
+ }
+ else
+ {
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized"));
+ }
+ }
+
+ // Target property - allows getting / updating of the handle's referent.
+ public Object Target
+ {
+ [System.Security.SecurityCritical] // auto-generated_required
+ get
+ {
+ // Check if the handle was never initialized or was freed.
+ if (m_handle == IntPtr.Zero)
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized"));
+
+ return InternalGet(GetHandleValue());
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ set
+ {
+ // Check if the handle was never initialized or was freed.
+ if (m_handle == IntPtr.Zero)
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized"));
+
+ InternalSet(GetHandleValue(), value, IsPinned());
+ }
+ }
+
+ // Retrieve the address of an object in a Pinned handle. This throws
+ // an exception if the handle is any type other than Pinned.
+ [System.Security.SecurityCritical] // auto-generated_required
+ public IntPtr AddrOfPinnedObject()
+ {
+ // Check if the handle was not a pinned handle.
+ if (!IsPinned())
+ {
+ // Check if the handle was never initialized for was freed.
+ if (m_handle == IntPtr.Zero)
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized"));
+
+ // You can only get the address of pinned handles.
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotPinned"));
+ }
+
+ // Get the address.
+ return InternalAddrOfPinnedObject(GetHandleValue());
+ }
+
+ // Determine whether this handle has been allocated or not.
+ public bool IsAllocated
+ {
+ get
+ {
+ return m_handle != IntPtr.Zero;
+ }
+ }
+
+ // Used to create a GCHandle from an int. This is intended to
+ // be used with the reverse conversion.
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static explicit operator GCHandle(IntPtr value)
+ {
+ return FromIntPtr(value);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static GCHandle FromIntPtr(IntPtr value)
+ {
+ if (value == IntPtr.Zero)
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized"));
+ Contract.EndContractBlock();
+
+ IntPtr handle = value;
+
+#if MDA_SUPPORTED
+ if (s_probeIsActive)
+ {
+ // Make sure this cookie matches up with a GCHandle we've passed out a cookie for.
+ handle = s_cookieTable.GetHandle(value);
+ if (IntPtr.Zero == handle)
+ {
+ // Fire an MDA if we were unable to retrieve the GCHandle.
+ Mda.FireInvalidGCHandleCookieProbe(value);
+ return new GCHandle(IntPtr.Zero);
+ }
+ }
+#endif
+
+ return new GCHandle(handle);
+ }
+
+ // Used to get the internal integer representation of the handle out.
+ public static explicit operator IntPtr(GCHandle value)
+ {
+ return ToIntPtr(value);
+ }
+
+ public static IntPtr ToIntPtr(GCHandle value)
+ {
+#if MDA_SUPPORTED
+ if (s_probeIsActive)
+ {
+ // Remember that we passed this GCHandle out by storing the cookie we returned so we
+ // can later validate.
+ return s_cookieTable.FindOrAddHandle(value.m_handle);
+ }
+#endif
+ return value.m_handle;
+ }
+
+ public override int GetHashCode()
+ {
+ return m_handle.GetHashCode();
+ }
+
+ public override bool Equals(Object o)
+ {
+ GCHandle hnd;
+
+ // Check that o is a GCHandle first
+ if(o == null || !(o is GCHandle))
+ return false;
+ else
+ hnd = (GCHandle) o;
+
+ return m_handle == hnd.m_handle;
+ }
+
+ public static bool operator ==(GCHandle a, GCHandle b)
+ {
+ return a.m_handle == b.m_handle;
+ }
+
+ public static bool operator !=(GCHandle a, GCHandle b)
+ {
+ return a.m_handle != b.m_handle;
+ }
+
+ internal IntPtr GetHandleValue()
+ {
+#if BIT64
+ return new IntPtr(((long)m_handle) & ~1L);
+#else // !BIT64 (32)
+ return new IntPtr(((int)m_handle) & ~1);
+#endif
+ }
+
+ internal bool IsPinned()
+ {
+#if BIT64
+ return (((long)m_handle) & 1) != 0;
+#else // !BIT64 (32)
+ return (((int)m_handle) & 1) != 0;
+#endif
+ }
+
+ internal void SetIsPinned()
+ {
+#if BIT64
+ m_handle = new IntPtr(((long)m_handle) | 1L);
+#else // !BIT64 (32)
+ m_handle = new IntPtr(((int)m_handle) | 1);
+#endif
+ }
+
+ // Internal native calls that this implementation uses.
+ [System.Security.SecurityCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern IntPtr InternalAlloc(Object value, GCHandleType type);
+ [System.Security.SecurityCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern void InternalFree(IntPtr handle);
+ [System.Security.SecurityCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern Object InternalGet(IntPtr handle);
+ [System.Security.SecurityCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern void InternalSet(IntPtr handle, Object value, bool isPinned);
+ [System.Security.SecurityCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern Object InternalCompareExchange(IntPtr handle, Object value, Object oldValue, bool isPinned);
+ [System.Security.SecurityCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern IntPtr InternalAddrOfPinnedObject(IntPtr handle);
+ [System.Security.SecurityCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern void InternalCheckDomain(IntPtr handle);
+ [System.Security.SecurityCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern GCHandleType InternalGetHandleType(IntPtr handle);
+
+ // The actual integer handle value that the EE uses internally.
+ private IntPtr m_handle;
+
+#if MDA_SUPPORTED
+ // The GCHandle cookie table.
+ static private volatile GCHandleCookieTable s_cookieTable = null;
+ static private volatile bool s_probeIsActive = false;
+#endif
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/HandleRef.cs b/src/mscorlib/src/System/Runtime/InteropServices/HandleRef.cs
new file mode 100644
index 0000000000..d76750fdd7
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/HandleRef.cs
@@ -0,0 +1,50 @@
+// 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.
+
+namespace System.Runtime.InteropServices
+{
+
+ using System;
+
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public struct HandleRef
+ {
+
+ // ! Do not add or rearrange fields as the EE depends on this layout.
+ //------------------------------------------------------------------
+ internal Object m_wrapper;
+ internal IntPtr m_handle;
+ //------------------------------------------------------------------
+
+
+ public HandleRef(Object wrapper, IntPtr handle)
+ {
+ m_wrapper = wrapper;
+ m_handle = handle;
+ }
+
+ public Object Wrapper {
+ get {
+ return m_wrapper;
+ }
+ }
+
+ public IntPtr Handle {
+ get {
+ return m_handle;
+ }
+ }
+
+
+ public static explicit operator IntPtr(HandleRef value)
+ {
+ return value.m_handle;
+ }
+
+ public static IntPtr ToIntPtr(HandleRef value)
+ {
+ return value.m_handle;
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ICustomAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/ICustomAdapter.cs
new file mode 100644
index 0000000000..00abf7b3bf
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ICustomAdapter.cs
@@ -0,0 +1,23 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: This the base interface that custom adapters can chose to implement
+** when they want to expose the underlying object.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices {
+ using System;
+
+[System.Runtime.InteropServices.ComVisible(true)]
+ public interface ICustomAdapter
+ {
+ [return:MarshalAs(UnmanagedType.IUnknown)] Object GetUnderlyingObject();
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ICustomFactory.cs b/src/mscorlib/src/System/Runtime/InteropServices/ICustomFactory.cs
new file mode 100644
index 0000000000..33d2556bd0
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ICustomFactory.cs
@@ -0,0 +1,17 @@
+// 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.
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+namespace System.Runtime.InteropServices {
+
+ using System;
+
+[System.Runtime.InteropServices.ComVisible(true)]
+ public interface ICustomFactory
+ {
+ MarshalByRefObject CreateInstance(Type serverType);
+ }
+
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ICustomMarshaler.cs b/src/mscorlib/src/System/Runtime/InteropServices/ICustomMarshaler.cs
new file mode 100644
index 0000000000..4db4acceeb
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ICustomMarshaler.cs
@@ -0,0 +1,31 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: This the base interface that must be implemented by all custom
+** marshalers.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices {
+ using System;
+
+[System.Runtime.InteropServices.ComVisible(true)]
+ public interface ICustomMarshaler
+ {
+ Object MarshalNativeToManaged( IntPtr pNativeData );
+
+ IntPtr MarshalManagedToNative( Object ManagedObj );
+
+ void CleanUpNativeData( IntPtr pNativeData );
+
+ void CleanUpManagedData( Object ManagedObj );
+
+ int GetNativeDataSize();
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ICustomQueryInterface.cs b/src/mscorlib/src/System/Runtime/InteropServices/ICustomQueryInterface.cs
new file mode 100644
index 0000000000..61688b90b4
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ICustomQueryInterface.cs
@@ -0,0 +1,39 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: This the interface that be implemented by class that want to
+** customize the behavior of QueryInterface.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices {
+ using System;
+
+ //====================================================================
+ // The enum of the return value of IQuerable.GetInterface
+ //====================================================================
+ [Serializable]
+ [System.Runtime.InteropServices.ComVisible(false)]
+ public enum CustomQueryInterfaceResult
+ {
+ Handled = 0,
+ NotHandled = 1,
+ Failed = 2,
+ }
+
+ //====================================================================
+ // The interface for customizing IQueryInterface
+ //====================================================================
+ [System.Runtime.InteropServices.ComVisible(false)]
+ public interface ICustomQueryInterface
+ {
+ [System.Security.SecurityCritical]
+ CustomQueryInterfaceResult GetInterface([In]ref Guid iid, out IntPtr ppv);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/IException.cs b/src/mscorlib/src/System/Runtime/InteropServices/IException.cs
new file mode 100644
index 0000000000..2da0a564a2
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/IException.cs
@@ -0,0 +1,84 @@
+// 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.
+
+/*=============================================================================
+**
+** Interface: _Exception
+**
+**
+** Purpose: COM backwards compatibility with v1 Exception
+** object layout.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices {
+ using System;
+ using System.Reflection;
+ using System.Runtime.Serialization;
+ using System.Security.Permissions;
+
+ [GuidAttribute("b36b5c63-42ef-38bc-a07e-0b34c98f164a")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsDual)]
+ [CLSCompliant(false)]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public interface _Exception
+ {
+#if !FEATURE_CORECLR
+ // This contains all of our V1 Exception class's members.
+
+ // From Object
+ String ToString();
+ bool Equals (Object obj);
+ int GetHashCode ();
+ Type GetType ();
+
+ // From V1's Exception class
+ String Message {
+ get;
+ }
+
+ Exception GetBaseException();
+
+ String StackTrace {
+ get;
+ }
+
+ String HelpLink {
+ get;
+ set;
+ }
+
+ String Source {
+ #if FEATURE_CORECLR
+ [System.Security.SecurityCritical] // auto-generated
+ #endif
+ get;
+ #if FEATURE_CORECLR
+ [System.Security.SecurityCritical] // auto-generated
+ #endif
+ set;
+ }
+ [System.Security.SecurityCritical] // auto-generated_required
+ void GetObjectData(SerializationInfo info, StreamingContext context);
+#endif
+
+ //
+ // This method is intentionally included in CoreCLR to make Exception.get_InnerException "newslot virtual final".
+ // Some phone apps include MEF from desktop Silverlight. MEF's ComposablePartException depends on implicit interface
+ // implementations of get_InnerException to be provided by the base class. It works only if Exception.get_InnerException
+ // is virtual.
+ //
+ Exception InnerException {
+ get;
+ }
+
+#if !FEATURE_CORECLR
+ MethodBase TargetSite {
+ get;
+ }
+#endif
+ }
+
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/IRegistrationServices.cs b/src/mscorlib/src/System/Runtime/InteropServices/IRegistrationServices.cs
new file mode 100644
index 0000000000..ae330e8652
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/IRegistrationServices.cs
@@ -0,0 +1,56 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: This interface provides services for registering and unregistering
+** a managed server for use by COM.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices {
+
+ using System;
+ using System.Reflection;
+ using System.Security;
+ using System.Security.Permissions;
+
+ [Flags()]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public enum AssemblyRegistrationFlags
+ {
+ None = 0x00000000,
+ SetCodeBase = 0x00000001,
+ }
+
+ [Guid("CCBD682C-73A5-4568-B8B0-C7007E11ABA2")]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public interface IRegistrationServices
+ {
+ [System.Security.SecurityCritical] // auto-generated_required
+ bool RegisterAssembly(Assembly assembly, AssemblyRegistrationFlags flags);
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ bool UnregisterAssembly(Assembly assembly);
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ Type[] GetRegistrableTypesInAssembly(Assembly assembly);
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ String GetProgIdForType(Type type);
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ void RegisterTypeForComClients(Type type, ref Guid g);
+
+ Guid GetManagedCategoryGuid();
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ bool TypeRequiresRegistration(Type type);
+
+ bool TypeRepresentsComType(Type type);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ITypeLibConverter.cs b/src/mscorlib/src/System/Runtime/InteropServices/ITypeLibConverter.cs
new file mode 100644
index 0000000000..a7b6889c55
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ITypeLibConverter.cs
@@ -0,0 +1,146 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: Methods used to convert a TypeLib to metadata and vice versa.
+**
+**
+=============================================================================*/
+
+// ***************************************************************************
+// *** Note: The following definitions must remain synchronized with the IDL
+// *** in src/inc/TlbImpExp.idl.
+// ***************************************************************************
+
+namespace System.Runtime.InteropServices {
+
+ using System;
+ using System.Reflection;
+ using System.Reflection.Emit;
+
+[Serializable]
+[Flags()]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public enum TypeLibImporterFlags
+ {
+ None = 0x00000000,
+ PrimaryInteropAssembly = 0x00000001,
+ UnsafeInterfaces = 0x00000002,
+ SafeArrayAsSystemArray = 0x00000004,
+ TransformDispRetVals = 0x00000008,
+ PreventClassMembers = 0x00000010,
+ SerializableValueClasses = 0x00000020,
+ ImportAsX86 = 0x00000100,
+ ImportAsX64 = 0x00000200,
+ ImportAsItanium = 0x00000400,
+ ImportAsAgnostic = 0x00000800,
+ ReflectionOnlyLoading = 0x00001000,
+ NoDefineVersionResource = 0x00002000,
+ ImportAsArm = 0x00004000,
+ }
+
+[Serializable]
+[Flags()]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public enum TypeLibExporterFlags
+ {
+ None = 0x00000000,
+ OnlyReferenceRegistered = 0x00000001,
+ CallerResolvedReferences = 0x00000002,
+ OldNames = 0x00000004,
+ ExportAs32Bit = 0x00000010,
+ ExportAs64Bit = 0x00000020,
+ }
+
+ [Serializable]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public enum ImporterEventKind
+ {
+ NOTIF_TYPECONVERTED = 0,
+ NOTIF_CONVERTWARNING = 1,
+ ERROR_REFTOINVALIDTYPELIB = 2,
+ }
+
+ [Serializable]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public enum ExporterEventKind
+ {
+ NOTIF_TYPECONVERTED = 0,
+ NOTIF_CONVERTWARNING = 1,
+ ERROR_REFTOINVALIDASSEMBLY = 2
+ }
+
+ [GuidAttribute("F1C3BF76-C3E4-11d3-88E7-00902754C43A")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public interface ITypeLibImporterNotifySink
+ {
+ void ReportEvent(
+ ImporterEventKind eventKind,
+ int eventCode,
+ String eventMsg);
+ Assembly ResolveRef(
+ [MarshalAs(UnmanagedType.Interface)] Object typeLib);
+ }
+
+ [GuidAttribute("F1C3BF77-C3E4-11d3-88E7-00902754C43A")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public interface ITypeLibExporterNotifySink
+ {
+ void ReportEvent(
+ ExporterEventKind eventKind,
+ int eventCode,
+ String eventMsg);
+
+ [return : MarshalAs(UnmanagedType.Interface)]
+ Object ResolveRef(
+ Assembly assembly);
+ }
+
+ [GuidAttribute("F1C3BF78-C3E4-11d3-88E7-00902754C43A")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public interface ITypeLibConverter
+ {
+ AssemblyBuilder ConvertTypeLibToAssembly(
+ [MarshalAs(UnmanagedType.Interface)] Object typeLib,
+ String asmFileName,
+ TypeLibImporterFlags flags,
+ ITypeLibImporterNotifySink notifySink,
+ byte[] publicKey,
+ StrongNameKeyPair keyPair,
+ String asmNamespace,
+ Version asmVersion);
+
+ [return : MarshalAs(UnmanagedType.Interface)]
+ Object ConvertAssemblyToTypeLib(
+ Assembly assembly,
+ String typeLibName,
+ TypeLibExporterFlags flags,
+ ITypeLibExporterNotifySink notifySink);
+
+ bool GetPrimaryInteropAssembly(Guid g, Int32 major, Int32 minor, Int32 lcid, out String asmName, out String asmCodeBase);
+
+ AssemblyBuilder ConvertTypeLibToAssembly([MarshalAs(UnmanagedType.Interface)] Object typeLib,
+ String asmFileName,
+ int flags,
+ ITypeLibImporterNotifySink notifySink,
+ byte[] publicKey,
+ StrongNameKeyPair keyPair,
+ bool unsafeInterfaces);
+ }
+
+ [GuidAttribute("FA1F3615-ACB9-486d-9EAC-1BEF87E36B09")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public interface ITypeLibExporterNameProvider
+ {
+ [return : MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VarEnum.VT_BSTR)]
+ String[] GetNames();
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/InvalidComObjectException.cs b/src/mscorlib/src/System/Runtime/InteropServices/InvalidComObjectException.cs
new file mode 100644
index 0000000000..ac8258b872
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/InvalidComObjectException.cs
@@ -0,0 +1,40 @@
+// 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.
+
+/*=============================================================================
+**
+**
+** Purpose: This exception is thrown when an invalid COM object is used. This
+** happens when a the __ComObject type is used directly without
+** having a backing class factory.
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices {
+
+ using System;
+ using System.Runtime.Serialization;
+
+ [System.Runtime.InteropServices.ComVisible(true)]
+ [Serializable]
+ public class InvalidComObjectException : SystemException {
+ public InvalidComObjectException()
+ : base(Environment.GetResourceString("Arg_InvalidComObjectException")) {
+ SetErrorCode(__HResults.COR_E_INVALIDCOMOBJECT);
+ }
+
+ public InvalidComObjectException(String message)
+ : base(message) {
+ SetErrorCode(__HResults.COR_E_INVALIDCOMOBJECT);
+ }
+
+ public InvalidComObjectException(String message, Exception inner)
+ : base(message, inner) {
+ SetErrorCode(__HResults.COR_E_INVALIDCOMOBJECT);
+ }
+
+ protected InvalidComObjectException(SerializationInfo info, StreamingContext context) : base(info, context) {
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/InvalidOleVariantTypeException.cs b/src/mscorlib/src/System/Runtime/InteropServices/InvalidOleVariantTypeException.cs
new file mode 100644
index 0000000000..60c9aa67b4
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/InvalidOleVariantTypeException.cs
@@ -0,0 +1,39 @@
+// 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.
+
+/*=============================================================================
+**
+**
+** Purpose: The type of an OLE variant that was passed into the runtime is
+** invalid.
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices {
+
+ using System;
+ using System.Runtime.Serialization;
+
+ [System.Runtime.InteropServices.ComVisible(true)]
+ [Serializable]
+ public class InvalidOleVariantTypeException : SystemException {
+ public InvalidOleVariantTypeException()
+ : base(Environment.GetResourceString("Arg_InvalidOleVariantTypeException")) {
+ SetErrorCode(__HResults.COR_E_INVALIDOLEVARIANTTYPE);
+ }
+
+ public InvalidOleVariantTypeException(String message)
+ : base(message) {
+ SetErrorCode(__HResults.COR_E_INVALIDOLEVARIANTTYPE);
+ }
+
+ public InvalidOleVariantTypeException(String message, Exception inner)
+ : base(message, inner) {
+ SetErrorCode(__HResults.COR_E_INVALIDOLEVARIANTTYPE);
+ }
+
+ protected InvalidOleVariantTypeException(SerializationInfo info, StreamingContext context) : base(info, context) {
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/LayoutKind.cs b/src/mscorlib/src/System/Runtime/InteropServices/LayoutKind.cs
new file mode 100644
index 0000000000..231779872e
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/LayoutKind.cs
@@ -0,0 +1,18 @@
+// 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.
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+namespace System.Runtime.InteropServices {
+ using System;
+ // Used in the StructLayoutAttribute class
+ [System.Runtime.InteropServices.ComVisible(true)]
+ [Serializable]
+ public enum LayoutKind
+ {
+ Sequential = 0, // 0x00000008,
+ Explicit = 2, // 0x00000010,
+ Auto = 3, // 0x00000000,
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/Marshal.cs b/src/mscorlib/src/System/Runtime/InteropServices/Marshal.cs
new file mode 100644
index 0000000000..86e88306f0
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/Marshal.cs
@@ -0,0 +1,2806 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: This class contains methods that are mainly used to marshal
+** between unmanaged and managed types.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Reflection;
+ using System.Reflection.Emit;
+ using System.Security;
+ using System.Security.Permissions;
+ using System.Text;
+ using System.Threading;
+ using System.Runtime.Remoting;
+ using System.Runtime.CompilerServices;
+ using System.Globalization;
+ using System.Runtime.ConstrainedExecution;
+ using System.Runtime.Versioning;
+ using Win32Native = Microsoft.Win32.Win32Native;
+ using Microsoft.Win32.SafeHandles;
+ using System.Diagnostics.Contracts;
+ using System.Runtime.InteropServices.ComTypes;
+
+ [Serializable]
+ public enum CustomQueryInterfaceMode
+ {
+ Ignore = 0,
+ Allow = 1
+ }
+
+ //========================================================================
+ // All public methods, including PInvoke, are protected with linkchecks.
+ // Remove the default demands for all PInvoke methods with this global
+ // declaration on the class.
+ //========================================================================
+
+ #if FEATURE_CORECLR
+ [System.Security.SecurityCritical] // auto-generated
+ #endif
+ public static partial class Marshal
+ {
+ //====================================================================
+ // Defines used inside the Marshal class.
+ //====================================================================
+ private const int LMEM_FIXED = 0;
+ private const int LMEM_MOVEABLE = 2;
+#if !FEATURE_PAL
+ private const long HIWORDMASK = unchecked((long)0xffffffffffff0000L);
+#endif //!FEATURE_PAL
+#if FEATURE_COMINTEROP
+ private static Guid IID_IUnknown = new Guid("00000000-0000-0000-C000-000000000046");
+#endif //FEATURE_COMINTEROP
+
+ // Win32 has the concept of Atoms, where a pointer can either be a pointer
+ // or an int. If it's less than 64K, this is guaranteed to NOT be a
+ // pointer since the bottom 64K bytes are reserved in a process' page table.
+ // We should be careful about deallocating this stuff. Extracted to
+ // a function to avoid C# problems with lack of support for IntPtr.
+ // We have 2 of these methods for slightly different semantics for NULL.
+ private static bool IsWin32Atom(IntPtr ptr)
+ {
+#if FEATURE_PAL
+ return false;
+#else
+ long lPtr = (long)ptr;
+ return 0 == (lPtr & HIWORDMASK);
+#endif
+ }
+
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ private static bool IsNotWin32Atom(IntPtr ptr)
+ {
+#if FEATURE_PAL
+ return true;
+#else
+ long lPtr = (long)ptr;
+ return 0 != (lPtr & HIWORDMASK);
+#endif
+ }
+
+ //====================================================================
+ // The default character size for the system. This is always 2 because
+ // the framework only runs on UTF-16 systems.
+ //====================================================================
+ public static readonly int SystemDefaultCharSize = 2;
+
+ //====================================================================
+ // The max DBCS character size for the system.
+ //====================================================================
+ public static readonly int SystemMaxDBCSCharSize = GetSystemMaxDBCSCharSize();
+
+
+ //====================================================================
+ // The name, title and description of the assembly that will contain
+ // the dynamically generated interop types.
+ //====================================================================
+ private const String s_strConvertedTypeInfoAssemblyName = "InteropDynamicTypes";
+ private const String s_strConvertedTypeInfoAssemblyTitle = "Interop Dynamic Types";
+ private const String s_strConvertedTypeInfoAssemblyDesc = "Type dynamically generated from ITypeInfo's";
+ private const String s_strConvertedTypeInfoNameSpace = "InteropDynamicTypes";
+
+
+ //====================================================================
+ // Helper method to retrieve the system's maximum DBCS character size.
+ //====================================================================
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern int GetSystemMaxDBCSCharSize();
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ unsafe public static String PtrToStringAnsi(IntPtr ptr)
+ {
+ if (IntPtr.Zero == ptr) {
+ return null;
+ }
+ else if (IsWin32Atom(ptr)) {
+ return null;
+ }
+ else {
+ int nb = Win32Native.lstrlenA(ptr);
+ if( nb == 0) {
+ return string.Empty;
+ }
+ else {
+ return new String((sbyte *)ptr);
+ }
+ }
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ unsafe public static String PtrToStringAnsi(IntPtr ptr, int len)
+ {
+ if (ptr == IntPtr.Zero)
+ throw new ArgumentNullException("ptr");
+ if (len < 0)
+ throw new ArgumentException("len");
+
+ return new String((sbyte *)ptr, 0, len);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ unsafe public static String PtrToStringUni(IntPtr ptr, int len)
+ {
+ if (ptr == IntPtr.Zero)
+ throw new ArgumentNullException("ptr");
+ if (len < 0)
+ throw new ArgumentException("len");
+
+ return new String((char *)ptr, 0, len);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static String PtrToStringAuto(IntPtr ptr, int len)
+ {
+ // Ansi platforms are no longer supported
+ return PtrToStringUni(ptr, len);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ unsafe public static String PtrToStringUni(IntPtr ptr)
+ {
+ if (IntPtr.Zero == ptr) {
+ return null;
+ }
+ else if (IsWin32Atom(ptr)) {
+ return null;
+ }
+ else {
+ return new String((char *)ptr);
+ }
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static String PtrToStringAuto(IntPtr ptr)
+ {
+ // Ansi platforms are no longer supported
+ return PtrToStringUni(ptr);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ unsafe public static String PtrToStringUTF8(IntPtr ptr)
+ {
+ int nbBytes = System.StubHelpers.StubHelpers.strlen((sbyte*)ptr.ToPointer());
+ return PtrToStringUTF8(ptr, nbBytes);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ unsafe public static String PtrToStringUTF8(IntPtr ptr,int byteLen)
+ {
+ if (byteLen < 0)
+ {
+ throw new ArgumentException("byteLen");
+ }
+ else if (IntPtr.Zero == ptr)
+ {
+ return null;
+ }
+ else if (IsWin32Atom(ptr))
+ {
+ return null;
+ }
+ else if (byteLen == 0)
+ {
+ return string.Empty;
+ }
+ else
+ {
+ byte* pByte = (byte*)ptr.ToPointer();
+ return Encoding.UTF8.GetString(pByte, byteLen);
+ }
+ }
+
+ //====================================================================
+ // SizeOf()
+ //====================================================================
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public static int SizeOf(Object structure)
+ {
+ if (structure == null)
+ throw new ArgumentNullException("structure");
+ // we never had a check for generics here
+ Contract.EndContractBlock();
+
+ return SizeOfHelper(structure.GetType(), true);
+ }
+
+ public static int SizeOf<T>(T structure)
+ {
+ return SizeOf((object)structure);
+ }
+
+ [Pure]
+ public static int SizeOf(Type t)
+ {
+ if (t == null)
+ throw new ArgumentNullException("t");
+ if (!(t is RuntimeType))
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "t");
+ if (t.IsGenericType)
+ throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), "t");
+ Contract.EndContractBlock();
+
+ return SizeOfHelper(t, true);
+ }
+
+ public static int SizeOf<T>()
+ {
+ return SizeOf(typeof(T));
+ }
+
+ /// <summary>
+ /// Returns the aligned size of an instance of a value type.
+ /// </summary>
+ /// <typeparam name="T">Provide a value type to figure out its size</typeparam>
+ /// <returns>The aligned size of T in bytes.</returns>
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
+ internal static uint AlignedSizeOf<T>() where T : struct
+ {
+ uint size = SizeOfType(typeof(T));
+ if (size == 1 || size == 2)
+ {
+ return size;
+ }
+ if (IntPtr.Size == 8 && size == 4)
+ {
+ return size;
+ }
+ return AlignedSizeOfType(typeof(T));
+ }
+
+ // Type must be a value type with no object reference fields. We only
+ // assert this, due to the lack of a suitable generic constraint.
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ internal static extern uint SizeOfType(Type type);
+
+ // Type must be a value type with no object reference fields. We only
+ // assert this, due to the lack of a suitable generic constraint.
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ private static extern uint AlignedSizeOfType(Type type);
+
+#if !FEATURE_CORECLR // Marshal is critical in CoreCLR, so SafeCritical members trigger Annotator violations
+ [System.Security.SecuritySafeCritical]
+#endif // !FEATURE_CORECLR
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern int SizeOfHelper(Type t, bool throwIfNotMarshalable);
+
+ //====================================================================
+ // OffsetOf()
+ //====================================================================
+ public static IntPtr OffsetOf(Type t, String fieldName)
+ {
+ if (t == null)
+ throw new ArgumentNullException("t");
+ Contract.EndContractBlock();
+
+ FieldInfo f = t.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
+ if (f == null)
+ throw new ArgumentException(Environment.GetResourceString("Argument_OffsetOfFieldNotFound", t.FullName), "fieldName");
+ RtFieldInfo rtField = f as RtFieldInfo;
+ if (rtField == null)
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeFieldInfo"), "fieldName");
+
+ return OffsetOfHelper(rtField);
+ }
+ public static IntPtr OffsetOf<T>(string fieldName)
+ {
+ return OffsetOf(typeof(T), fieldName);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern IntPtr OffsetOfHelper(IRuntimeFieldInfo f);
+
+ //====================================================================
+ // UnsafeAddrOfPinnedArrayElement()
+ //
+ // IMPORTANT NOTICE: This method does not do any verification on the
+ // array. It must be used with EXTREME CAUTION since passing in
+ // an array that is not pinned or in the fixed heap can cause
+ // unexpected results !
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern IntPtr UnsafeAddrOfPinnedArrayElement(Array arr, int index);
+
+ [System.Security.SecurityCritical]
+ public static IntPtr UnsafeAddrOfPinnedArrayElement<T>(T[] arr, int index)
+ {
+ return UnsafeAddrOfPinnedArrayElement((Array)arr, index);
+ }
+
+ //====================================================================
+ // Copy blocks from CLR arrays to native memory.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void Copy(int[] source, int startIndex, IntPtr destination, int length)
+ {
+ CopyToNative(source, startIndex, destination, length);
+ }
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void Copy(char[] source, int startIndex, IntPtr destination, int length)
+ {
+ CopyToNative(source, startIndex, destination, length);
+ }
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void Copy(short[] source, int startIndex, IntPtr destination, int length)
+ {
+ CopyToNative(source, startIndex, destination, length);
+ }
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void Copy(long[] source, int startIndex, IntPtr destination, int length)
+ {
+ CopyToNative(source, startIndex, destination, length);
+ }
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void Copy(float[] source, int startIndex, IntPtr destination, int length)
+ {
+ CopyToNative(source, startIndex, destination, length);
+ }
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void Copy(double[] source, int startIndex, IntPtr destination, int length)
+ {
+ CopyToNative(source, startIndex, destination, length);
+ }
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void Copy(byte[] source, int startIndex, IntPtr destination, int length)
+ {
+ CopyToNative(source, startIndex, destination, length);
+ }
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void Copy(IntPtr[] source, int startIndex, IntPtr destination, int length)
+ {
+ CopyToNative(source, startIndex, destination, length);
+ }
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern void CopyToNative(Object source, int startIndex, IntPtr destination, int length);
+
+ //====================================================================
+ // Copy blocks from native memory to CLR arrays
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void Copy(IntPtr source, int[] destination, int startIndex, int length)
+ {
+ CopyToManaged(source, destination, startIndex, length);
+ }
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void Copy(IntPtr source, char[] destination, int startIndex, int length)
+ {
+ CopyToManaged(source, destination, startIndex, length);
+ }
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void Copy(IntPtr source, short[] destination, int startIndex, int length)
+ {
+ CopyToManaged(source, destination, startIndex, length);
+ }
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void Copy(IntPtr source, long[] destination, int startIndex, int length)
+ {
+ CopyToManaged(source, destination, startIndex, length);
+ }
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void Copy(IntPtr source, float[] destination, int startIndex, int length)
+ {
+ CopyToManaged(source, destination, startIndex, length);
+ }
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void Copy(IntPtr source, double[] destination, int startIndex, int length)
+ {
+ CopyToManaged(source, destination, startIndex, length);
+ }
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void Copy(IntPtr source, byte[] destination, int startIndex, int length)
+ {
+ CopyToManaged(source, destination, startIndex, length);
+ }
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void Copy(IntPtr source, IntPtr[] destination, int startIndex, int length)
+ {
+ CopyToManaged(source, destination, startIndex, length);
+ }
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern void CopyToManaged(IntPtr source, Object destination, int startIndex, int length);
+
+ //====================================================================
+ // Read from memory
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated
+#if !FEATURE_CORECLR
+ [DllImport(Win32Native.SHIM, EntryPoint="ND_RU1")]
+ [SuppressUnmanagedCodeSecurity]
+ public static extern byte ReadByte([MarshalAs(UnmanagedType.AsAny), In] Object ptr, int ofs);
+#else
+ public static byte ReadByte([MarshalAs(UnmanagedType.AsAny), In] Object ptr, int ofs)
+ {
+ throw new PlatformNotSupportedException();
+ }
+#endif // !FEATURE_CORECLR
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static unsafe byte ReadByte(IntPtr ptr, int ofs)
+ {
+ try
+ {
+ byte *addr = (byte *)ptr + ofs;
+ return *addr;
+ }
+ catch (NullReferenceException)
+ {
+ // this method is documented to throw AccessViolationException on any AV
+ throw new AccessViolationException();
+ }
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static byte ReadByte(IntPtr ptr)
+ {
+ return ReadByte(ptr,0);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+#if !FEATURE_CORECLR
+ [DllImport(Win32Native.SHIM, EntryPoint="ND_RI2")]
+ [SuppressUnmanagedCodeSecurity]
+ public static extern short ReadInt16([MarshalAs(UnmanagedType.AsAny),In] Object ptr, int ofs);
+#else
+ public static short ReadInt16([MarshalAs(UnmanagedType.AsAny),In] Object ptr, int ofs)
+ {
+ throw new PlatformNotSupportedException();
+ }
+#endif // !FEATURE_CORECLR
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static unsafe short ReadInt16(IntPtr ptr, int ofs)
+ {
+ try
+ {
+ byte *addr = (byte *)ptr + ofs;
+ if ((unchecked((int)addr) & 0x1) == 0)
+ {
+ // aligned read
+ return *((short *)addr);
+ }
+ else
+ {
+ // unaligned read
+ short val;
+ byte *valPtr = (byte *)&val;
+ valPtr[0] = addr[0];
+ valPtr[1] = addr[1];
+ return val;
+ }
+ }
+ catch (NullReferenceException)
+ {
+ // this method is documented to throw AccessViolationException on any AV
+ throw new AccessViolationException();
+ }
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static short ReadInt16(IntPtr ptr)
+ {
+ return ReadInt16(ptr, 0);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+#if !FEATURE_CORECLR
+ [DllImport(Win32Native.SHIM, EntryPoint="ND_RI4"), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ [SuppressUnmanagedCodeSecurity]
+ public static extern int ReadInt32([MarshalAs(UnmanagedType.AsAny),In] Object ptr, int ofs);
+#else
+ public static int ReadInt32([MarshalAs(UnmanagedType.AsAny),In] Object ptr, int ofs)
+ {
+ throw new PlatformNotSupportedException();
+ }
+#endif // !FEATURE_CORECLR
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ public static unsafe int ReadInt32(IntPtr ptr, int ofs)
+ {
+ try
+ {
+ byte *addr = (byte *)ptr + ofs;
+ if ((unchecked((int)addr) & 0x3) == 0)
+ {
+ // aligned read
+ return *((int *)addr);
+ }
+ else
+ {
+ // unaligned read
+ int val;
+ byte *valPtr = (byte *)&val;
+ valPtr[0] = addr[0];
+ valPtr[1] = addr[1];
+ valPtr[2] = addr[2];
+ valPtr[3] = addr[3];
+ return val;
+ }
+ }
+ catch (NullReferenceException)
+ {
+ // this method is documented to throw AccessViolationException on any AV
+ throw new AccessViolationException();
+ }
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ public static int ReadInt32(IntPtr ptr)
+ {
+ return ReadInt32(ptr,0);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ public static IntPtr ReadIntPtr([MarshalAs(UnmanagedType.AsAny),In] Object ptr, int ofs)
+ {
+ #if BIT64
+ return (IntPtr) ReadInt64(ptr, ofs);
+ #else // 32
+ return (IntPtr) ReadInt32(ptr, ofs);
+ #endif
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ public static IntPtr ReadIntPtr(IntPtr ptr, int ofs)
+ {
+ #if BIT64
+ return (IntPtr) ReadInt64(ptr, ofs);
+ #else // 32
+ return (IntPtr) ReadInt32(ptr, ofs);
+ #endif
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ public static IntPtr ReadIntPtr(IntPtr ptr)
+ {
+ #if BIT64
+ return (IntPtr) ReadInt64(ptr, 0);
+ #else // 32
+ return (IntPtr) ReadInt32(ptr, 0);
+ #endif
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+#if !FEATURE_CORECLR
+ [DllImport(Win32Native.SHIM, EntryPoint="ND_RI8"), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ [SuppressUnmanagedCodeSecurity]
+ public static extern long ReadInt64([MarshalAs(UnmanagedType.AsAny),In] Object ptr, int ofs);
+#else
+ public static long ReadInt64([MarshalAs(UnmanagedType.AsAny),In] Object ptr, int ofs)
+ {
+ throw new PlatformNotSupportedException();
+ }
+#endif // !FEATURE_CORECLR
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static unsafe long ReadInt64(IntPtr ptr, int ofs)
+ {
+ try
+ {
+ byte *addr = (byte *)ptr + ofs;
+ if ((unchecked((int)addr) & 0x7) == 0)
+ {
+ // aligned read
+ return *((long *)addr);
+ }
+ else
+ {
+ // unaligned read
+ long val;
+ byte *valPtr = (byte *)&val;
+ valPtr[0] = addr[0];
+ valPtr[1] = addr[1];
+ valPtr[2] = addr[2];
+ valPtr[3] = addr[3];
+ valPtr[4] = addr[4];
+ valPtr[5] = addr[5];
+ valPtr[6] = addr[6];
+ valPtr[7] = addr[7];
+ return val;
+ }
+ }
+ catch (NullReferenceException)
+ {
+ // this method is documented to throw AccessViolationException on any AV
+ throw new AccessViolationException();
+ }
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ public static long ReadInt64(IntPtr ptr)
+ {
+ return ReadInt64(ptr,0);
+ }
+
+
+ //====================================================================
+ // Write to memory
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static unsafe void WriteByte(IntPtr ptr, int ofs, byte val)
+ {
+ try
+ {
+ byte *addr = (byte *)ptr + ofs;
+ *addr = val;
+ }
+ catch (NullReferenceException)
+ {
+ // this method is documented to throw AccessViolationException on any AV
+ throw new AccessViolationException();
+ }
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+#if !FEATURE_CORECLR
+ [DllImport(Win32Native.SHIM, EntryPoint="ND_WU1")]
+ [SuppressUnmanagedCodeSecurity]
+ public static extern void WriteByte([MarshalAs(UnmanagedType.AsAny),In,Out] Object ptr, int ofs, byte val);
+#else
+ public static void WriteByte([MarshalAs(UnmanagedType.AsAny),In,Out] Object ptr, int ofs, byte val)
+ {
+ throw new PlatformNotSupportedException();
+ }
+#endif // !FEATURE_CORECLR
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void WriteByte(IntPtr ptr, byte val)
+ {
+ WriteByte(ptr, 0, val);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static unsafe void WriteInt16(IntPtr ptr, int ofs, short val)
+ {
+ try
+ {
+ byte *addr = (byte *)ptr + ofs;
+ if ((unchecked((int)addr) & 0x1) == 0)
+ {
+ // aligned write
+ *((short *)addr) = val;
+ }
+ else
+ {
+ // unaligned write
+ byte *valPtr = (byte *)&val;
+ addr[0] = valPtr[0];
+ addr[1] = valPtr[1];
+ }
+ }
+ catch (NullReferenceException)
+ {
+ // this method is documented to throw AccessViolationException on any AV
+ throw new AccessViolationException();
+ }
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+#if !FEATURE_CORECLR
+ [DllImport(Win32Native.SHIM, EntryPoint="ND_WI2")]
+ [SuppressUnmanagedCodeSecurity]
+ public static extern void WriteInt16([MarshalAs(UnmanagedType.AsAny),In,Out] Object ptr, int ofs, short val);
+#else
+ public static void WriteInt16([MarshalAs(UnmanagedType.AsAny),In,Out] Object ptr, int ofs, short val)
+ {
+ throw new PlatformNotSupportedException();
+ }
+#endif // !FEATURE_CORECLR
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void WriteInt16(IntPtr ptr, short val)
+ {
+ WriteInt16(ptr, 0, val);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void WriteInt16(IntPtr ptr, int ofs, char val)
+ {
+ WriteInt16(ptr, ofs, (short)val);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void WriteInt16([In,Out]Object ptr, int ofs, char val)
+ {
+ WriteInt16(ptr, ofs, (short)val);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void WriteInt16(IntPtr ptr, char val)
+ {
+ WriteInt16(ptr, 0, (short)val);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static unsafe void WriteInt32(IntPtr ptr, int ofs, int val)
+ {
+ try
+ {
+ byte *addr = (byte *)ptr + ofs;
+ if ((unchecked((int)addr) & 0x3) == 0)
+ {
+ // aligned write
+ *((int *)addr) = val;
+ }
+ else
+ {
+ // unaligned write
+ byte *valPtr = (byte *)&val;
+ addr[0] = valPtr[0];
+ addr[1] = valPtr[1];
+ addr[2] = valPtr[2];
+ addr[3] = valPtr[3];
+ }
+ }
+ catch (NullReferenceException)
+ {
+ // this method is documented to throw AccessViolationException on any AV
+ throw new AccessViolationException();
+ }
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+#if !FEATURE_CORECLR
+ [DllImport(Win32Native.SHIM, EntryPoint="ND_WI4")]
+ [SuppressUnmanagedCodeSecurity]
+ public static extern void WriteInt32([MarshalAs(UnmanagedType.AsAny),In,Out] Object ptr, int ofs, int val);
+#else
+ public static void WriteInt32([MarshalAs(UnmanagedType.AsAny),In,Out] Object ptr, int ofs, int val)
+ {
+ throw new PlatformNotSupportedException();
+ }
+#endif // !FEATURE_CORECLR
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void WriteInt32(IntPtr ptr, int val)
+ {
+ WriteInt32(ptr,0,val);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void WriteIntPtr(IntPtr ptr, int ofs, IntPtr val)
+ {
+ #if BIT64
+ WriteInt64(ptr, ofs, (long)val);
+ #else // 32
+ WriteInt32(ptr, ofs, (int)val);
+ #endif
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void WriteIntPtr([MarshalAs(UnmanagedType.AsAny),In,Out] Object ptr, int ofs, IntPtr val)
+ {
+ #if BIT64
+ WriteInt64(ptr, ofs, (long)val);
+ #else // 32
+ WriteInt32(ptr, ofs, (int)val);
+ #endif
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void WriteIntPtr(IntPtr ptr, IntPtr val)
+ {
+ #if BIT64
+ WriteInt64(ptr, 0, (long)val);
+ #else // 32
+ WriteInt32(ptr, 0, (int)val);
+ #endif
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static unsafe void WriteInt64(IntPtr ptr, int ofs, long val)
+ {
+ try
+ {
+ byte *addr = (byte *)ptr + ofs;
+ if ((unchecked((int)addr) & 0x7) == 0)
+ {
+ // aligned write
+ *((long *)addr) = val;
+ }
+ else
+ {
+ // unaligned write
+ byte *valPtr = (byte *)&val;
+ addr[0] = valPtr[0];
+ addr[1] = valPtr[1];
+ addr[2] = valPtr[2];
+ addr[3] = valPtr[3];
+ addr[4] = valPtr[4];
+ addr[5] = valPtr[5];
+ addr[6] = valPtr[6];
+ addr[7] = valPtr[7];
+ }
+ }
+ catch (NullReferenceException)
+ {
+ // this method is documented to throw AccessViolationException on any AV
+ throw new AccessViolationException();
+ }
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+#if !FEATURE_CORECLR
+ [DllImport(Win32Native.SHIM, EntryPoint="ND_WI8")]
+ [SuppressUnmanagedCodeSecurity]
+ public static extern void WriteInt64([MarshalAs(UnmanagedType.AsAny),In,Out] Object ptr, int ofs, long val);
+#else
+ public static void WriteInt64([MarshalAs(UnmanagedType.AsAny),In,Out] Object ptr, int ofs, long val)
+ {
+ throw new PlatformNotSupportedException();
+ }
+#endif // !FEATURE_CORECLR
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void WriteInt64(IntPtr ptr, long val)
+ {
+ WriteInt64(ptr, 0, val);
+ }
+
+
+ //====================================================================
+ // GetLastWin32Error
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ public static extern int GetLastWin32Error();
+
+
+ //====================================================================
+ // SetLastWin32Error
+ //====================================================================
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ internal static extern void SetLastWin32Error(int error);
+
+
+ //====================================================================
+ // GetHRForLastWin32Error
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ public static int GetHRForLastWin32Error()
+ {
+ int dwLastError = GetLastWin32Error();
+ if ((dwLastError & 0x80000000) == 0x80000000)
+ return dwLastError;
+ else
+ return (dwLastError & 0x0000FFFF) | unchecked((int)0x80070000);
+ }
+
+
+ //====================================================================
+ // Prelink
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void Prelink(MethodInfo m)
+ {
+ if (m == null)
+ throw new ArgumentNullException("m");
+ Contract.EndContractBlock();
+
+ RuntimeMethodInfo rmi = m as RuntimeMethodInfo;
+
+ if (rmi == null)
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"));
+
+ InternalPrelink(rmi);
+ }
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
+ [SecurityCritical]
+ private static extern void InternalPrelink(IRuntimeMethodInfo m);
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void PrelinkAll(Type c)
+ {
+ if (c == null)
+ throw new ArgumentNullException("c");
+ Contract.EndContractBlock();
+
+ MethodInfo[] mi = c.GetMethods();
+ if (mi != null)
+ {
+ for (int i = 0; i < mi.Length; i++)
+ {
+ Prelink(mi[i]);
+ }
+ }
+ }
+
+ //====================================================================
+ // NumParamBytes
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static int NumParamBytes(MethodInfo m)
+ {
+ if (m == null)
+ throw new ArgumentNullException("m");
+ Contract.EndContractBlock();
+
+ RuntimeMethodInfo rmi = m as RuntimeMethodInfo;
+ if (rmi == null)
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"));
+
+ return InternalNumParamBytes(rmi);
+ }
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
+ [SecurityCritical]
+ private static extern int InternalNumParamBytes(IRuntimeMethodInfo m);
+
+ //====================================================================
+ // Win32 Exception stuff
+ // These are mostly interesting for Structured exception handling,
+ // but need to be exposed for all exceptions (not just SEHException).
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public static extern /* struct _EXCEPTION_POINTERS* */ IntPtr GetExceptionPointers();
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern int GetExceptionCode();
+
+
+ //====================================================================
+ // Marshals data from a structure class to a native memory block.
+ // If the structure contains pointers to allocated blocks and
+ // "fDeleteOld" is true, this routine will call DestroyStructure() first.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public static extern void StructureToPtr(Object structure, IntPtr ptr, bool fDeleteOld);
+
+ [System.Security.SecurityCritical]
+ public static void StructureToPtr<T>(T structure, IntPtr ptr, bool fDeleteOld)
+ {
+ StructureToPtr((object)structure, ptr, fDeleteOld);
+ }
+
+ //====================================================================
+ // Marshals data from a native memory block to a preallocated structure class.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public static void PtrToStructure(IntPtr ptr, Object structure)
+ {
+ PtrToStructureHelper(ptr, structure, false);
+ }
+
+ [System.Security.SecurityCritical]
+ public static void PtrToStructure<T>(IntPtr ptr, T structure)
+ {
+ PtrToStructure(ptr, (object)structure);
+ }
+
+ //====================================================================
+ // Creates a new instance of "structuretype" and marshals data from a
+ // native memory block to it.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ [System.Runtime.InteropServices.ComVisible(true)]
+ [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ public static Object PtrToStructure(IntPtr ptr, Type structureType)
+ {
+ if (ptr == IntPtr.Zero) return null;
+
+ if (structureType == null)
+ throw new ArgumentNullException("structureType");
+
+ if (structureType.IsGenericType)
+ throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), "structureType");
+
+ RuntimeType rt = structureType.UnderlyingSystemType as RuntimeType;
+
+ if (rt == null)
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "type");
+
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+
+ Object structure = rt.CreateInstanceDefaultCtor(false /*publicOnly*/, false /*skipCheckThis*/, false /*fillCache*/, ref stackMark);
+ PtrToStructureHelper(ptr, structure, true);
+ return structure;
+ }
+
+ [System.Security.SecurityCritical]
+ public static T PtrToStructure<T>(IntPtr ptr)
+ {
+ return (T)PtrToStructure(ptr, typeof(T));
+ }
+
+ //====================================================================
+ // Helper function to copy a pointer into a preallocated structure.
+ //====================================================================
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern void PtrToStructureHelper(IntPtr ptr, Object structure, bool allowValueClasses);
+
+
+ //====================================================================
+ // Freeds all substructures pointed to by the native memory block.
+ // "structureclass" is used to provide layout information.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public static extern void DestroyStructure(IntPtr ptr, Type structuretype);
+
+ [System.Security.SecurityCritical]
+ public static void DestroyStructure<T>(IntPtr ptr)
+ {
+ DestroyStructure(ptr, typeof(T));
+ }
+
+ //====================================================================
+ // Returns the HInstance for this module. Returns -1 if the module
+ // doesn't have an HInstance. In Memory (Dynamic) Modules won't have
+ // an HInstance.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static IntPtr GetHINSTANCE(Module m)
+ {
+ if (m == null)
+ throw new ArgumentNullException("m");
+ Contract.EndContractBlock();
+
+ RuntimeModule rtModule = m as RuntimeModule;
+ if (rtModule == null)
+ {
+ ModuleBuilder mb = m as ModuleBuilder;
+ if (mb != null)
+ rtModule = mb.InternalModule;
+ }
+
+ if (rtModule == null)
+ throw new ArgumentNullException("m",Environment.GetResourceString("Argument_MustBeRuntimeModule"));
+
+ return GetHINSTANCE(rtModule.GetNativeHandle());
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ [SuppressUnmanagedCodeSecurity]
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
+ private extern static IntPtr GetHINSTANCE(RuntimeModule m);
+
+ //====================================================================
+ // Throws a CLR exception based on the HRESULT.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void ThrowExceptionForHR(int errorCode)
+ {
+ if (errorCode < 0)
+ ThrowExceptionForHRInternal(errorCode, IntPtr.Zero);
+ }
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void ThrowExceptionForHR(int errorCode, IntPtr errorInfo)
+ {
+ if (errorCode < 0)
+ ThrowExceptionForHRInternal(errorCode, errorInfo);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern void ThrowExceptionForHRInternal(int errorCode, IntPtr errorInfo);
+
+
+ //====================================================================
+ // Converts the HRESULT to a CLR exception.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static Exception GetExceptionForHR(int errorCode)
+ {
+ if (errorCode < 0)
+ return GetExceptionForHRInternal(errorCode, IntPtr.Zero);
+ else
+ return null;
+ }
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static Exception GetExceptionForHR(int errorCode, IntPtr errorInfo)
+ {
+ if (errorCode < 0)
+ return GetExceptionForHRInternal(errorCode, errorInfo);
+ else
+ return null;
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern Exception GetExceptionForHRInternal(int errorCode, IntPtr errorInfo);
+
+
+ //====================================================================
+ // This method is intended for compiler code generators rather
+ // than applications.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ [ObsoleteAttribute("The GetUnmanagedThunkForManagedMethodPtr method has been deprecated and will be removed in a future release.", false)]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern IntPtr GetUnmanagedThunkForManagedMethodPtr(IntPtr pfnMethodToWrap, IntPtr pbSignature, int cbSignature);
+
+ //====================================================================
+ // This method is intended for compiler code generators rather
+ // than applications.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ [ObsoleteAttribute("The GetManagedThunkForUnmanagedMethodPtr method has been deprecated and will be removed in a future release.", false)]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern IntPtr GetManagedThunkForUnmanagedMethodPtr(IntPtr pfnMethodToWrap, IntPtr pbSignature, int cbSignature);
+
+ //====================================================================
+ // The hosting APIs allow a sophisticated host to schedule fibers
+ // onto OS threads, so long as they notify the runtime of this
+ // activity. A fiber cookie can be redeemed for its managed Thread
+ // object by calling the following service.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ [ObsoleteAttribute("The GetThreadFromFiberCookie method has been deprecated. Use the hosting API to perform this operation.", false)]
+ public static Thread GetThreadFromFiberCookie(int cookie)
+ {
+ if (cookie == 0)
+ throw new ArgumentException(Environment.GetResourceString("Argument_ArgumentZero"), "cookie");
+ Contract.EndContractBlock();
+
+ return InternalGetThreadFromFiberCookie(cookie);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern Thread InternalGetThreadFromFiberCookie(int cookie);
+
+
+ //====================================================================
+ // Memory allocation and deallocation.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
+ public static IntPtr AllocHGlobal(IntPtr cb)
+ {
+ // For backwards compatibility on 32 bit platforms, ensure we pass values between
+ // Int32.MaxValue and UInt32.MaxValue to Windows. If the binary has had the
+ // LARGEADDRESSAWARE bit set in the PE header, it may get 3 or 4 GB of user mode
+ // address space. It is remotely that those allocations could have succeeded,
+ // though I couldn't reproduce that. In either case, that means we should continue
+ // throwing an OOM instead of an ArgumentOutOfRangeException for "negative" amounts of memory.
+ UIntPtr numBytes;
+#if BIT64
+ numBytes = new UIntPtr(unchecked((ulong)cb.ToInt64()));
+#else // 32
+ numBytes = new UIntPtr(unchecked((uint)cb.ToInt32()));
+#endif
+
+ IntPtr pNewMem = Win32Native.LocalAlloc_NoSafeHandle(LMEM_FIXED, unchecked(numBytes));
+
+ if (pNewMem == IntPtr.Zero) {
+ throw new OutOfMemoryException();
+ }
+ return pNewMem;
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
+ public static IntPtr AllocHGlobal(int cb)
+ {
+ return AllocHGlobal((IntPtr)cb);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ public static void FreeHGlobal(IntPtr hglobal)
+ {
+ if (IsNotWin32Atom(hglobal)) {
+ if (IntPtr.Zero != Win32Native.LocalFree(hglobal)) {
+ ThrowExceptionForHR(GetHRForLastWin32Error());
+ }
+ }
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static IntPtr ReAllocHGlobal(IntPtr pv, IntPtr cb)
+ {
+ IntPtr pNewMem = Win32Native.LocalReAlloc(pv, cb, LMEM_MOVEABLE);
+ if (pNewMem == IntPtr.Zero) {
+ throw new OutOfMemoryException();
+ }
+ return pNewMem;
+ }
+
+
+ //====================================================================
+ // String convertions.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ unsafe public static IntPtr StringToHGlobalAnsi(String s)
+ {
+ if (s == null)
+ {
+ return IntPtr.Zero;
+ }
+ else
+ {
+ int nb = (s.Length + 1) * SystemMaxDBCSCharSize;
+
+ // Overflow checking
+ if (nb < s.Length)
+ throw new ArgumentOutOfRangeException("s");
+
+ UIntPtr len = new UIntPtr((uint)nb);
+ IntPtr hglobal = Win32Native.LocalAlloc_NoSafeHandle(LMEM_FIXED, len);
+
+ if (hglobal == IntPtr.Zero)
+ {
+ throw new OutOfMemoryException();
+ }
+ else
+ {
+ s.ConvertToAnsi((byte *)hglobal, nb, false, false);
+ return hglobal;
+ }
+ }
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ unsafe public static IntPtr StringToHGlobalUni(String s)
+ {
+ if (s == null)
+ {
+ return IntPtr.Zero;
+ }
+ else
+ {
+ int nb = (s.Length + 1) * 2;
+
+ // Overflow checking
+ if (nb < s.Length)
+ throw new ArgumentOutOfRangeException("s");
+
+ UIntPtr len = new UIntPtr((uint)nb);
+ IntPtr hglobal = Win32Native.LocalAlloc_NoSafeHandle(LMEM_FIXED, len);
+
+ if (hglobal == IntPtr.Zero)
+ {
+ throw new OutOfMemoryException();
+ }
+ else
+ {
+ fixed (char* firstChar = s)
+ {
+ String.wstrcpy((char*)hglobal, firstChar, s.Length + 1);
+ }
+ return hglobal;
+ }
+ }
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static IntPtr StringToHGlobalAuto(String s)
+ {
+ // Ansi platforms are no longer supported
+ return StringToHGlobalUni(s);
+ }
+
+#if FEATURE_COMINTEROP
+
+ //====================================================================
+ // Converts the CLR exception to an HRESULT. This function also sets
+ // up an IErrorInfo for the exception.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern int GetHRForException(Exception e);
+
+ //====================================================================
+ // Converts the CLR exception to an HRESULT. This function also sets
+ // up an IErrorInfo for the exception.
+ // This function is only used in WinRT and converts ObjectDisposedException
+ // to RO_E_CLOSED
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern int GetHRForException_WinRT(Exception e);
+
+ internal static readonly Guid ManagedNameGuid = new Guid("{0F21F359-AB84-41E8-9A78-36D110E6D2F9}");
+
+ //====================================================================
+ // Given a managed object that wraps a UCOMITypeLib, return its name
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ [Obsolete("Use System.Runtime.InteropServices.Marshal.GetTypeLibName(ITypeLib pTLB) instead. http://go.microsoft.com/fwlink/?linkid=14202&ID=0000011.", false)]
+ public static String GetTypeLibName(UCOMITypeLib pTLB)
+ {
+ return GetTypeLibName((ITypeLib)pTLB);
+ }
+
+
+ //====================================================================
+ // Given a managed object that wraps an ITypeLib, return its name
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static String GetTypeLibName(ITypeLib typelib)
+ {
+ if (typelib == null)
+ throw new ArgumentNullException("typelib");
+ Contract.EndContractBlock();
+
+ String strTypeLibName = null;
+ String strDocString = null;
+ int dwHelpContext = 0;
+ String strHelpFile = null;
+
+ typelib.GetDocumentation(-1, out strTypeLibName, out strDocString, out dwHelpContext, out strHelpFile);
+
+ return strTypeLibName;
+ }
+
+ //====================================================================
+ // Internal version of GetTypeLibName
+ // Support GUID_ManagedName which aligns with TlbImp
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ internal static String GetTypeLibNameInternal(ITypeLib typelib)
+ {
+ if (typelib == null)
+ throw new ArgumentNullException("typelib");
+ Contract.EndContractBlock();
+
+ // Try GUID_ManagedName first
+ ITypeLib2 typeLib2 = typelib as ITypeLib2;
+ if (typeLib2 != null)
+ {
+ Guid guid = ManagedNameGuid;
+ object val;
+
+ try
+ {
+ typeLib2.GetCustData(ref guid, out val);
+ }
+ catch(Exception)
+ {
+ val = null;
+ }
+
+ if (val != null && val.GetType() == typeof(string))
+ {
+ string customManagedNamespace = (string)val;
+ customManagedNamespace = customManagedNamespace.Trim();
+ if (customManagedNamespace.EndsWith(".DLL", StringComparison.OrdinalIgnoreCase))
+ customManagedNamespace = customManagedNamespace.Substring(0, customManagedNamespace.Length - 4);
+ else if (customManagedNamespace.EndsWith(".EXE", StringComparison.OrdinalIgnoreCase))
+ customManagedNamespace = customManagedNamespace.Substring(0, customManagedNamespace.Length - 4);
+ return customManagedNamespace;
+ }
+ }
+
+ return GetTypeLibName(typelib);
+ }
+
+
+ //====================================================================
+ // Given an managed object that wraps an UCOMITypeLib, return its guid
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ [Obsolete("Use System.Runtime.InteropServices.Marshal.GetTypeLibGuid(ITypeLib pTLB) instead. http://go.microsoft.com/fwlink/?linkid=14202&ID=0000011.", false)]
+ public static Guid GetTypeLibGuid(UCOMITypeLib pTLB)
+ {
+ return GetTypeLibGuid((ITypeLib)pTLB);
+ }
+
+ //====================================================================
+ // Given an managed object that wraps an ITypeLib, return its guid
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static Guid GetTypeLibGuid(ITypeLib typelib)
+ {
+ Guid result = new Guid ();
+ FCallGetTypeLibGuid (ref result, typelib);
+ return result;
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern void FCallGetTypeLibGuid(ref Guid result, ITypeLib pTLB);
+
+ //====================================================================
+ // Given a managed object that wraps a UCOMITypeLib, return its lcid
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ [Obsolete("Use System.Runtime.InteropServices.Marshal.GetTypeLibLcid(ITypeLib pTLB) instead. http://go.microsoft.com/fwlink/?linkid=14202&ID=0000011.", false)]
+ public static int GetTypeLibLcid(UCOMITypeLib pTLB)
+ {
+ return GetTypeLibLcid((ITypeLib)pTLB);
+ }
+
+ //====================================================================
+ // Given a managed object that wraps an ITypeLib, return its lcid
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern int GetTypeLibLcid(ITypeLib typelib);
+
+ //====================================================================
+ // Given a managed object that wraps an ITypeLib, return it's
+ // version information.
+ //====================================================================
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern void GetTypeLibVersion(ITypeLib typeLibrary, out int major, out int minor);
+
+ //====================================================================
+ // Given a managed object that wraps an ITypeInfo, return its guid.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated
+ internal static Guid GetTypeInfoGuid(ITypeInfo typeInfo)
+ {
+ Guid result = new Guid ();
+ FCallGetTypeInfoGuid (ref result, typeInfo);
+ return result;
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern void FCallGetTypeInfoGuid(ref Guid result, ITypeInfo typeInfo);
+
+ //====================================================================
+ // Given a assembly, return the TLBID that will be generated for the
+ // typelib exported from the assembly.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static Guid GetTypeLibGuidForAssembly(Assembly asm)
+ {
+ if (asm == null)
+ throw new ArgumentNullException("asm");
+ Contract.EndContractBlock();
+
+ RuntimeAssembly rtAssembly = asm as RuntimeAssembly;
+ if (rtAssembly == null)
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeAssembly"), "asm");
+
+ Guid result = new Guid();
+ FCallGetTypeLibGuidForAssembly(ref result, rtAssembly);
+ return result;
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern void FCallGetTypeLibGuidForAssembly(ref Guid result, RuntimeAssembly asm);
+
+ //====================================================================
+ // Given a assembly, return the version number of the type library
+ // that would be exported from the assembly.
+ //====================================================================
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern void _GetTypeLibVersionForAssembly(RuntimeAssembly inputAssembly, out int majorVersion, out int minorVersion);
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void GetTypeLibVersionForAssembly(Assembly inputAssembly, out int majorVersion, out int minorVersion)
+ {
+ if (inputAssembly == null)
+ throw new ArgumentNullException("inputAssembly");
+ Contract.EndContractBlock();
+
+ RuntimeAssembly rtAssembly = inputAssembly as RuntimeAssembly;
+ if (rtAssembly == null)
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeAssembly"), "inputAssembly");
+
+ _GetTypeLibVersionForAssembly(rtAssembly, out majorVersion, out minorVersion);
+ }
+
+ //====================================================================
+ // Given a managed object that wraps an UCOMITypeInfo, return its name
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ [Obsolete("Use System.Runtime.InteropServices.Marshal.GetTypeInfoName(ITypeInfo pTLB) instead. http://go.microsoft.com/fwlink/?linkid=14202&ID=0000011.", false)]
+ public static String GetTypeInfoName(UCOMITypeInfo pTI)
+ {
+ return GetTypeInfoName((ITypeInfo)pTI);
+ }
+
+ //====================================================================
+ // Given a managed object that wraps an ITypeInfo, return its name
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static String GetTypeInfoName(ITypeInfo typeInfo)
+ {
+ if (typeInfo == null)
+ throw new ArgumentNullException("typeInfo");
+ Contract.EndContractBlock();
+
+ String strTypeLibName = null;
+ String strDocString = null;
+ int dwHelpContext = 0;
+ String strHelpFile = null;
+
+ typeInfo.GetDocumentation(-1, out strTypeLibName, out strDocString, out dwHelpContext, out strHelpFile);
+
+ return strTypeLibName;
+ }
+
+ //====================================================================
+ // Internal version of GetTypeInfoName
+ // Support GUID_ManagedName which aligns with TlbImp
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ internal static String GetTypeInfoNameInternal(ITypeInfo typeInfo, out bool hasManagedName)
+ {
+ if (typeInfo == null)
+ throw new ArgumentNullException("typeInfo");
+ Contract.EndContractBlock();
+
+ // Try ManagedNameGuid first
+ ITypeInfo2 typeInfo2 = typeInfo as ITypeInfo2;
+ if (typeInfo2 != null)
+ {
+ Guid guid = ManagedNameGuid;
+ object val;
+
+ try
+ {
+ typeInfo2.GetCustData(ref guid, out val);
+ }
+ catch(Exception)
+ {
+ val = null;
+ }
+
+ if (val != null && val.GetType() == typeof(string))
+ {
+ hasManagedName = true;
+ return (string)val;
+ }
+ }
+
+ hasManagedName = false;
+ return GetTypeInfoName(typeInfo);
+ }
+
+ //====================================================================
+ // Get the corresponding managed name as converted by TlbImp
+ // Used to get the type using GetType() from imported assemblies
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ internal static String GetManagedTypeInfoNameInternal(ITypeLib typeLib, ITypeInfo typeInfo)
+ {
+ bool hasManagedName;
+ string name = GetTypeInfoNameInternal(typeInfo, out hasManagedName);
+ if (hasManagedName)
+ return name;
+ else
+ return GetTypeLibNameInternal(typeLib) + "." + name;
+ }
+
+ //====================================================================
+ // If a type with the specified GUID is loaded, this method will
+ // return the reflection type that represents it. Otherwise it returns
+ // NULL.
+ //====================================================================
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern Type GetLoadedTypeForGUID(ref Guid guid);
+
+#if !FEATURE_CORECLR // current implementation requires reflection only load
+ //====================================================================
+ // map ITypeInfo* to Type
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static Type GetTypeForITypeInfo(IntPtr /* ITypeInfo* */ piTypeInfo)
+ {
+ ITypeInfo pTI = null;
+ ITypeLib pTLB = null;
+ Type TypeObj = null;
+ Assembly AsmBldr = null;
+ TypeLibConverter TlbConverter = null;
+ int Index = 0;
+ Guid clsid;
+
+ // If the input ITypeInfo is NULL then return NULL.
+ if (piTypeInfo == IntPtr.Zero)
+ return null;
+
+ // Wrap the ITypeInfo in a CLR object.
+ pTI = (ITypeInfo)GetObjectForIUnknown(piTypeInfo);
+
+ // Check to see if a class exists with the specified GUID.
+
+ clsid = GetTypeInfoGuid(pTI);
+ TypeObj = GetLoadedTypeForGUID(ref clsid);
+
+ // If we managed to find the type based on the GUID then return it.
+ if (TypeObj != null)
+ return TypeObj;
+
+ // There is no type with the specified GUID in the app domain so lets
+ // try and convert the containing typelib.
+ try
+ {
+ pTI.GetContainingTypeLib(out pTLB, out Index);
+ }
+ catch(COMException)
+ {
+ pTLB = null;
+ }
+
+ // Check to see if we managed to get a containing typelib.
+ if (pTLB != null)
+ {
+ // Get the assembly name from the typelib.
+ AssemblyName AsmName = TypeLibConverter.GetAssemblyNameFromTypelib(pTLB, null, null, null, null, AssemblyNameFlags.None);
+ String AsmNameString = AsmName.FullName;
+
+ // Check to see if the assembly that will contain the type already exists.
+ Assembly[] aAssemblies = Thread.GetDomain().GetAssemblies();
+ int NumAssemblies = aAssemblies.Length;
+ for (int i = 0; i < NumAssemblies; i++)
+ {
+ if (String.Compare(aAssemblies[i].FullName,
+ AsmNameString,StringComparison.Ordinal) == 0)
+ AsmBldr = aAssemblies[i];
+ }
+
+ // If we haven't imported the assembly yet then import it.
+ if (AsmBldr == null)
+ {
+ TlbConverter = new TypeLibConverter();
+ AsmBldr = TlbConverter.ConvertTypeLibToAssembly(pTLB,
+ GetTypeLibName(pTLB) + ".dll", 0, new ImporterCallback(), null, null, null, null);
+ }
+
+ // Load the type object from the imported typelib.
+ // Call GetManagedTypeInfoNameInternal to align with TlbImp behavior
+ TypeObj = AsmBldr.GetType(GetManagedTypeInfoNameInternal(pTLB, pTI), true, false);
+ if (TypeObj != null && !TypeObj.IsVisible)
+ TypeObj = null;
+ }
+ else
+ {
+ // If the ITypeInfo does not have a containing typelib then simply
+ // return Object as the type.
+ TypeObj = typeof(Object);
+ }
+
+ return TypeObj;
+ }
+#endif // #if !FEATURE_CORECLR
+
+ // This method is identical to Type.GetTypeFromCLSID. Since it's interop specific, we expose it
+ // on Marshal for more consistent API surface.
+#if !FEATURE_CORECLR
+ [System.Security.SecuritySafeCritical]
+#endif //!FEATURE_CORECLR
+ public static Type GetTypeFromCLSID(Guid clsid)
+ {
+ return RuntimeType.GetTypeFromCLSIDImpl(clsid, null, false);
+ }
+
+ //====================================================================
+ // map Type to ITypeInfo*
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern IntPtr /* ITypeInfo* */ GetITypeInfoForType(Type t);
+
+ //====================================================================
+ // return the IUnknown* for an Object if the current context
+ // is the one where the RCW was first seen. Will return null
+ // otherwise.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static IntPtr /* IUnknown* */ GetIUnknownForObject(Object o)
+ {
+ return GetIUnknownForObjectNative(o, false);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static IntPtr /* IUnknown* */ GetIUnknownForObjectInContext(Object o)
+ {
+ return GetIUnknownForObjectNative(o, true);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern IntPtr /* IUnknown* */ GetIUnknownForObjectNative(Object o, bool onlyInContext);
+
+ //====================================================================
+ // return the raw IUnknown* for a COM Object not related to current
+ // context
+ // Does not call AddRef
+ //====================================================================
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern IntPtr /* IUnknown* */ GetRawIUnknownForComObjectNoAddRef(Object o);
+
+ //====================================================================
+ // return the IDispatch* for an Object
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static IntPtr /* IDispatch */ GetIDispatchForObject(Object o)
+ {
+ return GetIDispatchForObjectNative(o, false);
+ }
+
+ //====================================================================
+ // return the IDispatch* for an Object if the current context
+ // is the one where the RCW was first seen. Will return null
+ // otherwise.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static IntPtr /* IUnknown* */ GetIDispatchForObjectInContext(Object o)
+ {
+ return GetIDispatchForObjectNative(o, true);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern IntPtr /* IUnknown* */ GetIDispatchForObjectNative(Object o, bool onlyInContext);
+
+ //====================================================================
+ // return the IUnknown* representing the interface for the Object
+ // Object o should support Type T
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static IntPtr /* IUnknown* */ GetComInterfaceForObject(Object o, Type T)
+ {
+ return GetComInterfaceForObjectNative(o, T, false, true);
+ }
+
+ [System.Security.SecurityCritical]
+ public static IntPtr GetComInterfaceForObject<T, TInterface>(T o)
+ {
+ return GetComInterfaceForObject(o, typeof(TInterface));
+ }
+
+ //====================================================================
+ // return the IUnknown* representing the interface for the Object
+ // Object o should support Type T, it refer the value of mode to
+ // invoke customized QueryInterface or not
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static IntPtr /* IUnknown* */ GetComInterfaceForObject(Object o, Type T, CustomQueryInterfaceMode mode)
+ {
+ bool bEnableCustomizedQueryInterface = ((mode == CustomQueryInterfaceMode.Allow) ? true : false);
+ return GetComInterfaceForObjectNative(o, T, false, bEnableCustomizedQueryInterface);
+ }
+
+ //====================================================================
+ // return the IUnknown* representing the interface for the Object
+ // Object o should support Type T if the current context
+ // is the one where the RCW was first seen. Will return null
+ // otherwise.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static IntPtr /* IUnknown* */ GetComInterfaceForObjectInContext(Object o, Type t)
+ {
+ return GetComInterfaceForObjectNative(o, t, true, true);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern IntPtr /* IUnknown* */ GetComInterfaceForObjectNative(Object o, Type t, bool onlyInContext, bool fEnalbeCustomizedQueryInterface);
+
+ //====================================================================
+ // return an Object for IUnknown
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern Object GetObjectForIUnknown(IntPtr /* IUnknown* */ pUnk);
+
+ //====================================================================
+ // Return a unique Object given an IUnknown. This ensures that you
+ // receive a fresh object (we will not look in the cache to match up this
+ // IUnknown to an already existing object). This is useful in cases
+ // where you want to be able to call ReleaseComObject on a RCW
+ // and not worry about other active uses of said RCW.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern Object GetUniqueObjectForIUnknown(IntPtr unknown);
+
+ //====================================================================
+ // return an Object for IUnknown, using the Type T,
+ // NOTE:
+ // Type T should be either a COM imported Type or a sub-type of COM
+ // imported Type
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern Object GetTypedObjectForIUnknown(IntPtr /* IUnknown* */ pUnk, Type t);
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern IntPtr CreateAggregatedObject(IntPtr pOuter, Object o);
+
+ [System.Security.SecurityCritical]
+ public static IntPtr CreateAggregatedObject<T>(IntPtr pOuter, T o)
+ {
+ return CreateAggregatedObject(pOuter, (object)o);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern void CleanupUnusedObjectsInCurrentContext();
+
+ [System.Security.SecurityCritical]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern bool AreComObjectsAvailableForCleanup();
+
+ //====================================================================
+ // check if the object is classic COM component
+ //====================================================================
+#if !FEATURE_CORECLR // with FEATURE_CORECLR, the whole type is SecurityCritical
+ [System.Security.SecuritySafeCritical]
+#endif
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern bool IsComObject(Object o);
+
+#endif // FEATURE_COMINTEROP
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static IntPtr AllocCoTaskMem(int cb)
+ {
+ IntPtr pNewMem = Win32Native.CoTaskMemAlloc(new UIntPtr((uint)cb));
+ if (pNewMem == IntPtr.Zero)
+ {
+ throw new OutOfMemoryException();
+ }
+ return pNewMem;
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ unsafe public static IntPtr StringToCoTaskMemUni(String s)
+ {
+ if (s == null)
+ {
+ return IntPtr.Zero;
+ }
+ else
+ {
+ int nb = (s.Length + 1) * 2;
+
+ // Overflow checking
+ if (nb < s.Length)
+ throw new ArgumentOutOfRangeException("s");
+
+ IntPtr hglobal = Win32Native.CoTaskMemAlloc(new UIntPtr((uint)nb));
+
+ if (hglobal == IntPtr.Zero)
+ {
+ throw new OutOfMemoryException();
+ }
+ else
+ {
+ fixed (char* firstChar = s)
+ {
+ String.wstrcpy((char *)hglobal, firstChar, s.Length + 1);
+ }
+ return hglobal;
+ }
+ }
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ unsafe public static IntPtr StringToCoTaskMemUTF8(String s)
+ {
+ const int MAX_UTF8_CHAR_SIZE = 3;
+ if (s == null)
+ {
+ return IntPtr.Zero;
+ }
+ else
+ {
+ int nb = (s.Length + 1) * MAX_UTF8_CHAR_SIZE;
+
+ // Overflow checking
+ if (nb < s.Length)
+ throw new ArgumentOutOfRangeException("s");
+
+ IntPtr pMem = Win32Native.CoTaskMemAlloc(new UIntPtr((uint)nb +1));
+
+ if (pMem == IntPtr.Zero)
+ {
+ throw new OutOfMemoryException();
+ }
+ else
+ {
+ byte* pbMem = (byte*)pMem;
+ int nbWritten = s.GetBytesFromEncoding(pbMem, nb, Encoding.UTF8);
+ pbMem[nbWritten] = 0;
+ return pMem;
+ }
+ }
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static IntPtr StringToCoTaskMemAuto(String s)
+ {
+ // Ansi platforms are no longer supported
+ return StringToCoTaskMemUni(s);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ unsafe public static IntPtr StringToCoTaskMemAnsi(String s)
+ {
+ if (s == null)
+ {
+ return IntPtr.Zero;
+ }
+ else
+ {
+ int nb = (s.Length + 1) * SystemMaxDBCSCharSize;
+
+ // Overflow checking
+ if (nb < s.Length)
+ throw new ArgumentOutOfRangeException("s");
+
+ IntPtr hglobal = Win32Native.CoTaskMemAlloc(new UIntPtr((uint)nb));
+
+ if (hglobal == IntPtr.Zero)
+ {
+ throw new OutOfMemoryException();
+ }
+ else
+ {
+ s.ConvertToAnsi((byte *)hglobal, nb, false, false);
+ return hglobal;
+ }
+ }
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void FreeCoTaskMem(IntPtr ptr)
+ {
+ if (IsNotWin32Atom(ptr)) {
+ Win32Native.CoTaskMemFree(ptr);
+ }
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static IntPtr ReAllocCoTaskMem(IntPtr pv, int cb)
+ {
+ IntPtr pNewMem = Win32Native.CoTaskMemRealloc(pv, new UIntPtr((uint)cb));
+ if (pNewMem == IntPtr.Zero && cb != 0)
+ {
+ throw new OutOfMemoryException();
+ }
+ return pNewMem;
+ }
+
+ //====================================================================
+ // BSTR allocation and dealocation.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void FreeBSTR(IntPtr ptr)
+ {
+ if (IsNotWin32Atom(ptr))
+ {
+ Win32Native.SysFreeString(ptr);
+ }
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static IntPtr StringToBSTR(String s)
+ {
+ if (s == null)
+ return IntPtr.Zero;
+
+ // Overflow checking
+ if (s.Length + 1 < s.Length)
+ throw new ArgumentOutOfRangeException("s");
+
+ IntPtr bstr = Win32Native.SysAllocStringLen(s, s.Length);
+ if (bstr == IntPtr.Zero)
+ throw new OutOfMemoryException();
+
+ return bstr;
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static String PtrToStringBSTR(IntPtr ptr)
+ {
+ return PtrToStringUni(ptr, (int)Win32Native.SysStringLen(ptr));
+ }
+
+#if FEATURE_COMINTEROP
+ //====================================================================
+ // release the COM component and if the reference hits 0 zombie this object
+ // further usage of this Object might throw an exception
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static int ReleaseComObject(Object o)
+ {
+ __ComObject co = null;
+
+ // Make sure the obj is an __ComObject.
+ try
+ {
+ co = (__ComObject)o;
+ }
+ catch (InvalidCastException)
+ {
+ throw new ArgumentException(Environment.GetResourceString("Argument_ObjNotComObject"), "o");
+ }
+
+ return co.ReleaseSelf();
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern int InternalReleaseComObject(Object o);
+
+
+ //====================================================================
+ // release the COM component and zombie this object
+ // further usage of this Object might throw an exception
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static Int32 FinalReleaseComObject(Object o)
+ {
+ if (o == null)
+ throw new ArgumentNullException("o");
+ Contract.EndContractBlock();
+
+ __ComObject co = null;
+
+ // Make sure the obj is an __ComObject.
+ try
+ {
+ co = (__ComObject)o;
+ }
+ catch (InvalidCastException)
+ {
+ throw new ArgumentException(Environment.GetResourceString("Argument_ObjNotComObject"), "o");
+ }
+
+ co.FinalReleaseSelf();
+
+ return 0;
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern void InternalFinalReleaseComObject(Object o);
+
+ //====================================================================
+ // This method retrieves data from the COM object.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static Object GetComObjectData(Object obj, Object key)
+ {
+ // Validate that the arguments aren't null.
+ if (obj == null)
+ throw new ArgumentNullException("obj");
+ if (key == null)
+ throw new ArgumentNullException("key");
+ Contract.EndContractBlock();
+
+ __ComObject comObj = null;
+
+ // Make sure the obj is an __ComObject.
+ try
+ {
+ comObj = (__ComObject)obj;
+ }
+ catch (InvalidCastException)
+ {
+ throw new ArgumentException(Environment.GetResourceString("Argument_ObjNotComObject"), "obj");
+ }
+
+ if (obj.GetType().IsWindowsRuntimeObject)
+ {
+ throw new ArgumentException(Environment.GetResourceString("Argument_ObjIsWinRTObject"), "obj");
+ }
+
+ // Retrieve the data from the __ComObject.
+ return comObj.GetData(key);
+ }
+
+ //====================================================================
+ // This method sets data on the COM object. The data can only be set
+ // once for a given key and cannot be removed. This function returns
+ // true if the data has been added, false if the data could not be
+ // added because there already was data for the specified key.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static bool SetComObjectData(Object obj, Object key, Object data)
+ {
+ // Validate that the arguments aren't null. The data can validly be null.
+ if (obj == null)
+ throw new ArgumentNullException("obj");
+ if (key == null)
+ throw new ArgumentNullException("key");
+ Contract.EndContractBlock();
+
+ __ComObject comObj = null;
+
+ // Make sure the obj is an __ComObject.
+ try
+ {
+ comObj = (__ComObject)obj;
+ }
+ catch (InvalidCastException)
+ {
+ throw new ArgumentException(Environment.GetResourceString("Argument_ObjNotComObject"), "obj");
+ }
+
+ if (obj.GetType().IsWindowsRuntimeObject)
+ {
+ throw new ArgumentException(Environment.GetResourceString("Argument_ObjIsWinRTObject"), "obj");
+ }
+
+ // Retrieve the data from the __ComObject.
+ return comObj.SetData(key, data);
+ }
+
+ //====================================================================
+ // This method takes the given COM object and wraps it in an object
+ // of the specified type. The type must be derived from __ComObject.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static Object CreateWrapperOfType(Object o, Type t)
+ {
+ // Validate the arguments.
+ if (t == null)
+ throw new ArgumentNullException("t");
+ if (!t.IsCOMObject)
+ throw new ArgumentException(Environment.GetResourceString("Argument_TypeNotComObject"), "t");
+ if (t.IsGenericType)
+ throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), "t");
+ Contract.EndContractBlock();
+
+ if (t.IsWindowsRuntimeObject)
+ throw new ArgumentException(Environment.GetResourceString("Argument_TypeIsWinRTType"), "t");
+
+ // Check for the null case.
+ if (o == null)
+ return null;
+
+ // Make sure the object is a COM object.
+ if (!o.GetType().IsCOMObject)
+ throw new ArgumentException(Environment.GetResourceString("Argument_ObjNotComObject"), "o");
+ if (o.GetType().IsWindowsRuntimeObject)
+ throw new ArgumentException(Environment.GetResourceString("Argument_ObjIsWinRTObject"), "o");
+
+ // Check to see if the type of the object is the requested type.
+ if (o.GetType() == t)
+ return o;
+
+ // Check to see if we already have a cached wrapper for this type.
+ Object Wrapper = GetComObjectData(o, t);
+ if (Wrapper == null)
+ {
+ // Create the wrapper for the specified type.
+ Wrapper = InternalCreateWrapperOfType(o, t);
+
+ // Attempt to cache the wrapper on the object.
+ if (!SetComObjectData(o, t, Wrapper))
+ {
+ // Another thead already cached the wrapper so use that one instead.
+ Wrapper = GetComObjectData(o, t);
+ }
+ }
+
+ return Wrapper;
+ }
+
+ [System.Security.SecurityCritical]
+ public static TWrapper CreateWrapperOfType<T, TWrapper>(T o)
+ {
+ return (TWrapper)CreateWrapperOfType(o, typeof(TWrapper));
+ }
+
+ //====================================================================
+ // Helper method called from CreateWrapperOfType.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern Object InternalCreateWrapperOfType(Object o, Type t);
+
+ //====================================================================
+ // There may be a thread-based cache of COM components. This service can
+ // force the aggressive release of the current thread's cache.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ [Obsolete("This API did not perform any operation and will be removed in future versions of the CLR.", false)]
+ public static void ReleaseThreadCache()
+ {
+ }
+
+ //====================================================================
+ // check if the type is visible from COM.
+ //====================================================================
+ [System.Security.SecuritySafeCritical]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern bool IsTypeVisibleFromCom(Type t);
+
+ //====================================================================
+ // IUnknown Helpers
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern int /* HRESULT */ QueryInterface(IntPtr /* IUnknown */ pUnk, ref Guid iid, out IntPtr ppv);
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern int /* ULONG */ AddRef(IntPtr /* IUnknown */ pUnk );
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ public static extern int /* ULONG */ Release(IntPtr /* IUnknown */ pUnk );
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern void GetNativeVariantForObject(Object obj, /* VARIANT * */ IntPtr pDstNativeVariant);
+
+ [System.Security.SecurityCritical]
+ public static void GetNativeVariantForObject<T>(T obj, IntPtr pDstNativeVariant)
+ {
+ GetNativeVariantForObject((object)obj, pDstNativeVariant);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern Object GetObjectForNativeVariant(/* VARIANT * */ IntPtr pSrcNativeVariant );
+
+ [System.Security.SecurityCritical]
+ public static T GetObjectForNativeVariant<T>(IntPtr pSrcNativeVariant)
+ {
+ return (T)GetObjectForNativeVariant(pSrcNativeVariant);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern Object[] GetObjectsForNativeVariants(/* VARIANT * */ IntPtr aSrcNativeVariant, int cVars );
+
+ [System.Security.SecurityCritical]
+ public static T[] GetObjectsForNativeVariants<T>(IntPtr aSrcNativeVariant, int cVars)
+ {
+ object[] objects = GetObjectsForNativeVariants(aSrcNativeVariant, cVars);
+ T[] result = null;
+
+ if (objects != null)
+ {
+ result = new T[objects.Length];
+ Array.Copy(objects, result, objects.Length);
+ }
+
+ return result;
+ }
+
+ /// <summary>
+ /// <para>Returns the first valid COM slot that GetMethodInfoForSlot will work on
+ /// This will be 3 for IUnknown based interfaces and 7 for IDispatch based interfaces. </para>
+ /// </summary>
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern int GetStartComSlot(Type t);
+
+ /// <summary>
+ /// <para>Returns the last valid COM slot that GetMethodInfoForSlot will work on. </para>
+ /// </summary>
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern int GetEndComSlot(Type t);
+
+ /// <summary>
+ /// <para>Returns the MemberInfo that COM callers calling through the exposed
+ /// vtable on the given slot will be calling. The slot should take into account
+ /// if the exposed interface is IUnknown based or IDispatch based.
+ /// For classes, the lookup is done on the default interface that will be
+ /// exposed for the class. </para>
+ /// </summary>
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern MemberInfo GetMethodInfoForComSlot(Type t, int slot, ref ComMemberType memberType);
+
+ /// <summary>
+ /// <para>Returns the COM slot for a memeber info, taking into account whether
+ /// the exposed interface is IUnknown based or IDispatch based</para>
+ /// </summary>
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static int GetComSlotForMethodInfo(MemberInfo m)
+ {
+ if (m== null)
+ throw new ArgumentNullException("m");
+
+ if (!(m is RuntimeMethodInfo))
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), "m");
+
+ if (!m.DeclaringType.IsInterface)
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeInterfaceMethod"), "m");
+ if (m.DeclaringType.IsGenericType)
+ throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), "m");
+ Contract.EndContractBlock();
+
+ return InternalGetComSlotForMethodInfo((IRuntimeMethodInfo)m);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern int InternalGetComSlotForMethodInfo(IRuntimeMethodInfo m);
+
+ //====================================================================
+ // This method generates a GUID for the specified type. If the type
+ // has a GUID in the metadata then it is returned otherwise a stable
+ // guid GUID is generated based on the fully qualified name of the
+ // type.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static Guid GenerateGuidForType(Type type)
+ {
+ Guid result = new Guid ();
+ FCallGenerateGuidForType (ref result, type);
+ return result;
+ }
+
+ // The full assembly name is used to compute the GUID, so this should be SxS-safe
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern void FCallGenerateGuidForType(ref Guid result, Type type);
+
+ //====================================================================
+ // This method generates a PROGID for the specified type. If the type
+ // has a PROGID in the metadata then it is returned otherwise a stable
+ // PROGID is generated based on the fully qualified name of the
+ // type.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static String GenerateProgIdForType(Type type)
+ {
+ if (type == null)
+ throw new ArgumentNullException("type");
+ if (type.IsImport)
+ throw new ArgumentException(Environment.GetResourceString("Argument_TypeMustNotBeComImport"), "type");
+ if (type.IsGenericType)
+ throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), "type");
+ Contract.EndContractBlock();
+
+ if (!RegistrationServices.TypeRequiresRegistrationHelper(type))
+ throw new ArgumentException(Environment.GetResourceString("Argument_TypeMustBeComCreatable"), "type");
+
+ IList<CustomAttributeData> cas = CustomAttributeData.GetCustomAttributes(type);
+ for (int i = 0; i < cas.Count; i ++)
+ {
+ if (cas[i].Constructor.DeclaringType == typeof(ProgIdAttribute))
+ {
+ // Retrieve the PROGID string from the ProgIdAttribute.
+ IList<CustomAttributeTypedArgument> caConstructorArgs = cas[i].ConstructorArguments;
+ Contract.Assert(caConstructorArgs.Count == 1, "caConstructorArgs.Count == 1");
+
+ CustomAttributeTypedArgument progIdConstructorArg = caConstructorArgs[0];
+ Contract.Assert(progIdConstructorArg.ArgumentType == typeof(String), "progIdConstructorArg.ArgumentType == typeof(String)");
+
+ String strProgId = (String)progIdConstructorArg.Value;
+
+ if (strProgId == null)
+ strProgId = String.Empty;
+
+ return strProgId;
+ }
+ }
+
+ // If there is no prog ID attribute then use the full name of the type as the prog id.
+ return type.FullName;
+ }
+
+ //====================================================================
+ // This method binds to the specified moniker.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static Object BindToMoniker(String monikerName)
+ {
+ Object obj = null;
+ IBindCtx bindctx = null;
+ CreateBindCtx(0, out bindctx);
+
+ UInt32 cbEaten;
+ IMoniker pmoniker = null;
+ MkParseDisplayName(bindctx, monikerName, out cbEaten, out pmoniker);
+
+ BindMoniker(pmoniker, 0, ref IID_IUnknown, out obj);
+ return obj;
+ }
+
+ //====================================================================
+ // This method gets the currently running object.
+ //====================================================================
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static Object GetActiveObject(String progID)
+ {
+ Object obj = null;
+ Guid clsid;
+
+ // Call CLSIDFromProgIDEx first then fall back on CLSIDFromProgID if
+ // CLSIDFromProgIDEx doesn't exist.
+ try
+ {
+ CLSIDFromProgIDEx(progID, out clsid);
+ }
+// catch
+ catch(Exception)
+ {
+ CLSIDFromProgID(progID, out clsid);
+ }
+
+ GetActiveObject(ref clsid, IntPtr.Zero, out obj);
+ return obj;
+ }
+
+ [DllImport(Microsoft.Win32.Win32Native.OLE32, PreserveSig = false)]
+ [SuppressUnmanagedCodeSecurity]
+ [System.Security.SecurityCritical] // auto-generated
+ private static extern void CLSIDFromProgIDEx([MarshalAs(UnmanagedType.LPWStr)] String progId, out Guid clsid);
+
+ [DllImport(Microsoft.Win32.Win32Native.OLE32, PreserveSig = false)]
+ [SuppressUnmanagedCodeSecurity]
+ [System.Security.SecurityCritical] // auto-generated
+ private static extern void CLSIDFromProgID([MarshalAs(UnmanagedType.LPWStr)] String progId, out Guid clsid);
+
+ [DllImport(Microsoft.Win32.Win32Native.OLE32, PreserveSig = false)]
+ [SuppressUnmanagedCodeSecurity]
+ [System.Security.SecurityCritical] // auto-generated
+ private static extern void CreateBindCtx(UInt32 reserved, out IBindCtx ppbc);
+
+ [DllImport(Microsoft.Win32.Win32Native.OLE32, PreserveSig = false)]
+ [SuppressUnmanagedCodeSecurity]
+ [System.Security.SecurityCritical] // auto-generated
+ private static extern void MkParseDisplayName(IBindCtx pbc, [MarshalAs(UnmanagedType.LPWStr)] String szUserName, out UInt32 pchEaten, out IMoniker ppmk);
+
+ [DllImport(Microsoft.Win32.Win32Native.OLE32, PreserveSig = false)]
+ [SuppressUnmanagedCodeSecurity]
+ [System.Security.SecurityCritical] // auto-generated
+ private static extern void BindMoniker(IMoniker pmk, UInt32 grfOpt, ref Guid iidResult, [MarshalAs(UnmanagedType.Interface)] out Object ppvResult);
+
+ [DllImport(Microsoft.Win32.Win32Native.OLEAUT32, PreserveSig = false)]
+ [SuppressUnmanagedCodeSecurity]
+ [System.Security.SecurityCritical] // auto-generated
+ private static extern void GetActiveObject(ref Guid rclsid, IntPtr reserved, [MarshalAs(UnmanagedType.Interface)] out Object ppunk);
+
+ //========================================================================
+ // Private method called from remoting to support ServicedComponents.
+ //========================================================================
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern bool InternalSwitchCCW(Object oldtp, Object newtp);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern Object InternalWrapIUnknownWithComObject(IntPtr i);
+
+ //========================================================================
+ // Private method called from EE upon use of license/ICF2 marshaling.
+ //========================================================================
+ [SecurityCritical]
+ private static IntPtr LoadLicenseManager()
+ {
+ Assembly sys = Assembly.Load("System, Version="+ ThisAssembly.Version +
+ ", Culture=neutral, PublicKeyToken=" + AssemblyRef.EcmaPublicKeyToken);
+ Type t = sys.GetType("System.ComponentModel.LicenseManager");
+ if (t == null || !t.IsVisible)
+ return IntPtr.Zero;
+ return t.TypeHandle.Value;
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern void ChangeWrapperHandleStrength(Object otp, bool fIsWeak);
+
+ [System.Security.SecurityCritical]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern void InitializeWrapperForWinRT(object o, ref IntPtr pUnk);
+
+#if FEATURE_COMINTEROP_WINRT_MANAGED_ACTIVATION
+ [System.Security.SecurityCritical]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern void InitializeManagedWinRTFactoryObject(object o, RuntimeType runtimeClassType);
+#endif
+
+ //========================================================================
+ // Create activation factory and wraps it with a unique RCW
+ //========================================================================
+ [System.Security.SecurityCritical]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern object GetNativeActivationFactory(Type type);
+
+ //========================================================================
+ // Methods allowing retrieval of the IIDs exposed by an underlying WinRT
+ // object, as specified by the object's IInspectable::GetIids()
+ //========================================================================
+ [System.Security.SecurityCritical]
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
+ private static extern void _GetInspectableIids(ObjectHandleOnStack obj, ObjectHandleOnStack guids);
+
+ [System.Security.SecurityCritical]
+ internal static System.Guid[] GetInspectableIids(object obj)
+ {
+ System.Guid[] result = null;
+ System.__ComObject comObj = obj as System.__ComObject;
+ if (comObj != null)
+ {
+ _GetInspectableIids(JitHelpers.GetObjectHandleOnStack(ref comObj),
+ JitHelpers.GetObjectHandleOnStack(ref result));
+ }
+
+ return result;
+ }
+
+ //========================================================================
+ // Methods allowing retrieval of the cached WinRT type corresponding to
+ // the specified GUID
+ //========================================================================
+ [System.Security.SecurityCritical]
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
+ private static extern void _GetCachedWinRTTypeByIid(
+ ObjectHandleOnStack appDomainObj,
+ System.Guid iid,
+ out IntPtr rthHandle);
+
+ [System.Security.SecurityCritical]
+ internal static System.Type GetCachedWinRTTypeByIid(
+ System.AppDomain ad,
+ System.Guid iid)
+ {
+ IntPtr rthHandle;
+ _GetCachedWinRTTypeByIid(JitHelpers.GetObjectHandleOnStack(ref ad),
+ iid,
+ out rthHandle);
+ System.Type res = Type.GetTypeFromHandleUnsafe(rthHandle);
+ return res;
+ }
+
+
+ //========================================================================
+ // Methods allowing retrieval of the WinRT types cached in the specified
+ // app domain
+ //========================================================================
+ [System.Security.SecurityCritical]
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
+ private static extern void _GetCachedWinRTTypes(
+ ObjectHandleOnStack appDomainObj,
+ ref int epoch,
+ ObjectHandleOnStack winrtTypes);
+
+ [System.Security.SecurityCritical]
+ internal static System.Type[] GetCachedWinRTTypes(
+ System.AppDomain ad,
+ ref int epoch)
+ {
+ System.IntPtr[] res = null;
+
+ _GetCachedWinRTTypes(JitHelpers.GetObjectHandleOnStack(ref ad),
+ ref epoch,
+ JitHelpers.GetObjectHandleOnStack(ref res));
+
+ System.Type[] result = new System.Type[res.Length];
+ for (int i = 0; i < res.Length; ++i)
+ {
+ result[i] = Type.GetTypeFromHandleUnsafe(res[i]);
+ }
+
+ return result;
+ }
+
+ [System.Security.SecurityCritical]
+ internal static System.Type[] GetCachedWinRTTypes(
+ System.AppDomain ad)
+ {
+ int dummyEpoch = 0;
+ return GetCachedWinRTTypes(ad, ref dummyEpoch);
+ }
+
+
+#endif // FEATURE_COMINTEROP
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static Delegate GetDelegateForFunctionPointer(IntPtr ptr, Type t)
+ {
+ // Validate the parameters
+ if (ptr == IntPtr.Zero)
+ throw new ArgumentNullException("ptr");
+
+ if (t == null)
+ throw new ArgumentNullException("t");
+ Contract.EndContractBlock();
+
+ if ((t as RuntimeType) == null)
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "t");
+
+ if (t.IsGenericType)
+ throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), "t");
+
+ Type c = t.BaseType;
+ if (c == null || (c != typeof(Delegate) && c != typeof(MulticastDelegate)))
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"), "t");
+
+ return GetDelegateForFunctionPointerInternal(ptr, t);
+ }
+
+ [System.Security.SecurityCritical]
+ public static TDelegate GetDelegateForFunctionPointer<TDelegate>(IntPtr ptr)
+ {
+ return (TDelegate)(object)GetDelegateForFunctionPointer(ptr, typeof(TDelegate));
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern Delegate GetDelegateForFunctionPointerInternal(IntPtr ptr, Type t);
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static IntPtr GetFunctionPointerForDelegate(Delegate d)
+ {
+ if (d == null)
+ throw new ArgumentNullException("d");
+ Contract.EndContractBlock();
+
+ return GetFunctionPointerForDelegateInternal(d);
+ }
+
+ [System.Security.SecurityCritical]
+ public static IntPtr GetFunctionPointerForDelegate<TDelegate>(TDelegate d)
+ {
+ return GetFunctionPointerForDelegate((Delegate)(object)d);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern IntPtr GetFunctionPointerForDelegateInternal(Delegate d);
+
+#if FEATURE_LEGACYSURFACE
+
+#if FEATURE_COMINTEROP
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static IntPtr SecureStringToBSTR(SecureString s) {
+ if( s == null) {
+ throw new ArgumentNullException("s");
+ }
+ Contract.EndContractBlock();
+
+ return s.ToBSTR();
+ }
+#endif
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static IntPtr SecureStringToCoTaskMemAnsi(SecureString s) {
+ if( s == null) {
+ throw new ArgumentNullException("s");
+ }
+ Contract.EndContractBlock();
+
+ return s.ToAnsiStr(false);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static IntPtr SecureStringToCoTaskMemUnicode(SecureString s)
+ {
+ if (s == null)
+ {
+ throw new ArgumentNullException("s");
+ }
+ Contract.EndContractBlock();
+
+ return s.ToUniStr(false);
+ }
+
+#endif // FEATURE_LEGACYSURFACE
+
+
+#if FEATURE_COMINTEROP
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void ZeroFreeBSTR(IntPtr s)
+ {
+ Win32Native.ZeroMemory(s, (UIntPtr)(Win32Native.SysStringLen(s) * 2));
+ FreeBSTR(s);
+ }
+#endif
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void ZeroFreeCoTaskMemAnsi(IntPtr s)
+ {
+ Win32Native.ZeroMemory(s, (UIntPtr)(Win32Native.lstrlenA(s)));
+ FreeCoTaskMem(s);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void ZeroFreeCoTaskMemUnicode(IntPtr s)
+ {
+ Win32Native.ZeroMemory(s, (UIntPtr)(Win32Native.lstrlenW(s) * 2));
+ FreeCoTaskMem(s);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ unsafe public static void ZeroFreeCoTaskMemUTF8(IntPtr s)
+ {
+ Win32Native.ZeroMemory(s, (UIntPtr)System.StubHelpers.StubHelpers.strlen((sbyte*)s));
+ FreeCoTaskMem(s);
+ }
+
+#if FEATURE_LEGACYSURFACE
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static IntPtr SecureStringToGlobalAllocAnsi(SecureString s) {
+ if( s == null) {
+ throw new ArgumentNullException("s");
+ }
+ Contract.EndContractBlock();
+
+ return s.ToAnsiStr(true);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static IntPtr SecureStringToGlobalAllocUnicode(SecureString s) {
+ if( s == null) {
+ throw new ArgumentNullException("s");
+ }
+ Contract.EndContractBlock();
+
+ return s.ToUniStr(true);
+ }
+#endif // FEATURE_LEGACYSURFACE
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void ZeroFreeGlobalAllocAnsi(IntPtr s) {
+ Win32Native.ZeroMemory(s, (UIntPtr)(Win32Native.lstrlenA(s)));
+ FreeHGlobal(s);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void ZeroFreeGlobalAllocUnicode(IntPtr s) {
+ Win32Native.ZeroMemory(s, (UIntPtr)(Win32Native.lstrlenW(s) * 2));
+ FreeHGlobal(s);
+ }
+ }
+
+#if FEATURE_COMINTEROP && !FEATURE_CORECLR // current implementation requires reflection only load
+ //========================================================================
+ // Typelib importer callback implementation.
+ //========================================================================
+ internal class ImporterCallback : ITypeLibImporterNotifySink
+ {
+ public void ReportEvent(ImporterEventKind EventKind, int EventCode, String EventMsg)
+ {
+ }
+
+ [System.Security.SecuritySafeCritical] // overrides transparent public member
+ public Assembly ResolveRef(Object TypeLib)
+ {
+ try
+ {
+ // Create the TypeLibConverter.
+ ITypeLibConverter TLBConv = new TypeLibConverter();
+
+ // Convert the typelib.
+ return TLBConv.ConvertTypeLibToAssembly(TypeLib,
+ Marshal.GetTypeLibName((ITypeLib)TypeLib) + ".dll",
+ 0,
+ new ImporterCallback(),
+ null,
+ null,
+ null,
+ null);
+ }
+ catch(Exception)
+// catch
+ {
+ return null;
+ }
+ }
+ }
+#endif // FEATURE_COMINTEROP && !FEATURE_CORECLR
+}
+
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/MarshalDirectiveException.cs b/src/mscorlib/src/System/Runtime/InteropServices/MarshalDirectiveException.cs
new file mode 100644
index 0000000000..b916778019
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/MarshalDirectiveException.cs
@@ -0,0 +1,40 @@
+// 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.
+
+/*=============================================================================
+**
+**
+** Purpose: This exception is thrown when the marshaller encounters a signature
+** that has an invalid MarshalAs CA for a given argument or is not
+** supported.
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices {
+
+ using System;
+ using System.Runtime.Serialization;
+
+ [System.Runtime.InteropServices.ComVisible(true)]
+ [Serializable]
+ public class MarshalDirectiveException : SystemException {
+ public MarshalDirectiveException()
+ : base(Environment.GetResourceString("Arg_MarshalDirectiveException")) {
+ SetErrorCode(__HResults.COR_E_MARSHALDIRECTIVE);
+ }
+
+ public MarshalDirectiveException(String message)
+ : base(message) {
+ SetErrorCode(__HResults.COR_E_MARSHALDIRECTIVE);
+ }
+
+ public MarshalDirectiveException(String message, Exception inner)
+ : base(message, inner) {
+ SetErrorCode(__HResults.COR_E_MARSHALDIRECTIVE);
+ }
+
+ protected MarshalDirectiveException(SerializationInfo info, StreamingContext context) : base(info, context) {
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/NativeBuffer.cs b/src/mscorlib/src/System/Runtime/InteropServices/NativeBuffer.cs
new file mode 100644
index 0000000000..94261621c3
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/NativeBuffer.cs
@@ -0,0 +1,175 @@
+// 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.
+
+using System.Runtime.CompilerServices;
+
+namespace System.Runtime.InteropServices
+{
+ /// <summary>
+ /// Wrapper for access to the native heap. Dispose to free the memory. Try to use with using statements.
+ /// Does not allocate zero size buffers, and will free the existing native buffer if capacity is dropped to zero.
+ /// </summary>
+ /// <remarks>
+ /// Suggested use through P/Invoke: define DllImport arguments that take a byte buffer as SafeHandle.
+ ///
+ /// Using SafeHandle will ensure that the buffer will not get collected during a P/Invoke.
+ /// (Notably AddRef and ReleaseRef will be called by the interop layer.)
+ ///
+ /// This class is not threadsafe, changing the capacity or disposing on multiple threads risks duplicate heap
+ /// handles or worse.
+ /// </remarks>
+ internal class NativeBuffer : IDisposable
+ {
+ [System.Security.SecurityCritical]
+ private readonly static SafeHandle s_emptyHandle;
+ [System.Security.SecurityCritical]
+ private SafeHeapHandle _handle;
+ private ulong _capacity;
+
+ [System.Security.SecuritySafeCritical]
+ static NativeBuffer()
+ {
+ s_emptyHandle = new EmptySafeHandle();
+ }
+
+ /// <summary>
+ /// Create a buffer with at least the specified initial capacity in bytes.
+ /// </summary>
+ public NativeBuffer(ulong initialMinCapacity = 0)
+ {
+ EnsureByteCapacity(initialMinCapacity);
+ }
+
+ protected unsafe void* VoidPointer
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [System.Security.SecurityCritical]
+ get
+ {
+ return _handle == null ? null : _handle.DangerousGetHandle().ToPointer();
+ }
+ }
+
+ protected unsafe byte* BytePointer
+ {
+ [System.Security.SecurityCritical]
+ get
+ {
+ return (byte*)VoidPointer;
+ }
+ }
+
+ /// <summary>
+ /// Get the handle for the buffer.
+ /// </summary>
+ [System.Security.SecuritySafeCritical]
+ public SafeHandle GetHandle()
+ {
+ // Marshalling code will throw on null for SafeHandle
+ return _handle ?? s_emptyHandle;
+ }
+
+ /// <summary>
+ /// The capacity of the buffer in bytes.
+ /// </summary>
+ public ulong ByteCapacity
+ {
+ get { return _capacity; }
+ }
+
+ /// <summary>
+ /// Ensure capacity in bytes is at least the given minimum.
+ /// </summary>
+ /// <exception cref="OutOfMemoryException">Thrown if unable to allocate memory when setting.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">Thrown if attempting to set <paramref name="nameof(minCapacity)"/> to a value that is larger than the maximum addressable memory.</exception>
+ [System.Security.SecuritySafeCritical]
+ public void EnsureByteCapacity(ulong minCapacity)
+ {
+ if (_capacity < minCapacity)
+ {
+ Resize(minCapacity);
+ _capacity = minCapacity;
+ }
+ }
+
+ public unsafe byte this[ulong index]
+ {
+ [System.Security.SecuritySafeCritical]
+ get
+ {
+ if (index >= _capacity) throw new ArgumentOutOfRangeException();
+ return BytePointer[index];
+ }
+ [System.Security.SecuritySafeCritical]
+ set
+ {
+ if (index >= _capacity) throw new ArgumentOutOfRangeException();
+ BytePointer[index] = value;
+ }
+ }
+
+ [System.Security.SecuritySafeCritical]
+ private unsafe void Resize(ulong byteLength)
+ {
+ if (byteLength == 0)
+ {
+ ReleaseHandle();
+ return;
+ }
+
+ if (_handle == null)
+ {
+ _handle = new SafeHeapHandle(byteLength);
+ }
+ else
+ {
+ _handle.Resize(byteLength);
+ }
+ }
+
+ [System.Security.SecuritySafeCritical]
+ private void ReleaseHandle()
+ {
+ if (_handle != null)
+ {
+ _capacity = 0;
+ _handle = null;
+ }
+ }
+
+ /// <summary>
+ /// Release the backing buffer
+ /// </summary>
+ [System.Security.SecuritySafeCritical]
+ public virtual void Free()
+ {
+ ReleaseHandle();
+ }
+
+ [System.Security.SecuritySafeCritical]
+ public void Dispose()
+ {
+ Free();
+ }
+
+ [System.Security.SecurityCritical]
+ private sealed class EmptySafeHandle : SafeHandle
+ {
+ public EmptySafeHandle() : base(IntPtr.Zero, true) { }
+
+ public override bool IsInvalid
+ {
+ [System.Security.SecurityCritical]
+ get
+ { return true; }
+ }
+
+ [System.Security.SecurityCritical]
+ protected override bool ReleaseHandle()
+ {
+ return true;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/NativeCallableAttribute.cs b/src/mscorlib/src/System/Runtime/InteropServices/NativeCallableAttribute.cs
new file mode 100644
index 0000000000..706ef80019
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/NativeCallableAttribute.cs
@@ -0,0 +1,28 @@
+// 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.
+
+/*=============================================================================
+** Any method marked with NativeCallableAttribute can be directly called from
+** native code.The function token can be loaded to a local variable using LDFTN and
+** passed as a callback to native method.
+=============================================================================*/
+
+using System;
+using System.Runtime.CompilerServices;
+
+namespace System.Runtime.InteropServices
+{
+
+ [AttributeUsage(AttributeTargets.Method)]
+ public sealed class NativeCallableAttribute : Attribute
+ {
+ public NativeCallableAttribute()
+ {
+ }
+ // Optional. If omitted , compiler will choose one for you.
+ public CallingConvention CallingConvention;
+ // Optional. If omitted, then the method is native callable, but no EAT is emitted.
+ public string EntryPoint;
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/NativeMethods.cs b/src/mscorlib/src/System/Runtime/InteropServices/NativeMethods.cs
new file mode 100644
index 0000000000..82cd4fa963
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/NativeMethods.cs
@@ -0,0 +1,65 @@
+// 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.
+
+
+/*============================================================
+**
+**
+** Purpose: part of ComEventHelpers APIs which allow binding
+** managed delegates to COM's connection point based events.
+**
+**/
+#if FEATURE_COMINTEROP
+
+namespace System.Runtime.InteropServices {
+
+ internal static class NativeMethods {
+
+ [
+ System.Security.SuppressUnmanagedCodeSecurity,
+ DllImport("oleaut32.dll", PreserveSig = false),
+ System.Security.SecurityCritical
+ ]
+ internal static extern void VariantClear(IntPtr variant);
+
+ [
+ System.Security.SuppressUnmanagedCodeSecurity,
+ ComImport,
+ InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
+ Guid("00020400-0000-0000-C000-000000000046")
+ ]
+ internal interface IDispatch {
+
+ [System.Security.SecurityCritical]
+ void GetTypeInfoCount(out uint pctinfo);
+
+ [System.Security.SecurityCritical]
+ void GetTypeInfo(uint iTInfo, int lcid, out IntPtr info);
+
+ [System.Security.SecurityCritical]
+ void GetIDsOfNames(
+ ref Guid iid,
+ [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 2)]
+ string[] names,
+ uint cNames,
+ int lcid,
+ [Out]
+ [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I4, SizeParamIndex = 2)]
+ int[] rgDispId);
+
+ [System.Security.SecurityCritical]
+ void Invoke(
+ int dispIdMember,
+ ref Guid riid,
+ int lcid,
+ ComTypes.INVOKEKIND wFlags,
+ ref ComTypes.DISPPARAMS pDispParams,
+ IntPtr pvarResult,
+ IntPtr pExcepInfo,
+ IntPtr puArgErr);
+ }
+ }
+}
+
+#endif
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/NonPortable.cs b/src/mscorlib/src/System/Runtime/InteropServices/NonPortable.cs
new file mode 100644
index 0000000000..408f56c8e2
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/NonPortable.cs
@@ -0,0 +1,209 @@
+// 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.
+
+// Dummy implementations of non-portable interop methods that just throw PlatformNotSupportedException
+
+namespace System.Runtime.InteropServices
+{
+ public static partial class Marshal
+ {
+ [System.Security.SecurityCritical]
+ public static int GetHRForException(Exception e)
+ {
+ return (e != null) ? e.HResult : 0;
+ }
+
+ [System.Security.SecurityCriticalAttribute]
+ public static int AddRef(System.IntPtr pUnk)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ [System.Security.SecurityCriticalAttribute]
+ public static bool AreComObjectsAvailableForCleanup()
+ {
+ return false;
+ }
+
+ [System.Security.SecurityCriticalAttribute]
+ public static System.IntPtr CreateAggregatedObject(System.IntPtr pOuter, object o)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ [System.Security.SecurityCriticalAttribute]
+ public static System.IntPtr CreateAggregatedObject<T>(System.IntPtr pOuter, T o)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ [System.Security.SecurityCriticalAttribute]
+ public static object CreateWrapperOfType(object o, System.Type t)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ [System.Security.SecurityCriticalAttribute]
+ public static TWrapper CreateWrapperOfType<T, TWrapper>(T o)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ [System.Security.SecurityCriticalAttribute]
+ public static int FinalReleaseComObject(object o)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ [System.Security.SecurityCriticalAttribute]
+ public static System.IntPtr GetComInterfaceForObject(object o, System.Type T)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ [System.Security.SecurityCriticalAttribute]
+ public static System.IntPtr GetComInterfaceForObject(object o, System.Type T, System.Runtime.InteropServices.CustomQueryInterfaceMode mode)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ [System.Security.SecurityCriticalAttribute]
+ public static System.IntPtr GetComInterfaceForObject<T, TInterface>(T o)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ [System.Security.SecurityCriticalAttribute]
+ public static System.IntPtr GetIUnknownForObject(object o)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ [System.Security.SecurityCriticalAttribute]
+ public static void GetNativeVariantForObject(object obj, System.IntPtr pDstNativeVariant)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ [System.Security.SecurityCriticalAttribute]
+ public static void GetNativeVariantForObject<T>(T obj, System.IntPtr pDstNativeVariant)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ [System.Security.SecurityCriticalAttribute]
+ public static object GetObjectForIUnknown(System.IntPtr pUnk)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ [System.Security.SecurityCriticalAttribute]
+ public static object GetObjectForNativeVariant(System.IntPtr pSrcNativeVariant)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ [System.Security.SecurityCriticalAttribute]
+ public static T GetObjectForNativeVariant<T>(System.IntPtr pSrcNativeVariant)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ [System.Security.SecurityCriticalAttribute]
+ public static object[] GetObjectsForNativeVariants(System.IntPtr aSrcNativeVariant, int cVars)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ [System.Security.SecurityCriticalAttribute]
+ public static T[] GetObjectsForNativeVariants<T>(System.IntPtr aSrcNativeVariant, int cVars)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ [System.Security.SecurityCriticalAttribute]
+ public static int GetStartComSlot(System.Type t)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ public static System.Type GetTypeFromCLSID(System.Guid clsid)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ [System.Security.SecurityCriticalAttribute]
+ public static string GetTypeInfoName(System.Runtime.InteropServices.ComTypes.ITypeInfo typeInfo)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ [System.Security.SecurityCriticalAttribute]
+ public static object GetUniqueObjectForIUnknown(System.IntPtr unknown)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ public static bool IsComObject(object o)
+ {
+ return false;
+ }
+
+ [System.Security.SecurityCriticalAttribute]
+ public static int QueryInterface(System.IntPtr pUnk, ref System.Guid iid, out System.IntPtr ppv)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ [System.Security.SecurityCriticalAttribute]
+ public static int Release(System.IntPtr pUnk)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ [System.Security.SecurityCriticalAttribute]
+ public static int ReleaseComObject(object o)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ [System.Security.SecurityCriticalAttribute]
+ public static void ZeroFreeBSTR(System.IntPtr s)
+ {
+ throw new PlatformNotSupportedException();
+ }
+ }
+
+ public class DispatchWrapper
+ {
+ public DispatchWrapper(object obj)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ public object WrappedObject
+ {
+ get
+ {
+ throw new PlatformNotSupportedException();
+ }
+ }
+ }
+
+ public static class ComEventsHelper
+ {
+ [System.Security.SecurityCriticalAttribute]
+ public static void Combine(object rcw, System.Guid iid, int dispid, System.Delegate d)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ [System.Security.SecurityCriticalAttribute]
+ public static System.Delegate Remove(object rcw, System.Guid iid, int dispid, System.Delegate d)
+ {
+ throw new PlatformNotSupportedException();
+ }
+ }
+}
+
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ObjectCreationDelegate.cs b/src/mscorlib/src/System/Runtime/InteropServices/ObjectCreationDelegate.cs
new file mode 100644
index 0000000000..f011253e1e
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ObjectCreationDelegate.cs
@@ -0,0 +1,24 @@
+// 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.
+
+/*=============================================================================
+**
+** Delegate: ObjectCreationDelegate
+**
+**
+** Purpose: Delegate called to create a classic COM object as an alternative to
+** CoCreateInstance.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices {
+
+ // Delegate called when a managed object wishes to instantiate its unmanaged
+ // portion. The IUnknown of the managed object (the aggregator) is passed as a
+ // parameter and the delegate should return the IUnknown of the unmanaged object
+ // (the aggregatee). Both are passed as int's to avoid any marshalling.
+[System.Runtime.InteropServices.ComVisible(true)]
+ public delegate IntPtr ObjectCreationDelegate(IntPtr aggregator);
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/PInvokeMap.cs b/src/mscorlib/src/System/Runtime/InteropServices/PInvokeMap.cs
new file mode 100644
index 0000000000..f47165544a
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/PInvokeMap.cs
@@ -0,0 +1,48 @@
+// 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.
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+//
+// PInvokeMap is an enum that defines the PInvoke attributes. These
+// values are defined in CorHdr.h.
+//
+//
+namespace System.Runtime.InteropServices {
+ using System.Runtime.InteropServices;
+ using System;
+
+ // This Enum matchs the CorPinvokeMap defined in CorHdr.h
+ [Serializable]
+ internal enum PInvokeMap
+ {
+ NoMangle = 0x0001, // Pinvoke is to use the member name as specified.
+ CharSetMask = 0x0006, // Heuristic used in data type & name mapping.
+ CharSetNotSpec = 0x0000,
+ CharSetAnsi = 0x0002,
+ CharSetUnicode = 0x0004,
+ CharSetAuto = 0x0006,
+
+ PinvokeOLE = 0x0020, // Heuristic: pinvoke will return hresult, with return value becoming the retval param. Not relevant for fields.
+ SupportsLastError = 0x0040, // Information about target function. Not relevant for fields.
+
+ BestFitMask = 0x0030,
+ BestFitEnabled = 0x0010,
+ BestFitDisabled = 0x0020,
+ BestFitUseAsm = 0x0030,
+
+ ThrowOnUnmappableCharMask = 0x3000,
+ ThrowOnUnmappableCharEnabled = 0x1000,
+ ThrowOnUnmappableCharDisabled = 0x2000,
+ ThrowOnUnmappableCharUseAsm = 0x3000,
+
+ // None of the calling convention flags is relevant for fields.
+ CallConvMask = 0x0700,
+ CallConvWinapi = 0x0100, // Pinvoke will use native callconv appropriate to target windows platform.
+ CallConvCdecl = 0x0200,
+ CallConvStdcall = 0x0300,
+ CallConvThiscall = 0x0400, // In M9, pinvoke will raise exception.
+ CallConvFastcall = 0x0500,
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/RegistrationServices.cs b/src/mscorlib/src/System/Runtime/InteropServices/RegistrationServices.cs
new file mode 100644
index 0000000000..7d3670d877
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/RegistrationServices.cs
@@ -0,0 +1,1087 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: This class provides services for registering and unregistering
+** a managed server for use by COM.
+**
+**
+**
+**
+** Change the way how to register and unregister a managed server
+**
+=============================================================================*/
+namespace System.Runtime.InteropServices {
+
+ using System;
+ using System.Collections;
+ using System.IO;
+ using System.Reflection;
+ using System.Security;
+ using System.Security.Permissions;
+ using System.Text;
+ using System.Threading;
+ using Microsoft.Win32;
+ using System.Runtime.CompilerServices;
+ using System.Globalization;
+ using System.Runtime.Versioning;
+ using System.Diagnostics.Contracts;
+
+ [Flags]
+ public enum RegistrationClassContext
+ {
+
+
+ InProcessServer = 0x1,
+ InProcessHandler = 0x2,
+ LocalServer = 0x4,
+ InProcessServer16 = 0x8,
+ RemoteServer = 0x10,
+ InProcessHandler16 = 0x20,
+ Reserved1 = 0x40,
+ Reserved2 = 0x80,
+ Reserved3 = 0x100,
+ Reserved4 = 0x200,
+ NoCodeDownload = 0x400,
+ Reserved5 = 0x800,
+ NoCustomMarshal = 0x1000,
+ EnableCodeDownload = 0x2000,
+ NoFailureLog = 0x4000,
+ DisableActivateAsActivator = 0x8000,
+ EnableActivateAsActivator = 0x10000,
+ FromDefaultContext = 0x20000
+ }
+
+
+ [Flags]
+ public enum RegistrationConnectionType
+ {
+ SingleUse = 0,
+ MultipleUse = 1,
+ MultiSeparate = 2,
+ Suspended = 4,
+ Surrogate = 8,
+ }
+
+ [Guid("475E398F-8AFA-43a7-A3BE-F4EF8D6787C9")]
+ [ClassInterface(ClassInterfaceType.None)]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public class RegistrationServices : IRegistrationServices
+ {
+ #region Constants
+
+ private const String strManagedCategoryGuid = "{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}";
+ private const String strDocStringPrefix = "";
+ private const String strManagedTypeThreadingModel = "Both";
+ private const String strComponentCategorySubKey = "Component Categories";
+ private const String strManagedCategoryDescription = ".NET Category";
+ private const String strImplementedCategoriesSubKey = "Implemented Categories";
+ private const String strMsCorEEFileName = "mscoree.dll";
+ private const String strRecordRootName = "Record";
+ private const String strClsIdRootName = "CLSID";
+ private const String strTlbRootName = "TypeLib";
+ private static Guid s_ManagedCategoryGuid = new Guid(strManagedCategoryGuid);
+
+ #endregion
+
+
+ #region IRegistrationServices
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public virtual bool RegisterAssembly(Assembly assembly, AssemblyRegistrationFlags flags)
+ {
+ // Validate the arguments.
+ if (assembly == null)
+ throw new ArgumentNullException("assembly");
+
+ if (assembly.ReflectionOnly)
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_AsmLoadedForReflectionOnly"));
+ Contract.EndContractBlock();
+
+ RuntimeAssembly rtAssembly = assembly as RuntimeAssembly;
+ if (rtAssembly == null)
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeAssembly"));
+
+ // Retrieve the assembly names.
+ String strAsmName = assembly.FullName;
+ if (strAsmName == null)
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NoAsmName"));
+
+ // Retrieve the assembly codebase.
+ String strAsmCodeBase = null;
+ if ((flags & AssemblyRegistrationFlags.SetCodeBase) != 0)
+ {
+ strAsmCodeBase = rtAssembly.GetCodeBase(false);
+ if (strAsmCodeBase == null)
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NoAsmCodeBase"));
+ }
+
+ // Go through all the registerable types in the assembly and register them.
+ Type[] aTypes = GetRegistrableTypesInAssembly(assembly);
+ int NumTypes = aTypes.Length;
+
+ String strAsmVersion = rtAssembly.GetVersion().ToString();
+
+ // Retrieve the runtime version used to build the assembly.
+ String strRuntimeVersion = assembly.ImageRuntimeVersion;
+
+ for (int cTypes = 0; cTypes < NumTypes; cTypes++)
+ {
+ if (IsRegisteredAsValueType(aTypes[cTypes]))
+ RegisterValueType(aTypes[cTypes], strAsmName, strAsmVersion, strAsmCodeBase, strRuntimeVersion);
+ else if (TypeRepresentsComType(aTypes[cTypes]))
+ RegisterComImportedType(aTypes[cTypes], strAsmName, strAsmVersion, strAsmCodeBase, strRuntimeVersion);
+ else
+ RegisterManagedType(aTypes[cTypes], strAsmName, strAsmVersion, strAsmCodeBase, strRuntimeVersion);
+
+ CallUserDefinedRegistrationMethod(aTypes[cTypes], true);
+ }
+
+ // If this assembly has the PIA attribute, then register it as a PIA.
+ Object[] aPIAAttrs = assembly.GetCustomAttributes(typeof(PrimaryInteropAssemblyAttribute), false);
+ int NumPIAAttrs = aPIAAttrs.Length;
+ for (int cPIAAttrs = 0; cPIAAttrs < NumPIAAttrs; cPIAAttrs++)
+ RegisterPrimaryInteropAssembly(rtAssembly, strAsmCodeBase, (PrimaryInteropAssemblyAttribute)aPIAAttrs[cPIAAttrs]);
+
+ // Return value indicating if we actually registered any types.
+ if (aTypes.Length > 0 || NumPIAAttrs > 0)
+ return true;
+ else
+ return false;
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public virtual bool UnregisterAssembly(Assembly assembly)
+ {
+ // Validate the arguments.
+ if (assembly == null)
+ throw new ArgumentNullException("assembly");
+
+ if (assembly.ReflectionOnly)
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_AsmLoadedForReflectionOnly"));
+ Contract.EndContractBlock();
+
+ RuntimeAssembly rtAssembly = assembly as RuntimeAssembly;
+ if (rtAssembly == null)
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeAssembly"));
+
+ bool bAllVersionsGone = true;
+
+ // Go through all the registrable types in the assembly and register them.
+ Type[] aTypes = GetRegistrableTypesInAssembly(assembly);
+ int NumTypes = aTypes.Length;
+
+ // Retrieve the assembly version
+ String strAsmVersion = rtAssembly.GetVersion().ToString();
+ for (int cTypes = 0;cTypes < NumTypes;cTypes++)
+ {
+ CallUserDefinedRegistrationMethod(aTypes[cTypes], false);
+
+ if (IsRegisteredAsValueType(aTypes[cTypes]))
+ {
+ if (!UnregisterValueType(aTypes[cTypes], strAsmVersion))
+ bAllVersionsGone = false;
+ }
+ else if (TypeRepresentsComType(aTypes[cTypes]))
+ {
+ if (!UnregisterComImportedType(aTypes[cTypes], strAsmVersion))
+ bAllVersionsGone = false;
+ }
+ else
+ {
+ if (!UnregisterManagedType(aTypes[cTypes], strAsmVersion))
+ bAllVersionsGone = false;
+ }
+ }
+
+ // If this assembly has the PIA attribute, then unregister it as a PIA.
+ Object[] aPIAAttrs = assembly.GetCustomAttributes(typeof(PrimaryInteropAssemblyAttribute),false);
+ int NumPIAAttrs = aPIAAttrs.Length;
+ if (bAllVersionsGone)
+ {
+ for (int cPIAAttrs = 0;cPIAAttrs < NumPIAAttrs;cPIAAttrs++)
+ UnregisterPrimaryInteropAssembly(assembly, (PrimaryInteropAssemblyAttribute)aPIAAttrs[cPIAAttrs]);
+ }
+
+ // Return value indicating if we actually un-registered any types.
+ if (aTypes.Length > 0 || NumPIAAttrs > 0)
+ return true;
+ else
+ return false;
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public virtual Type[] GetRegistrableTypesInAssembly(Assembly assembly)
+ {
+ // Validate the arguments.
+ if (assembly == null)
+ throw new ArgumentNullException("assembly");
+ Contract.EndContractBlock();
+
+ if (!(assembly is RuntimeAssembly))
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeAssembly"), "assembly");
+
+ // Retrieve the list of types in the assembly.
+ Type[] aTypes = assembly.GetExportedTypes();
+ int NumTypes = aTypes.Length;
+
+ // Create an array list that will be filled in.
+ ArrayList TypeList = new ArrayList();
+
+ // Register all the types that require registration.
+ for (int cTypes = 0; cTypes < NumTypes; cTypes++)
+ {
+ Type CurrentType = aTypes[cTypes];
+ if (TypeRequiresRegistration(CurrentType))
+ TypeList.Add(CurrentType);
+ }
+
+ // Copy the array list to an array and return it.
+ Type[] RetArray = new Type[TypeList.Count];
+ TypeList.CopyTo(RetArray);
+ return RetArray;
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public virtual String GetProgIdForType(Type type)
+ {
+ return Marshal.GenerateProgIdForType(type);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public virtual void RegisterTypeForComClients(Type type, ref Guid g)
+ {
+#if FEATURE_COMINTEROP_MANAGED_ACTIVATION
+ if(type == null)
+ throw new ArgumentNullException("type");
+ Contract.EndContractBlock();
+ if((type as RuntimeType) == null)
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"),"type");
+ if(!TypeRequiresRegistration(type))
+ throw new ArgumentException(Environment.GetResourceString("Argument_TypeMustBeComCreatable"),"type");
+
+ // Call the native method to do CoRegisterClassObject
+ RegisterTypeForComClientsNative(type, ref g);
+#else // FEATURE_COMINTEROP_MANAGED_ACTIVATION
+ throw new NotImplementedException("CoreCLR_REMOVED -- managed activation removed");
+#endif // FEATURE_COMINTEROP_MANAGED_ACTIVATION
+ }
+
+ public virtual Guid GetManagedCategoryGuid()
+ {
+ return s_ManagedCategoryGuid;
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public virtual bool TypeRequiresRegistration(Type type)
+ {
+ return TypeRequiresRegistrationHelper(type);
+ }
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+ public virtual bool TypeRepresentsComType(Type type)
+ {
+ // If the type is not a COM import, then it does not represent a COM type.
+ if (!type.IsCOMObject)
+ return false;
+
+ // If it is marked as tdImport, then it represents a COM type directly.
+ if (type.IsImport)
+ return true;
+
+ // If the type is derived from a tdImport class and has the same GUID as the
+ // imported class, then it represents a COM type.
+ Type baseComImportType = GetBaseComImportType(type);
+ Contract.Assert(baseComImportType != null, "baseComImportType != null");
+ if (Marshal.GenerateGuidForType(type) == Marshal.GenerateGuidForType(baseComImportType))
+ return true;
+
+ return false;
+ }
+
+ #endregion
+
+
+ #region Public methods not on IRegistrationServices
+ [System.Security.SecurityCritical] // auto-generated_required
+ [ComVisible(false)]
+ public virtual int RegisterTypeForComClients(Type type, RegistrationClassContext classContext, RegistrationConnectionType flags)
+ {
+#if FEATURE_COMINTEROP_MANAGED_ACTIVATION
+ if (type == null)
+ throw new ArgumentNullException("type");
+ Contract.EndContractBlock();
+ if ((type as RuntimeType) == null)
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"),"type");
+ if (!TypeRequiresRegistration(type))
+ throw new ArgumentException(Environment.GetResourceString("Argument_TypeMustBeComCreatable"),"type");
+
+ // Call the native method to do CoRegisterClassObject
+ return RegisterTypeForComClientsExNative(type, classContext, flags);
+#else // FEATURE_COMINTEROP_MANAGED_ACTIVATION
+ throw new NotImplementedException("CoreCLR_REMOVED -- managed activation removed");
+#endif // FEATURE_COMINTEROP_MANAGED_ACTIVATION
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ [ComVisible(false)]
+ public virtual void UnregisterTypeForComClients(int cookie)
+ {
+ // Call the native method to do CoRevokeClassObject.
+ CoRevokeClassObject(cookie);
+ }
+
+ #endregion
+
+
+ #region Internal helpers
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ internal static bool TypeRequiresRegistrationHelper(Type type)
+ {
+ // If the type is not a class or a value class, then it does not get registered.
+ if (!type.IsClass && !type.IsValueType)
+ return false;
+
+ // If the type is abstract then it does not get registered.
+ if (type.IsAbstract)
+ return false;
+
+ // If the does not have a public default constructor then is not creatable from COM so
+ // it does not require registration unless it is a value class.
+ if (!type.IsValueType && type.GetConstructor(BindingFlags.Instance | BindingFlags.Public,null,Array.Empty<Type>(),null) == null)
+ return false;
+
+ // All other conditions are met so check to see if the type is visible from COM.
+ return Marshal.IsTypeVisibleFromCom(type);
+ }
+
+ #endregion
+
+
+ #region Private helpers
+
+ [System.Security.SecurityCritical] // auto-generated
+ private void RegisterValueType(Type type, String strAsmName, String strAsmVersion, String strAsmCodeBase, String strRuntimeVersion)
+ {
+ // Retrieve some information that will be used during the registration process.
+ String strRecordId = "{" + Marshal.GenerateGuidForType(type).ToString().ToUpper(CultureInfo.InvariantCulture) + "}";
+
+ // Create the HKEY_CLASS_ROOT\Record key.
+ using (RegistryKey RecordRootKey = Registry.ClassesRoot.CreateSubKey(strRecordRootName))
+ {
+ // Create the HKEY_CLASS_ROOT\Record\<RecordID> key.
+ using (RegistryKey RecordKey = RecordRootKey.CreateSubKey(strRecordId))
+ {
+ // Create the HKEY_CLASS_ROOT\Record\<RecordId>\<version> key.
+ using (RegistryKey RecordVersionKey = RecordKey.CreateSubKey(strAsmVersion))
+ {
+ // Set the class value.
+ RecordVersionKey.SetValue("Class", type.FullName);
+
+ // Set the assembly value.
+ RecordVersionKey.SetValue("Assembly", strAsmName);
+
+ // Set the runtime version value.
+ RecordVersionKey.SetValue("RuntimeVersion", strRuntimeVersion);
+
+ // Set the assembly code base value if a code base was specified.
+ if (strAsmCodeBase != null)
+ RecordVersionKey.SetValue("CodeBase", strAsmCodeBase);
+ }
+ }
+ }
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ private void RegisterManagedType(Type type, String strAsmName, String strAsmVersion, String strAsmCodeBase, String strRuntimeVersion)
+ {
+ //
+ // Retrieve some information that will be used during the registration process.
+ //
+
+ String strDocString = strDocStringPrefix + type.FullName;
+ String strClsId = "{" + Marshal.GenerateGuidForType(type).ToString().ToUpper(CultureInfo.InvariantCulture) + "}";
+ String strProgId = GetProgIdForType(type);
+
+
+ //
+ // Write the actual type information in the registry.
+ //
+
+ if (strProgId != String.Empty)
+ {
+ // Create the HKEY_CLASS_ROOT\<wzProgId> key.
+ using (RegistryKey TypeNameKey = Registry.ClassesRoot.CreateSubKey(strProgId))
+ {
+ TypeNameKey.SetValue("", strDocString);
+
+ // Create the HKEY_CLASS_ROOT\<wzProgId>\CLSID key.
+ using (RegistryKey ProgIdClsIdKey = TypeNameKey.CreateSubKey("CLSID"))
+ {
+ ProgIdClsIdKey.SetValue("", strClsId);
+ }
+ }
+ }
+
+ // Create the HKEY_CLASS_ROOT\CLSID key.
+ using (RegistryKey ClsIdRootKey = Registry.ClassesRoot.CreateSubKey(strClsIdRootName))
+ {
+ // Create the HKEY_CLASS_ROOT\CLSID\<CLSID> key.
+ using (RegistryKey ClsIdKey = ClsIdRootKey.CreateSubKey(strClsId))
+ {
+ ClsIdKey.SetValue("", strDocString);
+
+ // Create the HKEY_CLASS_ROOT\CLSID\<CLSID>\InprocServer32 key.
+ using (RegistryKey InProcServerKey = ClsIdKey.CreateSubKey("InprocServer32"))
+ {
+ InProcServerKey.SetValue("", strMsCorEEFileName);
+ InProcServerKey.SetValue("ThreadingModel", strManagedTypeThreadingModel);
+ InProcServerKey.SetValue("Class", type.FullName);
+ InProcServerKey.SetValue("Assembly", strAsmName);
+ InProcServerKey.SetValue("RuntimeVersion", strRuntimeVersion);
+ if (strAsmCodeBase != null)
+ InProcServerKey.SetValue("CodeBase", strAsmCodeBase);
+
+ // Create the HKEY_CLASS_ROOT\CLSID\<CLSID>\InprocServer32\<Version> subkey
+ using (RegistryKey VersionSubKey = InProcServerKey.CreateSubKey(strAsmVersion))
+ {
+ VersionSubKey.SetValue("Class", type.FullName);
+ VersionSubKey.SetValue("Assembly", strAsmName);
+ VersionSubKey.SetValue("RuntimeVersion", strRuntimeVersion);
+ if (strAsmCodeBase != null)
+ VersionSubKey.SetValue("CodeBase", strAsmCodeBase);
+ }
+
+ if (strProgId != String.Empty)
+ {
+ // Create the HKEY_CLASS_ROOT\CLSID\<CLSID>\ProdId key.
+ using (RegistryKey ProgIdKey = ClsIdKey.CreateSubKey("ProgId"))
+ {
+ ProgIdKey.SetValue("", strProgId);
+ }
+ }
+ }
+
+ // Create the HKEY_CLASS_ROOT\CLSID\<CLSID>\Implemented Categories\<Managed Category Guid> key.
+ using (RegistryKey CategoryKey = ClsIdKey.CreateSubKey(strImplementedCategoriesSubKey))
+ {
+ using (RegistryKey ManagedCategoryKey = CategoryKey.CreateSubKey(strManagedCategoryGuid)) {}
+ }
+ }
+ }
+
+
+ //
+ // Ensure that the managed category exists.
+ //
+
+ EnsureManagedCategoryExists();
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ private void RegisterComImportedType(Type type, String strAsmName, String strAsmVersion, String strAsmCodeBase, String strRuntimeVersion)
+ {
+ // Retrieve some information that will be used during the registration process.
+ String strClsId = "{" + Marshal.GenerateGuidForType(type).ToString().ToUpper(CultureInfo.InvariantCulture) + "}";
+
+ // Create the HKEY_CLASS_ROOT\CLSID key.
+ using (RegistryKey ClsIdRootKey = Registry.ClassesRoot.CreateSubKey(strClsIdRootName))
+ {
+ // Create the HKEY_CLASS_ROOT\CLSID\<CLSID> key.
+ using (RegistryKey ClsIdKey = ClsIdRootKey.CreateSubKey(strClsId))
+ {
+ // Create the HKEY_CLASS_ROOT\CLSID\<CLSID>\InProcServer32 key.
+ using (RegistryKey InProcServerKey = ClsIdKey.CreateSubKey("InprocServer32"))
+ {
+ // Set the class value.
+ InProcServerKey.SetValue("Class", type.FullName);
+
+ // Set the assembly value.
+ InProcServerKey.SetValue("Assembly", strAsmName);
+
+ // Set the runtime version value.
+ InProcServerKey.SetValue("RuntimeVersion", strRuntimeVersion);
+
+ // Set the assembly code base value if a code base was specified.
+ if (strAsmCodeBase != null)
+ InProcServerKey.SetValue("CodeBase", strAsmCodeBase);
+
+ // Create the HKEY_CLASS_ROOT\CLSID\<CLSID>\InprocServer32\<Version> subkey
+ using (RegistryKey VersionSubKey = InProcServerKey.CreateSubKey(strAsmVersion))
+ {
+ VersionSubKey.SetValue("Class", type.FullName);
+ VersionSubKey.SetValue("Assembly", strAsmName);
+ VersionSubKey.SetValue("RuntimeVersion", strRuntimeVersion);
+ if (strAsmCodeBase != null)
+ VersionSubKey.SetValue("CodeBase", strAsmCodeBase);
+ }
+ }
+ }
+ }
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ private bool UnregisterValueType(Type type, String strAsmVersion)
+ {
+ bool bAllVersionsGone = true;
+
+ // Try to open the HKEY_CLASS_ROOT\Record key.
+ String strRecordId = "{" + Marshal.GenerateGuidForType(type).ToString().ToUpper(CultureInfo.InvariantCulture) + "}";
+
+ using (RegistryKey RecordRootKey = Registry.ClassesRoot.OpenSubKey(strRecordRootName, true))
+ {
+ if (RecordRootKey != null)
+ {
+ // Open the HKEY_CLASS_ROOT\Record\{RecordId} key.
+ using (RegistryKey RecordKey = RecordRootKey.OpenSubKey(strRecordId,true))
+ {
+ if (RecordKey != null)
+ {
+ using (RegistryKey VersionSubKey = RecordKey.OpenSubKey(strAsmVersion,true))
+ {
+ if (VersionSubKey != null)
+ {
+ // Delete the values we created.
+ VersionSubKey.DeleteValue("Assembly",false);
+ VersionSubKey.DeleteValue("Class",false);
+ VersionSubKey.DeleteValue("CodeBase",false);
+ VersionSubKey.DeleteValue("RuntimeVersion",false);
+
+ // delete the version sub key if no value or subkeys under it
+ if ((VersionSubKey.SubKeyCount == 0) && (VersionSubKey.ValueCount == 0))
+ RecordKey.DeleteSubKey(strAsmVersion);
+ }
+ }
+
+ // If there are sub keys left then there are versions left.
+ if (RecordKey.SubKeyCount != 0)
+ bAllVersionsGone = false;
+
+ // If there are no other values or subkeys then we can delete the HKEY_CLASS_ROOT\Record\{RecordId}.
+ if ((RecordKey.SubKeyCount == 0) && (RecordKey.ValueCount == 0))
+ RecordRootKey.DeleteSubKey(strRecordId);
+ }
+ }
+
+ // If there are no other values or subkeys then we can delete the HKEY_CLASS_ROOT\Record.
+ if ((RecordRootKey.SubKeyCount == 0) && (RecordRootKey.ValueCount == 0))
+ Registry.ClassesRoot.DeleteSubKey(strRecordRootName);
+ }
+ }
+
+ return bAllVersionsGone;
+ }
+
+ // UnregisterManagedType
+ //
+ // Return :
+ // true: All versions are gone.
+ // false: Some versions are still left in registry
+ [System.Security.SecurityCritical] // auto-generated
+ private bool UnregisterManagedType(Type type,String strAsmVersion)
+ {
+ bool bAllVersionsGone = true;
+
+ //
+ // Create the CLSID string.
+ //
+
+ String strClsId = "{" + Marshal.GenerateGuidForType(type).ToString().ToUpper(CultureInfo.InvariantCulture) + "}";
+ String strProgId = GetProgIdForType(type);
+
+
+ //
+ // Remove the entries under HKEY_CLASS_ROOT\CLSID key.
+ //
+
+ using (RegistryKey ClsIdRootKey = Registry.ClassesRoot.OpenSubKey(strClsIdRootName, true))
+ {
+ if (ClsIdRootKey != null)
+ {
+ //
+ // Remove the entries under HKEY_CLASS_ROOT\CLSID\<CLSID> key.
+ //
+
+ using (RegistryKey ClsIdKey = ClsIdRootKey.OpenSubKey(strClsId, true))
+ {
+ if (ClsIdKey != null)
+ {
+ //
+ // Remove the entries in the HKEY_CLASS_ROOT\CLSID\<CLSID>\InprocServer32 key.
+ //
+
+ using (RegistryKey InProcServerKey = ClsIdKey.OpenSubKey("InprocServer32", true))
+ {
+ if (InProcServerKey != null)
+ {
+ //
+ // Remove the entries in HKEY_CLASS_ROOT\CLSID\<CLSID>\InprocServer32\<Version>
+ //
+
+ using (RegistryKey VersionSubKey = InProcServerKey.OpenSubKey(strAsmVersion, true))
+ {
+ if (VersionSubKey != null)
+ {
+ // Delete the values we created
+ VersionSubKey.DeleteValue("Assembly",false);
+ VersionSubKey.DeleteValue("Class",false);
+ VersionSubKey.DeleteValue("RuntimeVersion",false);
+ VersionSubKey.DeleteValue("CodeBase",false);
+
+ // If there are no other values or subkeys then we can delete the VersionSubKey.
+ if ((VersionSubKey.SubKeyCount == 0) && (VersionSubKey.ValueCount == 0))
+ InProcServerKey.DeleteSubKey(strAsmVersion);
+ }
+ }
+
+ // If there are sub keys left then there are versions left.
+ if (InProcServerKey.SubKeyCount != 0)
+ bAllVersionsGone = false;
+
+ // If there are no versions left, then delete the threading model and default value.
+ if (bAllVersionsGone)
+ {
+ InProcServerKey.DeleteValue("",false);
+ InProcServerKey.DeleteValue("ThreadingModel",false);
+ }
+
+ InProcServerKey.DeleteValue("Assembly",false);
+ InProcServerKey.DeleteValue("Class",false);
+ InProcServerKey.DeleteValue("RuntimeVersion",false);
+ InProcServerKey.DeleteValue("CodeBase",false);
+
+ // If there are no other values or subkeys then we can delete the InProcServerKey.
+ if ((InProcServerKey.SubKeyCount == 0) && (InProcServerKey.ValueCount == 0))
+ ClsIdKey.DeleteSubKey("InprocServer32");
+ }
+ }
+
+ // remove HKEY_CLASS_ROOT\CLSID\<CLSID>\ProgId
+ // and HKEY_CLASS_ROOT\CLSID\<CLSID>\Implemented Category
+ // only when all versions are removed
+ if (bAllVersionsGone)
+ {
+ // Delete the value we created.
+ ClsIdKey.DeleteValue("",false);
+
+ if (strProgId != String.Empty)
+ {
+ //
+ // Remove the entries in the HKEY_CLASS_ROOT\CLSID\<CLSID>\ProgId key.
+ //
+
+ using (RegistryKey ProgIdKey = ClsIdKey.OpenSubKey("ProgId", true))
+ {
+ if (ProgIdKey != null)
+ {
+ // Delete the value we created.
+ ProgIdKey.DeleteValue("",false);
+
+ // If there are no other values or subkeys then we can delete the ProgIdSubKey.
+ if ((ProgIdKey.SubKeyCount == 0) && (ProgIdKey.ValueCount == 0))
+ ClsIdKey.DeleteSubKey("ProgId");
+ }
+ }
+ }
+
+
+ //
+ // Remove entries in the HKEY_CLASS_ROOT\CLSID\<CLSID>\Implemented Categories\<Managed Category Guid> key.
+ //
+
+ using (RegistryKey CategoryKey = ClsIdKey.OpenSubKey(strImplementedCategoriesSubKey, true))
+ {
+ if (CategoryKey != null)
+ {
+ using (RegistryKey ManagedCategoryKey = CategoryKey.OpenSubKey(strManagedCategoryGuid, true))
+ {
+ if (ManagedCategoryKey != null)
+ {
+ // If there are no other values or subkeys then we can delete the ManagedCategoryKey.
+ if ((ManagedCategoryKey.SubKeyCount == 0) && (ManagedCategoryKey.ValueCount == 0))
+ CategoryKey.DeleteSubKey(strManagedCategoryGuid);
+ }
+ }
+
+ // If there are no other values or subkeys then we can delete the CategoryKey.
+ if ((CategoryKey.SubKeyCount == 0) && (CategoryKey.ValueCount == 0))
+ ClsIdKey.DeleteSubKey(strImplementedCategoriesSubKey);
+ }
+ }
+ }
+
+ // If there are no other values or subkeys then we can delete the ClsIdKey.
+ if ((ClsIdKey.SubKeyCount == 0) && (ClsIdKey.ValueCount == 0))
+ ClsIdRootKey.DeleteSubKey(strClsId);
+ }
+ }
+
+ // If there are no other values or subkeys then we can delete the CLSID key.
+ if ((ClsIdRootKey.SubKeyCount == 0) && (ClsIdRootKey.ValueCount == 0))
+ Registry.ClassesRoot.DeleteSubKey(strClsIdRootName);
+ }
+
+
+ //
+ // Remove the entries under HKEY_CLASS_ROOT\<wzProgId> key.
+ //
+
+ if (bAllVersionsGone)
+ {
+ if (strProgId != String.Empty)
+ {
+ using (RegistryKey TypeNameKey = Registry.ClassesRoot.OpenSubKey(strProgId, true))
+ {
+ if (TypeNameKey != null)
+ {
+ // Delete the values we created.
+ TypeNameKey.DeleteValue("",false);
+
+
+ //
+ // Remove the entries in the HKEY_CLASS_ROOT\<wzProgId>\CLSID key.
+ //
+
+ using (RegistryKey ProgIdClsIdKey = TypeNameKey.OpenSubKey("CLSID", true))
+ {
+ if (ProgIdClsIdKey != null)
+ {
+ // Delete the values we created.
+ ProgIdClsIdKey.DeleteValue("",false);
+
+ // If there are no other values or subkeys then we can delete the ProgIdClsIdKey.
+ if ((ProgIdClsIdKey.SubKeyCount == 0) && (ProgIdClsIdKey.ValueCount == 0))
+ TypeNameKey.DeleteSubKey("CLSID");
+ }
+ }
+
+ // If there are no other values or subkeys then we can delete the TypeNameKey.
+ if ((TypeNameKey.SubKeyCount == 0) && (TypeNameKey.ValueCount == 0))
+ Registry.ClassesRoot.DeleteSubKey(strProgId);
+ }
+ }
+ }
+ }
+ }
+
+ return bAllVersionsGone;
+ }
+
+ // UnregisterComImportedType
+ // Return:
+ // true: All version information are gone.
+ // false: There are still some version left in registry
+ [System.Security.SecurityCritical] // auto-generated
+ private bool UnregisterComImportedType(Type type, String strAsmVersion)
+ {
+ bool bAllVersionsGone = true;
+
+ String strClsId = "{" + Marshal.GenerateGuidForType(type).ToString().ToUpper(CultureInfo.InvariantCulture) + "}";
+
+ // Try to open the HKEY_CLASS_ROOT\CLSID key.
+ using (RegistryKey ClsIdRootKey = Registry.ClassesRoot.OpenSubKey(strClsIdRootName, true))
+ {
+ if (ClsIdRootKey != null)
+ {
+ // Try to open the HKEY_CLASS_ROOT\CLSID\<CLSID> key.
+ using (RegistryKey ClsIdKey = ClsIdRootKey.OpenSubKey(strClsId, true))
+ {
+ if (ClsIdKey != null)
+ {
+ // Try to open the HKEY_CLASS_ROOT\CLSID\<CLSID>\InProcServer32 key.
+ using (RegistryKey InProcServerKey = ClsIdKey.OpenSubKey("InprocServer32", true))
+ {
+ if (InProcServerKey != null)
+ {
+ // Delete the values we created.
+ InProcServerKey.DeleteValue("Assembly",false);
+ InProcServerKey.DeleteValue("Class",false);
+ InProcServerKey.DeleteValue("RuntimeVersion",false);
+ InProcServerKey.DeleteValue("CodeBase",false);
+
+ // Try to open the entries in HKEY_CLASS_ROOT\CLSID\<CLSID>\InProcServer32\<Version>
+ using (RegistryKey VersionSubKey = InProcServerKey.OpenSubKey(strAsmVersion,true))
+ {
+ if (VersionSubKey != null)
+ {
+ // Delete the value we created
+ VersionSubKey.DeleteValue("Assembly",false);
+ VersionSubKey.DeleteValue("Class",false);
+ VersionSubKey.DeleteValue("RuntimeVersion",false);
+ VersionSubKey.DeleteValue("CodeBase",false);
+
+ // If there are no other values or subkeys then we can delete the VersionSubKey
+ if ((VersionSubKey.SubKeyCount == 0) && (VersionSubKey.ValueCount == 0))
+ InProcServerKey.DeleteSubKey(strAsmVersion);
+ }
+ }
+
+ // If there are sub keys left then there are versions left.
+ if (InProcServerKey.SubKeyCount != 0)
+ bAllVersionsGone = false;
+
+ // If there are no other values or subkeys then we can delete the InProcServerKey.
+ if ((InProcServerKey.SubKeyCount == 0) && (InProcServerKey.ValueCount == 0))
+ ClsIdKey.DeleteSubKey("InprocServer32");
+ }
+ }
+
+ // If there are no other values or subkeys then we can delete the ClsIdKey.
+ if ((ClsIdKey.SubKeyCount == 0) && (ClsIdKey.ValueCount == 0))
+ ClsIdRootKey.DeleteSubKey(strClsId);
+ }
+ }
+
+ // If there are no other values or subkeys then we can delete the CLSID key.
+ if ((ClsIdRootKey.SubKeyCount == 0) && (ClsIdRootKey.ValueCount == 0))
+ Registry.ClassesRoot.DeleteSubKey(strClsIdRootName);
+ }
+ }
+
+ return bAllVersionsGone;
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ private void RegisterPrimaryInteropAssembly(RuntimeAssembly assembly, String strAsmCodeBase, PrimaryInteropAssemblyAttribute attr)
+ {
+ // Validate that the PIA has a strong name.
+ if (assembly.GetPublicKey().Length == 0)
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_PIAMustBeStrongNamed"));
+
+ String strTlbId = "{" + Marshal.GetTypeLibGuidForAssembly(assembly).ToString().ToUpper(CultureInfo.InvariantCulture) + "}";
+ String strVersion = attr.MajorVersion.ToString("x", CultureInfo.InvariantCulture) + "." + attr.MinorVersion.ToString("x", CultureInfo.InvariantCulture);
+
+ // Create the HKEY_CLASS_ROOT\TypeLib key.
+ using (RegistryKey TypeLibRootKey = Registry.ClassesRoot.CreateSubKey(strTlbRootName))
+ {
+ // Create the HKEY_CLASS_ROOT\TypeLib\<TLBID> key.
+ using (RegistryKey TypeLibKey = TypeLibRootKey.CreateSubKey(strTlbId))
+ {
+ // Create the HKEY_CLASS_ROOT\TypeLib\<TLBID>\<Major.Minor> key.
+ using (RegistryKey VersionSubKey = TypeLibKey.CreateSubKey(strVersion))
+ {
+ // Create the HKEY_CLASS_ROOT\TypeLib\<TLBID>\PrimaryInteropAssembly key.
+ VersionSubKey.SetValue("PrimaryInteropAssemblyName", assembly.FullName);
+ if (strAsmCodeBase != null)
+ VersionSubKey.SetValue("PrimaryInteropAssemblyCodeBase", strAsmCodeBase);
+ }
+ }
+ }
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ private void UnregisterPrimaryInteropAssembly(Assembly assembly, PrimaryInteropAssemblyAttribute attr)
+ {
+ String strTlbId = "{" + Marshal.GetTypeLibGuidForAssembly(assembly).ToString().ToUpper(CultureInfo.InvariantCulture) + "}";
+ String strVersion = attr.MajorVersion.ToString("x", CultureInfo.InvariantCulture) + "." + attr.MinorVersion.ToString("x", CultureInfo.InvariantCulture);
+
+ // Try to open the HKEY_CLASS_ROOT\TypeLib key.
+ using (RegistryKey TypeLibRootKey = Registry.ClassesRoot.OpenSubKey(strTlbRootName, true))
+ {
+ if (TypeLibRootKey != null)
+ {
+ // Try to open the HKEY_CLASS_ROOT\TypeLib\<TLBID> key.
+ using (RegistryKey TypeLibKey = TypeLibRootKey.OpenSubKey(strTlbId, true))
+ {
+ if (TypeLibKey != null)
+ {
+ // Try to open the HKEY_CLASS_ROOT\TypeLib<TLBID>\<Major.Minor> key.
+ using (RegistryKey VersionSubKey = TypeLibKey.OpenSubKey(strVersion, true))
+ {
+ if (VersionSubKey != null)
+ {
+ // Delete the values we created.
+ VersionSubKey.DeleteValue("PrimaryInteropAssemblyName",false);
+ VersionSubKey.DeleteValue("PrimaryInteropAssemblyCodeBase",false);
+
+ // If there are no other values or subkeys then we can delete the VersionKey.
+ if ((VersionSubKey.SubKeyCount == 0) && (VersionSubKey.ValueCount == 0))
+ TypeLibKey.DeleteSubKey(strVersion);
+ }
+ }
+
+ // If there are no other values or subkeys then we can delete the TypeLibKey.
+ if ((TypeLibKey.SubKeyCount == 0) && (TypeLibKey.ValueCount == 0))
+ TypeLibRootKey.DeleteSubKey(strTlbId);
+ }
+ }
+
+ // If there are no other values or subkeys then we can delete the TypeLib key.
+ if ((TypeLibRootKey.SubKeyCount == 0) && (TypeLibRootKey.ValueCount == 0))
+ Registry.ClassesRoot.DeleteSubKey(strTlbRootName);
+ }
+ }
+ }
+
+ private void EnsureManagedCategoryExists()
+ {
+ if (!ManagedCategoryExists())
+ {
+ // Create the HKEY_CLASS_ROOT\Component Category key.
+ using (RegistryKey ComponentCategoryKey = Registry.ClassesRoot.CreateSubKey(strComponentCategorySubKey))
+ {
+ // Create the HKEY_CLASS_ROOT\Component Category\<Managed Category Guid> key.
+ using (RegistryKey ManagedCategoryKey = ComponentCategoryKey.CreateSubKey(strManagedCategoryGuid))
+ {
+ ManagedCategoryKey.SetValue("0", strManagedCategoryDescription);
+ }
+ }
+ }
+ }
+
+ private static bool ManagedCategoryExists()
+ {
+ using (RegistryKey componentCategoryKey = Registry.ClassesRoot.OpenSubKey(strComponentCategorySubKey,
+#if FEATURE_MACL
+ RegistryKeyPermissionCheck.ReadSubTree))
+#else
+ false))
+#endif
+ {
+ if (componentCategoryKey == null)
+ return false;
+ using (RegistryKey managedCategoryKey = componentCategoryKey.OpenSubKey(strManagedCategoryGuid,
+#if FEATURE_MACL
+ RegistryKeyPermissionCheck.ReadSubTree))
+#else
+ false))
+#endif
+ {
+ if (managedCategoryKey == null)
+ return false;
+ object value = managedCategoryKey.GetValue("0");
+ if (value == null || value.GetType() != typeof(string))
+ return false;
+ string stringValue = (string)value;
+ if (stringValue != strManagedCategoryDescription)
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ private void CallUserDefinedRegistrationMethod(Type type, bool bRegister)
+ {
+ bool bFunctionCalled = false;
+
+ // Retrieve the attribute type to use to determine if a function is the requested user defined
+ // registration function.
+ Type RegFuncAttrType = null;
+ if(bRegister)
+ RegFuncAttrType = typeof(ComRegisterFunctionAttribute);
+ else
+ RegFuncAttrType = typeof(ComUnregisterFunctionAttribute);
+
+ for(Type currType = type; !bFunctionCalled && currType != null; currType = currType.BaseType)
+ {
+ // Retrieve all the methods.
+ MethodInfo[] aMethods = currType.GetMethods(BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Static);
+ int NumMethods = aMethods.Length;
+
+ // Go through all the methods and check for the ComRegisterMethod custom attribute.
+ for(int cMethods = 0;cMethods < NumMethods;cMethods++)
+ {
+ MethodInfo CurrentMethod = aMethods[cMethods];
+
+ // Check to see if the method has the custom attribute.
+ if(CurrentMethod.GetCustomAttributes(RegFuncAttrType, true).Length != 0)
+ {
+ // Check to see if the method is static before we call it.
+ if(!CurrentMethod.IsStatic)
+ {
+ if(bRegister)
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NonStaticComRegFunction",CurrentMethod.Name,currType.Name));
+ else
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NonStaticComUnRegFunction",CurrentMethod.Name,currType.Name));
+ }
+
+ // Finally check that the signature is string ret void.
+ ParameterInfo[] aParams = CurrentMethod.GetParameters();
+ if (CurrentMethod.ReturnType != typeof(void) ||
+ aParams == null ||
+ aParams.Length != 1 ||
+ (aParams[0].ParameterType != typeof(String) && aParams[0].ParameterType != typeof(Type)))
+ {
+ if(bRegister)
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_InvalidComRegFunctionSig",CurrentMethod.Name,currType.Name));
+ else
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_InvalidComUnRegFunctionSig",CurrentMethod.Name,currType.Name));
+ }
+
+ // There can only be one register and one unregister function per type.
+ if(bFunctionCalled)
+ {
+ if(bRegister)
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MultipleComRegFunctions",currType.Name));
+ else
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MultipleComUnRegFunctions",currType.Name));
+ }
+
+ // The function is valid so set up the arguments to call it.
+ Object[] objs = new Object[1];
+ if(aParams[0].ParameterType == typeof(String))
+ {
+ // We are dealing with the string overload of the function.
+ objs[0] = "HKEY_CLASSES_ROOT\\CLSID\\{" + Marshal.GenerateGuidForType(type).ToString().ToUpper(CultureInfo.InvariantCulture) + "}";
+ }
+ else
+ {
+ // We are dealing with the type overload of the function.
+ objs[0] = type;
+ }
+
+ // Invoke the COM register function.
+ CurrentMethod.Invoke(null, objs);
+
+ // Mark the function as having been called.
+ bFunctionCalled = true;
+ }
+ }
+ }
+ }
+
+ private Type GetBaseComImportType(Type type)
+ {
+ for (; type != null && !type.IsImport; type = type.BaseType);
+ return type;
+ }
+
+ private bool IsRegisteredAsValueType(Type type)
+ {
+ if (!type.IsValueType)
+ return false;
+
+ return true;
+ }
+
+ #endregion
+
+
+ #region FCalls and DllImports
+
+#if FEATURE_COMINTEROP_MANAGED_ACTIVATION
+ // GUID versioning can be controlled by using the GuidAttribute or
+ // letting the runtime generate it based on type and assembly strong name.
+ [System.Security.SecurityCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern void RegisterTypeForComClientsNative(Type type,ref Guid g);
+
+ // GUID versioning can be controlled by using the GuidAttribute or
+ // letting the runtime generate it based on type and assembly strong name.
+ [System.Security.SecurityCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern int RegisterTypeForComClientsExNative(Type t, RegistrationClassContext clsContext, RegistrationConnectionType flags);
+#endif // FEATURE_COMINTEROP_MANAGED_ACTIVATION
+
+ [DllImport(Win32Native.OLE32,CharSet=CharSet.Auto,PreserveSig=false)]
+ private static extern void CoRevokeClassObject(int cookie);
+ #endregion
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/RuntimeEnvironment.cs b/src/mscorlib/src/System/Runtime/InteropServices/RuntimeEnvironment.cs
new file mode 100644
index 0000000000..d722843ae8
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/RuntimeEnvironment.cs
@@ -0,0 +1,165 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: Runtime information
+**
+**
+=============================================================================*/
+
+using System;
+using System.Text;
+using System.IO;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Security;
+using System.Security.Permissions;
+using System.Reflection;
+using Microsoft.Win32;
+using System.Runtime.Versioning;
+using StackCrawlMark = System.Threading.StackCrawlMark;
+
+namespace System.Runtime.InteropServices {
+[System.Runtime.InteropServices.ComVisible(true)]
+#if FEATURE_CORECLR
+ static
+#endif
+ public class RuntimeEnvironment {
+
+#if !FEATURE_CORECLR
+ // This should have been a static class, but wasn't as of v3.5. Clearly, this is
+ // broken. We'll keep this in V4 for binary compat, but marked obsolete as error
+ // so migrated source code gets fixed. On Silverlight, this type exists but is
+ // not public.
+ [Obsolete("Do not create instances of the RuntimeEnvironment class. Call the static methods directly on this type instead", true)]
+ public RuntimeEnvironment()
+ {
+ // Should not have been instantiable - here for binary compatibility in V4.
+ }
+#endif
+
+ [System.Security.SecurityCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern String GetModuleFileName();
+
+ [System.Security.SecurityCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern String GetDeveloperPath();
+
+ [System.Security.SecurityCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern String GetHostBindingFile();
+
+#if !FEATURE_CORECLR
+ [System.Security.SecurityCritical] // auto-generated
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ internal static extern void _GetSystemVersion(StringHandleOnStack retVer);
+#endif //!FEATURE_CORECLR
+
+ public static bool FromGlobalAccessCache(Assembly a)
+ {
+ return a.GlobalAssemblyCache;
+ }
+
+#if !FEATURE_CORECLR
+ [System.Security.SecuritySafeCritical] // public member
+#endif
+ [MethodImpl (MethodImplOptions.NoInlining)]
+ public static String GetSystemVersion()
+ {
+#if FEATURE_CORECLR
+
+ return Assembly.GetExecutingAssembly().ImageRuntimeVersion;
+
+#else // FEATURE_CORECLR
+
+ String ver = null;
+ _GetSystemVersion(JitHelpers.GetStringHandleOnStack(ref ver));
+ return ver;
+
+#endif // FEATURE_CORECLR
+
+ }
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+ public static String GetRuntimeDirectory()
+ {
+ String dir = GetRuntimeDirectoryImpl();
+ new FileIOPermission(FileIOPermissionAccess.PathDiscovery, dir).Demand();
+ return dir;
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern String GetRuntimeDirectoryImpl();
+
+ // Returns the system ConfigurationFile
+ public static String SystemConfigurationFile {
+ [System.Security.SecuritySafeCritical] // auto-generated
+ get {
+ StringBuilder sb = new StringBuilder(Path.MaxPath);
+ sb.Append(GetRuntimeDirectory());
+ sb.Append(AppDomainSetup.RuntimeConfigurationFile);
+ String path = sb.ToString();
+
+ // Do security check
+ new FileIOPermission(FileIOPermissionAccess.PathDiscovery, path).Demand();
+
+ return path;
+ }
+ }
+
+#if FEATURE_COMINTEROP
+ [System.Security.SecurityCritical]
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private static extern IntPtr GetRuntimeInterfaceImpl(
+ [In, MarshalAs(UnmanagedType.LPStruct)] Guid clsid,
+ [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid);
+
+ //
+ // This function does the equivalent of calling GetInterface(clsid, riid) on the
+ // ICLRRuntimeInfo representing this runtime. See MetaHost.idl for a list of
+ // CLSIDs and IIDs supported by this method.
+ //
+ // Returns unmanaged pointer to requested interface on success. Throws
+ // COMException with failed HR if there is a QI failure.
+ //
+ [System.Security.SecurityCritical] // do not allow partial trust callers
+ [ComVisible(false)]
+ public static IntPtr GetRuntimeInterfaceAsIntPtr(Guid clsid, Guid riid)
+ {
+ return GetRuntimeInterfaceImpl(clsid, riid);
+ }
+
+ //
+ // This function does the equivalent of calling GetInterface(clsid, riid) on the
+ // ICLRRuntimeInfo representing this runtime. See MetaHost.idl for a list of
+ // CLSIDs and IIDs supported by this method.
+ //
+ // Returns an RCW to requested interface on success. Throws
+ // COMException with failed HR if there is a QI failure.
+ //
+ [System.Security.SecurityCritical] // do not allow partial trust callers
+ [ComVisible(false)]
+ public static object GetRuntimeInterfaceAsObject(Guid clsid, Guid riid)
+ {
+ IntPtr p = IntPtr.Zero;
+ try {
+ p = GetRuntimeInterfaceImpl(clsid, riid);
+ return Marshal.GetObjectForIUnknown(p);
+ } finally {
+ if(p != IntPtr.Zero) {
+ Marshal.Release(p);
+ }
+ }
+ }
+
+#endif // FEATURE_COMINTEROP
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/SEHException.cs b/src/mscorlib/src/System/Runtime/InteropServices/SEHException.cs
new file mode 100644
index 0000000000..b418d914ed
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/SEHException.cs
@@ -0,0 +1,54 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: Exception class for all Structured Exception Handling code.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices {
+ using System.Runtime.InteropServices;
+ using System;
+ using System.Runtime.Serialization;
+ // Exception for Structured Exception Handler exceptions.
+ //
+ [System.Runtime.InteropServices.ComVisible(true)]
+ [Serializable]
+ public class SEHException : ExternalException {
+ public SEHException()
+ : base() {
+ SetErrorCode(__HResults.E_FAIL);
+ }
+
+ public SEHException(String message)
+ : base(message) {
+ SetErrorCode(__HResults.E_FAIL);
+ }
+
+ public SEHException(String message, Exception inner)
+ : base(message, inner) {
+ SetErrorCode(__HResults.E_FAIL);
+ }
+
+ protected SEHException(SerializationInfo info, StreamingContext context) : base(info, context) {
+ }
+
+ // Exceptions can be resumable, meaning a filtered exception
+ // handler can correct the problem that caused the exception,
+ // and the code will continue from the point that threw the
+ // exception.
+ //
+ // Resumable exceptions aren't implemented in this version,
+ // but this method exists and always returns false.
+ //
+ public virtual bool CanResume()
+ {
+ return false;
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/SafeArrayRankMismatchException.cs b/src/mscorlib/src/System/Runtime/InteropServices/SafeArrayRankMismatchException.cs
new file mode 100644
index 0000000000..0f4caa21a1
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/SafeArrayRankMismatchException.cs
@@ -0,0 +1,41 @@
+// 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.
+
+/*=============================================================================
+**
+**
+** Purpose: This exception is thrown when the runtime rank of a safe array
+** is different than the array rank specified in the metadata.
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices {
+
+ using System;
+ using System.Runtime.Serialization;
+
+ [System.Runtime.InteropServices.ComVisible(true)]
+ [Serializable]
+ public class SafeArrayRankMismatchException : SystemException {
+ public SafeArrayRankMismatchException()
+ : base(Environment.GetResourceString("Arg_SafeArrayRankMismatchException")) {
+ SetErrorCode(__HResults.COR_E_SAFEARRAYRANKMISMATCH);
+ }
+
+ public SafeArrayRankMismatchException(String message)
+ : base(message) {
+ SetErrorCode(__HResults.COR_E_SAFEARRAYRANKMISMATCH);
+ }
+
+ public SafeArrayRankMismatchException(String message, Exception inner)
+ : base(message, inner) {
+ SetErrorCode(__HResults.COR_E_SAFEARRAYRANKMISMATCH);
+ }
+
+ protected SafeArrayRankMismatchException(SerializationInfo info, StreamingContext context) : base(info, context) {
+ }
+
+ }
+
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/SafeArrayTypeMismatchException.cs b/src/mscorlib/src/System/Runtime/InteropServices/SafeArrayTypeMismatchException.cs
new file mode 100644
index 0000000000..a5711c1ade
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/SafeArrayTypeMismatchException.cs
@@ -0,0 +1,42 @@
+// 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.
+
+/*=============================================================================
+**
+**
+** Purpose: This exception is thrown when the runtime type of an array
+** is different than the safe array sub type specified in the
+** metadata.
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices {
+
+ using System;
+ using System.Runtime.Serialization;
+
+ [System.Runtime.InteropServices.ComVisible(true)]
+ [Serializable]
+ public class SafeArrayTypeMismatchException : SystemException {
+ public SafeArrayTypeMismatchException()
+ : base(Environment.GetResourceString("Arg_SafeArrayTypeMismatchException")) {
+ SetErrorCode(__HResults.COR_E_SAFEARRAYTYPEMISMATCH);
+ }
+
+ public SafeArrayTypeMismatchException(String message)
+ : base(message) {
+ SetErrorCode(__HResults.COR_E_SAFEARRAYTYPEMISMATCH);
+ }
+
+ public SafeArrayTypeMismatchException(String message, Exception inner)
+ : base(message, inner) {
+ SetErrorCode(__HResults.COR_E_SAFEARRAYTYPEMISMATCH);
+ }
+
+ protected SafeArrayTypeMismatchException(SerializationInfo info, StreamingContext context) : base(info, context) {
+ }
+
+ }
+
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/SafeBuffer.cs b/src/mscorlib/src/System/Runtime/InteropServices/SafeBuffer.cs
new file mode 100644
index 0000000000..a659daf2b5
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/SafeBuffer.cs
@@ -0,0 +1,415 @@
+// 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.
+
+/*============================================================
+**
+** Purpose: Unsafe code that uses pointers should use
+** SafePointer to fix subtle lifetime problems with the
+** underlying resource.
+**
+===========================================================*/
+
+// Design points:
+// *) Avoid handle-recycling problems (including ones triggered via
+// resurrection attacks) for all accesses via pointers. This requires tying
+// together the lifetime of the unmanaged resource with the code that reads
+// from that resource, in a package that uses synchronization to enforce
+// the correct semantics during finalization. We're using SafeHandle's
+// ref count as a gate on whether the pointer can be dereferenced because that
+// controls the lifetime of the resource.
+//
+// *) Keep the penalties for using this class small, both in terms of space
+// and time. Having multiple threads reading from a memory mapped file
+// will already require 2 additional interlocked operations. If we add in
+// a "current position" concept, that requires additional space in memory and
+// synchronization. Since the position in memory is often (but not always)
+// something that can be stored on the stack, we can save some memory by
+// excluding it from this object. However, avoiding the need for
+// synchronization is a more significant win. This design allows multiple
+// threads to read and write memory simultaneously without locks (as long as
+// you don't write to a region of memory that overlaps with what another
+// thread is accessing).
+//
+// *) Space-wise, we use the following memory, including SafeHandle's fields:
+// Object Header MT* handle int bool bool <2 pad bytes> length
+// On 32 bit platforms: 24 bytes. On 64 bit platforms: 40 bytes.
+// (We can safe 4 bytes on x86 only by shrinking SafeHandle)
+//
+// *) Wrapping a SafeHandle would have been a nice solution, but without an
+// ordering between critical finalizable objects, it would have required
+// changes to each SafeHandle subclass to opt in to being usable from a
+// SafeBuffer (or some clever exposure of SafeHandle's state fields and a
+// way of forcing ReleaseHandle to run even after the SafeHandle has been
+// finalized with a ref count > 1). We can use less memory and create fewer
+// objects by simply inserting a SafeBuffer into the class hierarchy.
+//
+// *) In an ideal world, we could get marshaling support for SafeBuffer that
+// would allow us to annotate a P/Invoke declaration, saying this parameter
+// specifies the length of the buffer, and the units of that length are X.
+// P/Invoke would then pass that size parameter to SafeBuffer.
+// [DllImport(...)]
+// static extern SafeMemoryHandle AllocCharBuffer(int numChars);
+// If we could put an attribute on the SafeMemoryHandle saying numChars is
+// the element length, and it must be multiplied by 2 to get to the byte
+// length, we can simplify the usage model for SafeBuffer.
+//
+// *) This class could benefit from a constraint saying T is a value type
+// containing no GC references.
+
+// Implementation notes:
+// *) The Initialize method must be called before you use any instance of
+// a SafeBuffer. To avoid race conditions when storing SafeBuffers in statics,
+// you either need to take a lock when publishing the SafeBuffer, or you
+// need to create a local, initialize the SafeBuffer, then assign to the
+// static variable (perhaps using Interlocked.CompareExchange). Of course,
+// assignments in a static class constructor are under a lock implicitly.
+
+
+namespace System.Runtime.InteropServices
+{
+using System;
+using System.Security.Permissions;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using System.Runtime.ConstrainedExecution;
+using System.Runtime.Versioning;
+using Microsoft.Win32.SafeHandles;
+using System.Diagnostics.Contracts;
+
+
+ [System.Security.SecurityCritical]
+ public abstract unsafe class SafeBuffer : SafeHandleZeroOrMinusOneIsInvalid
+ {
+ // Steal UIntPtr.MaxValue as our uninitialized value.
+ private static readonly UIntPtr Uninitialized = (UIntPtr.Size == 4) ?
+ ((UIntPtr) UInt32.MaxValue) : ((UIntPtr) UInt64.MaxValue);
+
+ private UIntPtr _numBytes;
+
+ protected SafeBuffer(bool ownsHandle) : base(ownsHandle)
+ {
+ _numBytes = Uninitialized;
+ }
+
+ /// <summary>
+ /// Specifies the size of the region of memory, in bytes. Must be
+ /// called before using the SafeBuffer.
+ /// </summary>
+ /// <param name="numBytes">Number of valid bytes in memory.</param>
+ [CLSCompliant(false)]
+ public void Initialize(ulong numBytes)
+ {
+ if (numBytes < 0)
+ throw new ArgumentOutOfRangeException("numBytes", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ if (IntPtr.Size == 4 && numBytes > UInt32.MaxValue)
+ throw new ArgumentOutOfRangeException("numBytes", Environment.GetResourceString("ArgumentOutOfRange_AddressSpace"));
+ Contract.EndContractBlock();
+
+ if (numBytes >= (ulong)Uninitialized)
+ throw new ArgumentOutOfRangeException("numBytes", Environment.GetResourceString("ArgumentOutOfRange_UIntPtrMax-1"));
+
+ _numBytes = (UIntPtr) numBytes;
+ }
+
+ /// <summary>
+ /// Specifies the the size of the region in memory, as the number of
+ /// elements in an array. Must be called before using the SafeBuffer.
+ /// </summary>
+ [CLSCompliant(false)]
+ public void Initialize(uint numElements, uint sizeOfEachElement)
+ {
+ if (numElements < 0)
+ throw new ArgumentOutOfRangeException("numElements", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ if (sizeOfEachElement < 0)
+ throw new ArgumentOutOfRangeException("sizeOfEachElement", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+
+ if (IntPtr.Size == 4 && numElements * sizeOfEachElement > UInt32.MaxValue)
+ throw new ArgumentOutOfRangeException("numBytes", Environment.GetResourceString("ArgumentOutOfRange_AddressSpace"));
+ Contract.EndContractBlock();
+
+ if (numElements * sizeOfEachElement >= (ulong)Uninitialized)
+ throw new ArgumentOutOfRangeException("numElements", Environment.GetResourceString("ArgumentOutOfRange_UIntPtrMax-1"));
+
+ _numBytes = checked((UIntPtr) (numElements * sizeOfEachElement));
+ }
+
+ /// <summary>
+ /// Specifies the the size of the region in memory, as the number of
+ /// elements in an array. Must be called before using the SafeBuffer.
+ /// </summary>
+ [CLSCompliant(false)]
+ public void Initialize<T>(uint numElements) where T : struct
+ {
+ Initialize(numElements, Marshal.AlignedSizeOf<T>());
+ }
+
+ // Callers should ensure that they check whether the pointer ref param
+ // is null when AcquirePointer returns. If it is not null, they must
+ // call ReleasePointer in a CER. This method calls DangerousAddRef
+ // & exposes the pointer. Unlike Read, it does not alter the "current
+ // position" of the pointer. Here's how to use it:
+ //
+ // byte* pointer = null;
+ // RuntimeHelpers.PrepareConstrainedRegions();
+ // try {
+ // safeBuffer.AcquirePointer(ref pointer);
+ // // Use pointer here, with your own bounds checking
+ // }
+ // finally {
+ // if (pointer != null)
+ // safeBuffer.ReleasePointer();
+ // }
+ //
+ // Note: If you cast this byte* to a T*, you have to worry about
+ // whether your pointer is aligned. Additionally, you must take
+ // responsibility for all bounds checking with this pointer.
+ /// <summary>
+ /// Obtain the pointer from a SafeBuffer for a block of code,
+ /// with the express responsibility for bounds checking and calling
+ /// ReleasePointer later within a CER to ensure the pointer can be
+ /// freed later. This method either completes successfully or
+ /// throws an exception and returns with pointer set to null.
+ /// </summary>
+ /// <param name="pointer">A byte*, passed by reference, to receive
+ /// the pointer from within the SafeBuffer. You must set
+ /// pointer to null before calling this method.</param>
+ [CLSCompliant(false)]
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
+ public void AcquirePointer(ref byte* pointer)
+ {
+ if (_numBytes == Uninitialized)
+ throw NotInitialized();
+
+ pointer = null;
+ RuntimeHelpers.PrepareConstrainedRegions();
+ try
+ {
+ }
+ finally
+ {
+ bool junk = false;
+ DangerousAddRef(ref junk);
+ pointer = (byte*)handle;
+ }
+ }
+
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ public void ReleasePointer()
+ {
+ if (_numBytes == Uninitialized)
+ throw NotInitialized();
+
+ DangerousRelease();
+ }
+
+ /// <summary>
+ /// Read a value type from memory at the given offset. This is
+ /// equivalent to: return *(T*)(bytePtr + byteOffset);
+ /// </summary>
+ /// <typeparam name="T">The value type to read</typeparam>
+ /// <param name="byteOffset">Where to start reading from memory. You
+ /// may have to consider alignment.</param>
+ /// <returns>An instance of T read from memory.</returns>
+ [CLSCompliant(false)]
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
+ public T Read<T>(ulong byteOffset) where T : struct {
+ if (_numBytes == Uninitialized)
+ throw NotInitialized();
+
+ uint sizeofT = Marshal.SizeOfType(typeof(T));
+ byte* ptr = (byte*)handle + byteOffset;
+ SpaceCheck(ptr, sizeofT);
+
+ // return *(T*) (_ptr + byteOffset);
+ T value;
+ bool mustCallRelease = false;
+ RuntimeHelpers.PrepareConstrainedRegions();
+ try
+ {
+ DangerousAddRef(ref mustCallRelease);
+
+ GenericPtrToStructure<T>(ptr, out value, sizeofT);
+ }
+ finally
+ {
+ if (mustCallRelease)
+ DangerousRelease();
+ }
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
+ public void ReadArray<T>(ulong byteOffset, T[] array, int index, int count)
+ where T : struct
+ {
+ if (array == null)
+ throw new ArgumentNullException("array", Environment.GetResourceString("ArgumentNull_Buffer"));
+ if (index < 0)
+ throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ if (count < 0)
+ throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ if (array.Length - index < count)
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ Contract.EndContractBlock();
+
+ if (_numBytes == Uninitialized)
+ throw NotInitialized();
+
+ uint sizeofT = Marshal.SizeOfType(typeof(T));
+ uint alignedSizeofT = Marshal.AlignedSizeOf<T>();
+ byte* ptr = (byte*)handle + byteOffset;
+ SpaceCheck(ptr, checked((ulong)(alignedSizeofT * count)));
+
+ bool mustCallRelease = false;
+ RuntimeHelpers.PrepareConstrainedRegions();
+ try
+ {
+ DangerousAddRef(ref mustCallRelease);
+
+ for (int i = 0; i < count; i++)
+ unsafe { GenericPtrToStructure<T>(ptr + alignedSizeofT * i, out array[i + index], sizeofT); }
+ }
+ finally
+ {
+ if (mustCallRelease)
+ DangerousRelease();
+ }
+ }
+
+ /// <summary>
+ /// Write a value type to memory at the given offset. This is
+ /// equivalent to: *(T*)(bytePtr + byteOffset) = value;
+ /// </summary>
+ /// <typeparam name="T">The type of the value type to write to memory.</typeparam>
+ /// <param name="byteOffset">The location in memory to write to. You
+ /// may have to consider alignment.</param>
+ /// <param name="value">The value type to write to memory.</param>
+ [CLSCompliant(false)]
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
+ public void Write<T>(ulong byteOffset, T value) where T : struct {
+ if (_numBytes == Uninitialized)
+ throw NotInitialized();
+
+ uint sizeofT = Marshal.SizeOfType(typeof(T));
+ byte* ptr = (byte*)handle + byteOffset;
+ SpaceCheck(ptr, sizeofT);
+
+ // *((T*) (_ptr + byteOffset)) = value;
+ bool mustCallRelease = false;
+ RuntimeHelpers.PrepareConstrainedRegions();
+ try
+ {
+ DangerousAddRef(ref mustCallRelease);
+ GenericStructureToPtr(ref value, ptr, sizeofT);
+ }
+ finally
+ {
+ if (mustCallRelease)
+ DangerousRelease();
+ }
+ }
+
+ [CLSCompliant(false)]
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
+ public void WriteArray<T>(ulong byteOffset, T[] array, int index, int count)
+ where T : struct
+ {
+ if (array == null)
+ throw new ArgumentNullException("array", Environment.GetResourceString("ArgumentNull_Buffer"));
+ if (index < 0)
+ throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ if (count < 0)
+ throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ if (array.Length - index < count)
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ Contract.EndContractBlock();
+
+ if (_numBytes == Uninitialized)
+ throw NotInitialized();
+
+ uint sizeofT = Marshal.SizeOfType(typeof(T));
+ uint alignedSizeofT = Marshal.AlignedSizeOf<T>();
+ byte* ptr = (byte*)handle + byteOffset;
+ SpaceCheck(ptr, checked((ulong)(alignedSizeofT * count)));
+
+ bool mustCallRelease = false;
+ RuntimeHelpers.PrepareConstrainedRegions();
+ try
+ {
+ DangerousAddRef(ref mustCallRelease);
+ for (int i = 0; i < count; i++)
+ unsafe { GenericStructureToPtr(ref array[i + index], ptr + alignedSizeofT * i, sizeofT); }
+ }
+ finally
+ {
+ if (mustCallRelease)
+ DangerousRelease();
+ }
+ }
+
+
+ /// <summary>
+ /// Returns the number of bytes in the memory region.
+ /// </summary>
+ [CLSCompliant(false)]
+ public ulong ByteLength {
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ get {
+ if (_numBytes == Uninitialized)
+ throw NotInitialized();
+
+ return (ulong) _numBytes;
+ }
+ }
+
+ /* No indexer. The perf would be misleadingly bad. People should use
+ * AcquirePointer and ReleasePointer instead. */
+
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ private void SpaceCheck(byte* ptr, ulong sizeInBytes)
+ {
+ if ((ulong)_numBytes < sizeInBytes)
+ NotEnoughRoom();
+ if ((ulong)(ptr - (byte*) handle) > ((ulong)_numBytes) - sizeInBytes)
+ NotEnoughRoom();
+ }
+
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ private static void NotEnoughRoom()
+ {
+ throw new ArgumentException(Environment.GetResourceString("Arg_BufferTooSmall"));
+ }
+
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ private static InvalidOperationException NotInitialized()
+ {
+ Contract.Assert(false, "Uninitialized SafeBuffer! Someone needs to call Initialize before using this instance!");
+ return new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MustCallInitialize"));
+ }
+
+ // FCALL limitations mean we can't have generic FCALL methods. However, we can pass
+ // TypedReferences to FCALL methods.
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ internal static void GenericPtrToStructure<T>(byte* ptr, out T structure, uint sizeofT) where T : struct
+ {
+ structure = default(T); // Dummy assignment to silence the compiler
+ PtrToStructureNative(ptr, __makeref(structure), sizeofT);
+ }
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ private static extern void PtrToStructureNative(byte* ptr, /*out T*/ TypedReference structure, uint sizeofT);
+
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ internal static void GenericStructureToPtr<T>(ref T structure, byte* ptr, uint sizeofT) where T : struct
+ {
+ StructureToPtrNative(__makeref(structure), ptr, sizeofT);
+ }
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ private static extern void StructureToPtrNative(/*ref T*/ TypedReference structure, byte* ptr, uint sizeofT);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/SafeHandle.cs b/src/mscorlib/src/System/Runtime/InteropServices/SafeHandle.cs
new file mode 100644
index 0000000000..c26852874d
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/SafeHandle.cs
@@ -0,0 +1,317 @@
+// 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.
+
+/*============================================================
+**
+**
+**
+** A specially designed handle wrapper to ensure we never leak
+** an OS handle. The runtime treats this class specially during
+** P/Invoke marshaling and finalization. Users should write
+** subclasses of SafeHandle for each distinct handle type.
+**
+**
+===========================================================*/
+
+namespace System.Runtime.InteropServices {
+
+using System;
+using System.Reflection;
+using System.Threading;
+using System.Security.Permissions;
+using System.Runtime;
+using System.Runtime.CompilerServices;
+using System.IO;
+using System.Runtime.ConstrainedExecution;
+using System.Runtime.Versioning;
+
+/*
+ Problems addressed by the SafeHandle class:
+ 1) Critical finalization - ensure we never leak OS resources in SQL. Done
+ without running truly arbitrary & unbounded amounts of managed code.
+ 2) Reduced graph promotion - during finalization, keep object graph small
+ 3) GC.KeepAlive behavior - P/Invoke vs. finalizer thread race conditions (HandleRef)
+ 4) Elimination of security race conditions w/ explicit calls to Close (HandleProtector)
+ 5) Enforcement of the above via the type system - Don't use IntPtr anymore.
+ 6) Allows the handle lifetime to be controlled externally via a boolean.
+
+ Subclasses of SafeHandle will implement the ReleaseHandle abstract method
+ used to execute any code required to free the handle. This method will be
+ prepared as a constrained execution region at instance construction time
+ (along with all the methods in its statically determinable call graph). This
+ implies that we won't get any inconvenient jit allocation errors or rude
+ thread abort interrupts while releasing the handle but the user must still
+ write careful code to avoid injecting fault paths of their own (see the CER
+ spec for more details). In particular, any sub-methods you call should be
+ decorated with a reliability contract of the appropriate level. In most cases
+ this should be:
+ ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)
+ Also, any P/Invoke methods should use the SuppressUnmanagedCodeSecurity
+ attribute to avoid a runtime security check that can also inject failures
+ (even if the check is guaranteed to pass).
+
+ The GC will run ReleaseHandle methods after any normal finalizers have been
+ run for objects that were collected at the same time. This ensures classes
+ like FileStream can run a normal finalizer to flush out existing buffered
+ data. This is key - it means adding this class to a class like FileStream does
+ not alter our current semantics w.r.t. finalization today.
+
+ Subclasses must also implement the IsInvalid property so that the
+ infrastructure can tell when critical finalization is actually required.
+ Again, this method is prepared ahead of time. It's envisioned that direct
+ subclasses of SafeHandle will provide an IsInvalid implementation that suits
+ the general type of handle they support (null is invalid, -1 is invalid etc.)
+ and then these classes will be further derived for specific safe handle types.
+
+ Most classes using SafeHandle should not provide a finalizer. If they do
+ need to do so (ie, for flushing out file buffers, needing to write some data
+ back into memory, etc), then they can provide a finalizer that will be
+ guaranteed to run before the SafeHandle's critical finalizer.
+
+ Note that SafeHandle's ReleaseHandle is called from a constrained execution
+ region, and is eagerly prepared before we create your class. This means you
+ should only call methods with an appropriate reliability contract from your
+ ReleaseHandle method.
+
+ Subclasses are expected to be written as follows (note that
+ SuppressUnmanagedCodeSecurity should always be used on any P/Invoke methods
+ invoked as part of ReleaseHandle, in order to switch the security check from
+ runtime to jit time and thus remove a possible failure path from the
+ invocation of the method):
+
+ internal sealed MySafeHandleSubclass : SafeHandle {
+ // Called by P/Invoke when returning SafeHandles
+ private MySafeHandleSubclass() : base(IntPtr.Zero, true)
+ {
+ }
+
+ // If & only if you need to support user-supplied handles
+ internal MySafeHandleSubclass(IntPtr preexistingHandle, bool ownsHandle) : base(IntPtr.Zero, ownsHandle)
+ {
+ SetHandle(preexistingHandle);
+ }
+
+ // Do not provide a finalizer - SafeHandle's critical finalizer will
+ // call ReleaseHandle for you.
+
+ public override bool IsInvalid {
+ get { return handle == IntPtr.Zero; }
+ }
+
+ override protected bool ReleaseHandle()
+ {
+ return MyNativeMethods.CloseHandle(handle);
+ }
+ }
+
+ Then elsewhere to create one of these SafeHandles, define a method
+ with the following type of signature (CreateFile follows this model).
+ Note that when returning a SafeHandle like this, P/Invoke will call your
+ class's default constructor. Also, you probably want to define CloseHandle
+ somewhere, and remember to apply a reliability contract to it.
+
+ [SuppressUnmanagedCodeSecurity]
+ internal static class MyNativeMethods {
+ [DllImport("kernel32")]
+ private static extern MySafeHandleSubclass CreateHandle(int someState);
+
+ [DllImport("kernel32", SetLastError=true), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ private static extern bool CloseHandle(IntPtr handle);
+ }
+
+ Drawbacks with this implementation:
+ 1) Requires some magic to run the critical finalizer.
+ 2) Requires more memory than just an IntPtr.
+ 3) If you use DangerousAddRef and forget to call DangerousRelease, you can leak a SafeHandle. Use CER's & don't do that.
+ */
+
+
+// This class should not be serializable - it's a handle. We require unmanaged
+// code permission to subclass SafeHandle to prevent people from writing a
+// subclass and suddenly being able to run arbitrary native code with the
+// same signature as CloseHandle. This is technically a little redundant, but
+// we'll do this to ensure we've cut off all attack vectors. Similarly, all
+// methods have a link demand to ensure untrusted code cannot directly edit
+// or alter a handle.
+[System.Security.SecurityCritical] // auto-generated_required
+#if !FEATURE_CORECLR
+[SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode=true)]
+#endif
+public abstract class SafeHandle : CriticalFinalizerObject, IDisposable
+{
+ // ! Do not add or rearrange fields as the EE depends on this layout.
+ //------------------------------------------------------------------
+#if DEBUG
+ // FxCop thinks this field is marshaled and so it raises a CA2101 error unless
+ // we specify this. In practice this is never presented to Win32.
+ [MarshalAs(UnmanagedType.LPWStr)]
+ private String _stackTrace; // Where we allocated this SafeHandle.
+#endif
+ protected IntPtr handle; // this must be protected so derived classes can use out params.
+ private int _state; // Combined ref count and closed/disposed flags (so we can atomically modify them).
+ private bool _ownsHandle; // Whether we can release this handle.
+#pragma warning disable 414
+ private bool _fullyInitialized; // Whether constructor completed.
+#pragma warning restore 414
+
+ // Creates a SafeHandle class. Users must then set the Handle property.
+ // To prevent the SafeHandle from being freed, write a subclass that
+ // doesn't define a finalizer.
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
+ protected SafeHandle(IntPtr invalidHandleValue, bool ownsHandle)
+ {
+ handle = invalidHandleValue;
+ _state = 4; // Ref count 1 and not closed or disposed.
+ _ownsHandle = ownsHandle;
+
+ if (!ownsHandle)
+ GC.SuppressFinalize(this);
+
+#if DEBUG
+ if (BCLDebug.SafeHandleStackTracesEnabled)
+ _stackTrace = Environment.GetStackTrace(null, false);
+ else
+ _stackTrace = "For a stack trace showing who allocated this SafeHandle, set SafeHandleStackTraces to 1 and rerun your app.";
+#endif
+
+ // Set this last to prevent SafeHandle's finalizer from freeing an
+ // invalid handle. This means we don't have to worry about
+ // ThreadAbortExceptions interrupting this constructor or the managed
+ // constructors on subclasses that call this constructor.
+ _fullyInitialized = true;
+ }
+
+#if FEATURE_CORECLR
+ // Migrating InheritanceDemands requires this default ctor, so we can mark it critical
+ protected SafeHandle()
+ {
+ BCLDebug.Assert(false, "SafeHandle's protected default ctor should never be used!");
+ throw new NotImplementedException();
+ }
+#endif
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+ ~SafeHandle()
+ {
+ Dispose(false);
+ }
+
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ extern void InternalFinalize();
+
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ protected void SetHandle(IntPtr handle) {
+ this.handle = handle;
+ }
+
+ // This method is necessary for getting an IntPtr out of a SafeHandle.
+ // Used to tell whether a call to create the handle succeeded by comparing
+ // the handle against a known invalid value, and for backwards
+ // compatibility to support the handle properties returning IntPtrs on
+ // many of our Framework classes.
+ // Note that this method is dangerous for two reasons:
+ // 1) If the handle has been marked invalid with SetHandleasInvalid,
+ // DangerousGetHandle will still return the original handle value.
+ // 2) The handle returned may be recycled at any point. At best this means
+ // the handle might stop working suddenly. At worst, if the handle or
+ // the resource the handle represents is exposed to untrusted code in
+ // any way, this can lead to a handle recycling security attack (i.e. an
+ // untrusted caller can query data on the handle you've just returned
+ // and get back information for an entirely unrelated resource).
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ public IntPtr DangerousGetHandle()
+ {
+ return handle;
+ }
+
+ public bool IsClosed {
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ get { return (_state & 1) == 1; }
+ }
+
+ public abstract bool IsInvalid {
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ get;
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ public void Close() {
+ Dispose(true);
+ }
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ public void Dispose() {
+ Dispose(true);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ InternalDispose();
+ else
+ InternalFinalize();
+ }
+
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private extern void InternalDispose();
+
+ // This should only be called for cases when you know for a fact that
+ // your handle is invalid and you want to record that information.
+ // An example is calling a syscall and getting back ERROR_INVALID_HANDLE.
+ // This method will normally leak handles!
+ [System.Security.SecurityCritical] // auto-generated
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public extern void SetHandleAsInvalid();
+
+ // Implement this abstract method in your derived class to specify how to
+ // free the handle. Be careful not write any code that's subject to faults
+ // in this method (the runtime will prepare the infrastructure for you so
+ // that no jit allocations etc. will occur, but don't allocate memory unless
+ // you can deal with the failure and still free the handle).
+ // The boolean returned should be true for success and false if the runtime
+ // should fire a SafeHandleCriticalFailure MDA (CustomerDebugProbe) if that
+ // MDA is enabled.
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ protected abstract bool ReleaseHandle();
+
+ // Add a reason why this handle should not be relinquished (i.e. have
+ // ReleaseHandle called on it). This method has dangerous in the name since
+ // it must always be used carefully (e.g. called within a CER) to avoid
+ // leakage of the handle. It returns a boolean indicating whether the
+ // increment was actually performed to make it easy for program logic to
+ // back out in failure cases (i.e. is a call to DangerousRelease needed).
+ // It is passed back via a ref parameter rather than as a direct return so
+ // that callers need not worry about the atomicity of calling the routine
+ // and assigning the return value to a variable (the variable should be
+ // explicitly set to false prior to the call). The only failure cases are
+ // when the method is interrupted prior to processing by a thread abort or
+ // when the handle has already been (or is in the process of being)
+ // released.
+ [System.Security.SecurityCritical] // auto-generated
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public extern void DangerousAddRef(ref bool success);
+
+ // Partner to DangerousAddRef. This should always be successful when used in
+ // a correct manner (i.e. matching a successful DangerousAddRef and called
+ // from a region such as a CER where a thread abort cannot interrupt
+ // processing). In the same way that unbalanced DangerousAddRef calls can
+ // cause resource leakage, unbalanced DangerousRelease calls may cause
+ // invalid handle states to become visible to other threads. This
+ // constitutes a potential security hole (via handle recycling) as well as a
+ // correctness problem -- so don't ever expose Dangerous* calls out to
+ // untrusted code.
+ [System.Security.SecurityCritical] // auto-generated
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public extern void DangerousRelease();
+}
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/SafeHeapHandle.cs b/src/mscorlib/src/System/Runtime/InteropServices/SafeHeapHandle.cs
new file mode 100644
index 0000000000..b0c422d0c0
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/SafeHeapHandle.cs
@@ -0,0 +1,115 @@
+// 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.
+
+namespace System.Runtime.InteropServices
+{
+ /// <summary>
+ /// Handle for heap memory that allows tracking of capacity and reallocating.
+ /// </summary>
+ [System.Security.SecurityCritical]
+ internal sealed class SafeHeapHandle : SafeBuffer
+ {
+ /// <summary>
+ /// Allocate a buffer of the given size if requested.
+ /// </summary>
+ /// <param name="byteLength">Required size in bytes. Must be less than UInt32.MaxValue for 32 bit or UInt64.MaxValue for 64 bit.</param>
+ /// <exception cref="OutOfMemoryException">Thrown if the requested memory size cannot be allocated.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">Thrown if size is greater than the maximum memory size.</exception>
+ public SafeHeapHandle(ulong byteLength) : base(ownsHandle: true)
+ {
+ Resize(byteLength);
+ }
+
+ public override bool IsInvalid
+ {
+ [System.Security.SecurityCritical]
+ get
+ { return handle == IntPtr.Zero; }
+ }
+
+ /// <summary>
+ /// Resize the buffer to the given size if requested.
+ /// </summary>
+ /// <param name="byteLength">Required size in bytes. Must be less than UInt32.MaxValue for 32 bit or UInt64.MaxValue for 64 bit.</param>
+ /// <exception cref="OutOfMemoryException">Thrown if the requested memory size cannot be allocated.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">Thrown if size is greater than the maximum memory size.</exception>
+ public void Resize(ulong byteLength)
+ {
+ if (IsClosed) throw new ObjectDisposedException("SafeHeapHandle");
+
+ ulong originalLength = 0;
+ if (handle == IntPtr.Zero)
+ {
+ handle = Marshal.AllocHGlobal((IntPtr)byteLength);
+ }
+ else
+ {
+ originalLength = ByteLength;
+
+ // This may or may not be the same handle, may realloc in place. If the
+ // handle changes Windows will deal with the old handle, trying to free it will
+ // cause an error.
+ handle = Marshal.ReAllocHGlobal(pv: handle, cb: (IntPtr)byteLength);
+ }
+
+ if (handle == IntPtr.Zero)
+ {
+ // Only real plausible answer
+ throw new OutOfMemoryException();
+ }
+
+ if (byteLength > originalLength)
+ {
+ // Add pressure
+ ulong addedBytes = byteLength - originalLength;
+ if (addedBytes > long.MaxValue)
+ {
+ GC.AddMemoryPressure(long.MaxValue);
+ GC.AddMemoryPressure((long)(addedBytes - long.MaxValue));
+ }
+ else
+ {
+ GC.AddMemoryPressure((long)addedBytes);
+ }
+ }
+ else
+ {
+ // Shrank or did nothing, release pressure if needed
+ RemoveMemoryPressure(originalLength - byteLength);
+ }
+
+ Initialize(byteLength);
+ }
+
+ private void RemoveMemoryPressure(ulong removedBytes)
+ {
+ if (removedBytes == 0) return;
+
+ if (removedBytes > long.MaxValue)
+ {
+ GC.RemoveMemoryPressure(long.MaxValue);
+ GC.RemoveMemoryPressure((long)(removedBytes - long.MaxValue));
+ }
+ else
+ {
+ GC.RemoveMemoryPressure((long)removedBytes);
+ }
+ }
+
+ [System.Security.SecurityCritical]
+ protected override bool ReleaseHandle()
+ {
+ IntPtr handle = this.handle;
+ this.handle = IntPtr.Zero;
+
+ if (handle != IntPtr.Zero)
+ {
+ RemoveMemoryPressure(ByteLength);
+ Marshal.FreeHGlobal(handle);
+ }
+
+ return true;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/StringBuffer.cs b/src/mscorlib/src/System/Runtime/InteropServices/StringBuffer.cs
new file mode 100644
index 0000000000..15b1b6ae8e
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/StringBuffer.cs
@@ -0,0 +1,402 @@
+// 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.
+
+namespace System.Runtime.InteropServices
+{
+ /// <summary>
+ /// Native buffer that deals in char size increments. Dispose to free memory. Allows buffers larger
+ /// than a maximum size string to enable working with very large string arrays. Always makes ordinal
+ /// comparisons.
+ ///
+ /// A more performant replacement for StringBuilder when performing native interop.
+ /// </summary>
+ /// <remarks>
+ /// Suggested use through P/Invoke: define DllImport arguments that take a character buffer as IntPtr.
+ /// NativeStringBuffer has an implicit conversion to IntPtr.
+ /// </remarks>
+ internal class StringBuffer : NativeBuffer
+ {
+ private uint _length;
+
+ /// <summary>
+ /// Instantiate the buffer with capacity for at least the specified number of characters. Capacity
+ /// includes the trailing null character.
+ /// </summary>
+ public StringBuffer(uint initialCapacity = 0)
+ : base(initialCapacity * (ulong)sizeof(char))
+ {
+ }
+
+ /// <summary>
+ /// Instantiate the buffer with a copy of the specified string.
+ /// </summary>
+ public StringBuffer(string initialContents)
+ : base(0)
+ {
+ // We don't pass the count of bytes to the base constructor, appending will
+ // initialize to the correct size for the specified initial contents.
+ if (initialContents != null)
+ {
+ Append(initialContents);
+ }
+ }
+
+ /// <summary>
+ /// Instantiate the buffer with a copy of the specified StringBuffer.
+ /// </summary>
+ public StringBuffer(StringBuffer initialContents)
+ : base(0)
+ {
+ // We don't pass the count of bytes to the base constructor, appending will
+ // initialize to the correct size for the specified initial contents.
+ if (initialContents != null)
+ {
+ Append(initialContents);
+ }
+ }
+
+ /// <summary>
+ /// Get/set the character at the given index.
+ /// </summary>
+ /// <exception cref="ArgumentOutOfRangeException">Thrown if attempting to index outside of the buffer length.</exception>
+ public unsafe char this[uint index]
+ {
+ [System.Security.SecuritySafeCritical]
+ get
+ {
+ if (index >= _length) throw new ArgumentOutOfRangeException("index");
+ return CharPointer[index];
+ }
+ [System.Security.SecuritySafeCritical]
+ set
+ {
+ if (index >= _length) throw new ArgumentOutOfRangeException("index");
+ CharPointer[index] = value;
+ }
+ }
+
+ /// <summary>
+ /// Character capacity of the buffer. Includes the count for the trailing null character.
+ /// </summary>
+ public uint CharCapacity
+ {
+ [System.Security.SecuritySafeCritical]
+ get
+ {
+ ulong byteCapacity = ByteCapacity;
+ ulong charCapacity = byteCapacity == 0 ? 0 : byteCapacity / sizeof(char);
+ return charCapacity > uint.MaxValue ? uint.MaxValue : (uint)charCapacity;
+ }
+ }
+
+ /// <summary>
+ /// Ensure capacity in characters is at least the given minimum. Capacity includes space for the trailing
+ /// null, which is not part of the Length.
+ /// </summary>
+ /// <exception cref="OutOfMemoryException">Thrown if unable to allocate memory when setting.</exception>
+ [System.Security.SecuritySafeCritical]
+ public void EnsureCharCapacity(uint minCapacity)
+ {
+ EnsureByteCapacity(minCapacity * (ulong)sizeof(char));
+ }
+
+ /// <summary>
+ /// The logical length of the buffer in characters. (Does not include the final null, which is auto appended.) Will automatically attempt to increase capacity.
+ /// This is where the usable data ends.
+ /// </summary>
+ /// <exception cref="OutOfMemoryException">Thrown if unable to allocate memory when setting.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">Thrown if the set size in bytes is uint.MaxValue (as space is implicitly reservced for the trailing null).</exception>
+ public unsafe uint Length
+ {
+ get { return _length; }
+ [System.Security.SecuritySafeCritical]
+ set
+ {
+ if (value == uint.MaxValue) throw new ArgumentOutOfRangeException("Length");
+
+ // Null terminate
+ EnsureCharCapacity(value + 1);
+ CharPointer[value] = '\0';
+
+ _length = value;
+ }
+ }
+
+ /// <summary>
+ /// For use when the native api null terminates but doesn't return a length.
+ /// If no null is found, the length will not be changed.
+ /// </summary>
+ [System.Security.SecuritySafeCritical]
+ public unsafe void SetLengthToFirstNull()
+ {
+ char* buffer = CharPointer;
+ uint capacity = CharCapacity;
+ for (uint i = 0; i < capacity; i++)
+ {
+ if (buffer[i] == '\0')
+ {
+ _length = i;
+ break;
+ }
+ }
+ }
+
+ internal unsafe char* CharPointer
+ {
+ [System.Security.SecurityCritical]
+ get
+ {
+ return (char*)VoidPointer;
+ }
+ }
+
+ /// <summary>
+ /// True if the buffer contains the given character.
+ /// </summary>
+ [System.Security.SecurityCritical]
+ public unsafe bool Contains(char value)
+ {
+ char* start = CharPointer;
+ uint length = _length;
+
+ for (uint i = 0; i < length; i++)
+ {
+ if (*start++ == value) return true;
+ }
+
+ return false;
+ }
+
+ /// <summary>
+ /// Returns true if the buffer starts with the given string.
+ /// </summary>
+ [System.Security.SecuritySafeCritical]
+ public bool StartsWith(string value)
+ {
+ if (value == null) throw new ArgumentNullException("value");
+ if (_length < (uint)value.Length) return false;
+ return SubstringEquals(value, startIndex: 0, count: value.Length);
+ }
+
+ /// <summary>
+ /// Returns true if the specified StringBuffer substring equals the given value.
+ /// </summary>
+ /// <param name="value">The value to compare against the specified substring.</param>
+ /// <param name="startIndex">Start index of the sub string.</param>
+ /// <param name="count">Length of the substring, or -1 to check all remaining.</param>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// Thrown if <paramref name="startIndex"/> or <paramref name="count"/> are outside the range
+ /// of the buffer's length.
+ /// </exception>
+ [System.Security.SecuritySafeCritical]
+ public unsafe bool SubstringEquals(string value, uint startIndex = 0, int count = -1)
+ {
+ if (value == null) return false;
+ if (count < -1) throw new ArgumentOutOfRangeException("count");
+ if (startIndex > _length) throw new ArgumentOutOfRangeException("startIndex");
+
+ uint realCount = count == -1 ? _length - startIndex : (uint)count;
+ if (checked(startIndex + realCount) > _length) throw new ArgumentOutOfRangeException("count");
+
+ int length = value.Length;
+
+ // Check the substring length against the input length
+ if (realCount != (uint)length) return false;
+
+ fixed (char* valueStart = value)
+ {
+ char* bufferStart = CharPointer + startIndex;
+ for (int i = 0; i < length; i++)
+ {
+ // Note that indexing in this case generates faster code than trying to copy the pointer and increment it
+ if (*bufferStart++ != valueStart[i]) return false;
+ }
+ }
+
+ return true;
+ }
+
+ /// <summary>
+ /// Append the given string.
+ /// </summary>
+ /// <param name="value">The string to append.</param>
+ /// <param name="startIndex">The index in the input string to start appending from.</param>
+ /// <param name="count">The count of characters to copy from the input string, or -1 for all remaining.</param>
+ /// <exception cref="ArgumentNullException">Thrown if <paramref name="value"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// Thrown if <paramref name="startIndex"/> or <paramref name="count"/> are outside the range
+ /// of <paramref name="value"/> characters.
+ /// </exception>
+ [System.Security.SecuritySafeCritical]
+ public void Append(string value, int startIndex = 0, int count = -1)
+ {
+ CopyFrom(
+ bufferIndex: _length,
+ source: value,
+ sourceIndex: startIndex,
+ count: count);
+ }
+
+ /// <summary>
+ /// Append the given buffer.
+ /// </summary>
+ /// <param name="value">The buffer to append.</param>
+ /// <param name="startIndex">The index in the input buffer to start appending from.</param>
+ /// <exception cref="ArgumentNullException">Thrown if <paramref name="value"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// Thrown if <paramref name="startIndex"/> is outside the range of <paramref name="value"/> characters.
+ /// </exception>
+ public void Append(StringBuffer value, uint startIndex = 0)
+ {
+ if (value == null) throw new ArgumentNullException("value");
+ if (value.Length == 0) return;
+ value.CopyTo(
+ bufferIndex: startIndex,
+ destination: this,
+ destinationIndex: _length,
+ count: value.Length);
+ }
+
+ /// <summary>
+ /// Append the given buffer.
+ /// </summary>
+ /// <param name="value">The buffer to append.</param>
+ /// <param name="startIndex">The index in the input buffer to start appending from.</param>
+ /// <param name="count">The count of characters to copy from the buffer string.</param>
+ /// <exception cref="ArgumentNullException">Thrown if <paramref name="value"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// Thrown if <paramref name="startIndex"/> or <paramref name="count"/> are outside the range
+ /// of <paramref name="value"/> characters.
+ /// </exception>
+ public void Append(StringBuffer value, uint startIndex, uint count)
+ {
+ if (value == null) throw new ArgumentNullException("value");
+ if (count == 0) return;
+ value.CopyTo(
+ bufferIndex: startIndex,
+ destination: this,
+ destinationIndex: _length,
+ count: count);
+ }
+
+ /// <summary>
+ /// Copy contents to the specified buffer. Destination index must be within current destination length.
+ /// Will grow the destination buffer if needed.
+ /// </summary>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// Thrown if <paramref name="bufferIndex"/> or <paramref name="destinationIndex"/> or <paramref name="count"/> are outside the range
+ /// of <paramref name="value"/> characters.
+ /// </exception>
+ /// <exception cref="ArgumentNullException">Thrown if <paramref name="destination"/> is null.</exception>
+ [System.Security.SecuritySafeCritical]
+ public unsafe void CopyTo(uint bufferIndex, StringBuffer destination, uint destinationIndex, uint count)
+ {
+ if (destination == null) throw new ArgumentNullException("destination");
+ if (destinationIndex > destination._length) throw new ArgumentOutOfRangeException("destinationIndex");
+ if (bufferIndex >= _length) throw new ArgumentOutOfRangeException("bufferIndex");
+ if (_length < checked(bufferIndex + count)) throw new ArgumentOutOfRangeException("count");
+
+ if (count == 0) return;
+ uint lastIndex = checked(destinationIndex + count);
+ if (destination._length < lastIndex) destination.Length = lastIndex;
+
+ Buffer.MemoryCopy(
+ source: CharPointer + bufferIndex,
+ destination: destination.CharPointer + destinationIndex,
+ destinationSizeInBytes: checked((long)(destination.ByteCapacity - (destinationIndex * sizeof(char)))),
+ sourceBytesToCopy: checked((long)count * sizeof(char)));
+ }
+
+ /// <summary>
+ /// Copy contents from the specified string into the buffer at the given index. Start index must be within the current length of
+ /// the buffer, will grow as necessary.
+ /// </summary>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// Thrown if <paramref name="bufferIndex"/> or <paramref name="sourceIndex"/> or <paramref name="count"/> are outside the range
+ /// of <paramref name="value"/> characters.
+ /// </exception>
+ /// <exception cref="ArgumentNullException">Thrown if <paramref name="source"/> is null.</exception>
+ [System.Security.SecuritySafeCritical]
+ public unsafe void CopyFrom(uint bufferIndex, string source, int sourceIndex = 0, int count = -1)
+ {
+ if (source == null) throw new ArgumentNullException("source");
+ if (bufferIndex > _length) throw new ArgumentOutOfRangeException("bufferIndex");
+ if (sourceIndex < 0 || sourceIndex >= source.Length) throw new ArgumentOutOfRangeException("sourceIndex");
+ if (count == -1) count = source.Length - sourceIndex;
+ if (count < 0 || source.Length - count < sourceIndex) throw new ArgumentOutOfRangeException("count");
+
+ if (count == 0) return;
+ uint lastIndex = bufferIndex + (uint)count;
+ if (_length < lastIndex) Length = lastIndex;
+
+ fixed (char* content = source)
+ {
+ Buffer.MemoryCopy(
+ source: content + sourceIndex,
+ destination: CharPointer + bufferIndex,
+ destinationSizeInBytes: checked((long)(ByteCapacity - (bufferIndex * sizeof(char)))),
+ sourceBytesToCopy: (long)count * sizeof(char));
+ }
+ }
+
+ /// <summary>
+ /// Trim the specified values from the end of the buffer. If nothing is specified, nothing is trimmed.
+ /// </summary>
+ [System.Security.SecuritySafeCritical]
+ public unsafe void TrimEnd(char[] values)
+ {
+ if (values == null || values.Length == 0 || _length == 0) return;
+
+ char* end = CharPointer + _length - 1;
+
+ while (_length > 0 && Array.IndexOf(values, *end) >= 0)
+ {
+ Length = _length - 1;
+ end--;
+ }
+ }
+
+ /// <summary>
+ /// String representation of the entire buffer. If the buffer is larger than the maximum size string (int.MaxValue) this will throw.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">Thrown if the buffer is too big to fit into a string.</exception>
+ [System.Security.SecuritySafeCritical]
+ public unsafe override string ToString()
+ {
+ if (_length == 0) return string.Empty;
+ if (_length > int.MaxValue) throw new InvalidOperationException();
+ return new string(CharPointer, startIndex: 0, length: (int)_length);
+ }
+
+ /// <summary>
+ /// Get the given substring in the buffer.
+ /// </summary>
+ /// <param name="count">Count of characters to take, or remaining characters from <paramref name="startIndex"/> if -1.</param>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// Thrown if <paramref name="startIndex"/> or <paramref name="count"/> are outside the range of the buffer's length
+ /// or count is greater than the maximum string size (int.MaxValue).
+ /// </exception>
+ [System.Security.SecuritySafeCritical]
+ public unsafe string Substring(uint startIndex, int count = -1)
+ {
+ if (startIndex > (_length == 0 ? 0 : _length - 1)) throw new ArgumentOutOfRangeException("startIndex");
+ if (count < -1) throw new ArgumentOutOfRangeException("count");
+
+ uint realCount = count == -1 ? _length - startIndex : (uint)count;
+ if (realCount > int.MaxValue || checked(startIndex + realCount) > _length) throw new ArgumentOutOfRangeException("count");
+ if (realCount == 0) return string.Empty;
+
+ // The buffer could be bigger than will fit into a string, but the substring might fit. As the starting
+ // index might be bigger than int we need to index ourselves.
+ return new string(value: CharPointer + startIndex, startIndex: 0, length: (int)realCount);
+ }
+
+ [System.Security.SecuritySafeCritical]
+ public override void Free()
+ {
+ base.Free();
+ _length = 0;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventItfInfo.cs b/src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventItfInfo.cs
new file mode 100644
index 0000000000..29b094c9e8
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventItfInfo.cs
@@ -0,0 +1,53 @@
+// 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.
+
+namespace System.Runtime.InteropServices.TCEAdapterGen {
+
+ using System;
+ using System.Reflection;
+ using System.Collections;
+
+ internal class EventItfInfo
+ {
+ public EventItfInfo(String strEventItfName,
+ String strSrcItfName,
+ String strEventProviderName,
+ RuntimeAssembly asmImport,
+ RuntimeAssembly asmSrcItf)
+ {
+ m_strEventItfName = strEventItfName;
+ m_strSrcItfName = strSrcItfName;
+ m_strEventProviderName = strEventProviderName;
+ m_asmImport = asmImport;
+ m_asmSrcItf = asmSrcItf;
+ }
+
+ public Type GetEventItfType()
+ {
+ Type t = m_asmImport.GetType(m_strEventItfName, true, false);
+ if (t != null && !t.IsVisible)
+ t = null;
+ return t;
+ }
+
+ public Type GetSrcItfType()
+ {
+ Type t = m_asmSrcItf.GetType(m_strSrcItfName, true, false);
+ if (t != null && !t.IsVisible)
+ t = null;
+ return t;
+ }
+
+ public String GetEventProviderName()
+ {
+ return m_strEventProviderName;
+ }
+
+ private String m_strEventItfName;
+ private String m_strSrcItfName;
+ private String m_strEventProviderName;
+ private RuntimeAssembly m_asmImport;
+ private RuntimeAssembly m_asmSrcItf;
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventProviderWriter.cs b/src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventProviderWriter.cs
new file mode 100644
index 0000000000..58f70e57b7
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventProviderWriter.cs
@@ -0,0 +1,773 @@
+// 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.
+
+namespace System.Runtime.InteropServices.TCEAdapterGen {
+ using System.Runtime.InteropServices.ComTypes;
+ using ubyte = System.Byte;
+ using System;
+ using System.Reflection;
+ using System.Reflection.Emit;
+ using System.Collections;
+ using System.Threading;
+ using System.Diagnostics.Contracts;
+
+ internal class EventProviderWriter
+ {
+ private const BindingFlags DefaultLookup = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public;
+
+ private readonly Type[] MonitorEnterParamTypes = new Type[] { typeof(Object), Type.GetType("System.Boolean&") };
+
+ public EventProviderWriter( ModuleBuilder OutputModule, String strDestTypeName, Type EventItfType, Type SrcItfType, Type SinkHelperType )
+ {
+ m_OutputModule = OutputModule;
+ m_strDestTypeName = strDestTypeName;
+ m_EventItfType = EventItfType;
+ m_SrcItfType = SrcItfType;
+ m_SinkHelperType = SinkHelperType;
+ }
+
+ public Type Perform()
+ {
+ // Create the event provider class.
+ TypeBuilder OutputTypeBuilder = m_OutputModule.DefineType(
+ m_strDestTypeName,
+ TypeAttributes.Sealed | TypeAttributes.NotPublic,
+ typeof(Object),
+ new Type[]{m_EventItfType, typeof(IDisposable)}
+ );
+
+ // Create the event source field.
+ FieldBuilder fbCPC = OutputTypeBuilder.DefineField(
+ "m_ConnectionPointContainer",
+ typeof(IConnectionPointContainer),
+ FieldAttributes.Private
+ );
+
+ // Create array of event sink helpers.
+ FieldBuilder fbSinkHelper = OutputTypeBuilder.DefineField(
+ "m_aEventSinkHelpers",
+ typeof(ArrayList),
+ FieldAttributes.Private
+ );
+
+ // Define the connection point field.
+ FieldBuilder fbEventCP = OutputTypeBuilder.DefineField(
+ "m_ConnectionPoint",
+ typeof(IConnectionPoint),
+ FieldAttributes.Private
+ );
+
+ // Define the InitXXX method.
+ MethodBuilder InitSrcItfMethodBuilder =
+ DefineInitSrcItfMethod( OutputTypeBuilder, m_SrcItfType, fbSinkHelper, fbEventCP, fbCPC );
+
+ // Process all the methods in the event interface.
+ MethodInfo[] aMethods = TCEAdapterGenerator.GetNonPropertyMethods(m_SrcItfType);
+ for ( int cMethods = 0; cMethods < aMethods.Length; cMethods++ )
+ {
+ if ( m_SrcItfType == aMethods[cMethods].DeclaringType )
+ {
+ // Define the add_XXX method.
+ MethodBuilder AddEventMethodBuilder = DefineAddEventMethod(
+ OutputTypeBuilder, aMethods[cMethods], m_SinkHelperType, fbSinkHelper, fbEventCP, InitSrcItfMethodBuilder );
+
+ // Define the remove_XXX method.
+ MethodBuilder RemoveEventMethodBuilder = DefineRemoveEventMethod(
+ OutputTypeBuilder, aMethods[cMethods], m_SinkHelperType, fbSinkHelper, fbEventCP );
+ }
+ }
+
+ // Define the constructor.
+ DefineConstructor( OutputTypeBuilder, fbCPC );
+
+ // Define the finalize method.
+ MethodBuilder FinalizeMethod = DefineFinalizeMethod( OutputTypeBuilder, m_SinkHelperType, fbSinkHelper, fbEventCP );
+
+ // Define the Dispose method.
+ DefineDisposeMethod( OutputTypeBuilder, FinalizeMethod);
+
+ return OutputTypeBuilder.CreateType();
+ }
+
+ private MethodBuilder DefineAddEventMethod( TypeBuilder OutputTypeBuilder, MethodInfo SrcItfMethod, Type SinkHelperClass, FieldBuilder fbSinkHelperArray, FieldBuilder fbEventCP, MethodBuilder mbInitSrcItf )
+ {
+ Type[] aParamTypes;
+
+ // Find the delegate on the event sink helper.
+ FieldInfo DelegateField = SinkHelperClass.GetField( "m_" + SrcItfMethod.Name + "Delegate" );
+ Contract.Assert(DelegateField != null, "Unable to find the field m_" + SrcItfMethod.Name + "Delegate on the sink helper");
+
+ // Find the cookie on the event sink helper.
+ FieldInfo CookieField = SinkHelperClass.GetField( "m_dwCookie" );
+ Contract.Assert(CookieField != null, "Unable to find the field m_dwCookie on the sink helper");
+
+ // Retrieve the sink helper's constructor.
+ ConstructorInfo SinkHelperCons = SinkHelperClass.GetConstructor(EventProviderWriter.DefaultLookup | BindingFlags.NonPublic, null, Array.Empty<Type>(), null );
+ Contract.Assert(SinkHelperCons != null, "Unable to find the constructor for the sink helper");
+
+ // Retrieve the IConnectionPoint.Advise method.
+ MethodInfo CPAdviseMethod = typeof(IConnectionPoint).GetMethod( "Advise" );
+ Contract.Assert(CPAdviseMethod != null, "Unable to find the method ConnectionPoint.Advise");
+
+ // Retrieve the ArrayList.Add method.
+ aParamTypes = new Type[1];
+ aParamTypes[0] = typeof(Object);
+ MethodInfo ArrayListAddMethod = typeof(ArrayList).GetMethod( "Add", aParamTypes, null );
+ Contract.Assert(ArrayListAddMethod != null, "Unable to find the method ArrayList.Add");
+
+ // Retrieve the Monitor.Enter() method.
+ MethodInfo MonitorEnterMethod = typeof(Monitor).GetMethod( "Enter", MonitorEnterParamTypes, null );
+ Contract.Assert(MonitorEnterMethod != null, "Unable to find the method Monitor.Enter()");
+
+ // Retrieve the Monitor.Exit() method.
+ aParamTypes[0] = typeof(Object);
+ MethodInfo MonitorExitMethod = typeof(Monitor).GetMethod( "Exit", aParamTypes, null );
+ Contract.Assert(MonitorExitMethod != null, "Unable to find the method Monitor.Exit()");
+
+ // Define the add_XXX method.
+ Type[] parameterTypes;
+ parameterTypes = new Type[1];
+ parameterTypes[0] = DelegateField.FieldType;
+ MethodBuilder Meth = OutputTypeBuilder.DefineMethod(
+ "add_" + SrcItfMethod.Name,
+ MethodAttributes.Public | MethodAttributes.Virtual,
+ null,
+ parameterTypes );
+
+ ILGenerator il = Meth.GetILGenerator();
+
+ // Define a label for the m_IFooEventsCP comparision.
+ Label EventCPNonNullLabel = il.DefineLabel();
+
+ // Declare the local variables.
+ LocalBuilder ltSinkHelper = il.DeclareLocal( SinkHelperClass );
+ LocalBuilder ltCookie = il.DeclareLocal( typeof(Int32) );
+ LocalBuilder ltLockTaken = il.DeclareLocal( typeof(bool) );
+
+ // Generate the following code:
+ // try {
+ il.BeginExceptionBlock();
+
+ // Generate the following code:
+ // Monitor.Enter(this, ref lockTaken);
+ il.Emit(OpCodes.Ldarg, (short)0);
+ il.Emit(OpCodes.Ldloca_S, ltLockTaken);
+ il.Emit(OpCodes.Call, MonitorEnterMethod);
+
+ // Generate the following code:
+ // if ( m_IFooEventsCP != null ) goto EventCPNonNullLabel;
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Ldfld, fbEventCP );
+ il.Emit( OpCodes.Brtrue, EventCPNonNullLabel );
+
+ // Generate the following code:
+ // InitIFooEvents();
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Call, mbInitSrcItf );
+
+ // Mark this as label to jump to if the CP is not null.
+ il.MarkLabel( EventCPNonNullLabel );
+
+ // Generate the following code:
+ // IFooEvents_SinkHelper SinkHelper = new IFooEvents_SinkHelper;
+ il.Emit( OpCodes.Newobj, SinkHelperCons );
+ il.Emit( OpCodes.Stloc, ltSinkHelper );
+
+ // Generate the following code:
+ // dwCookie = 0;
+ il.Emit( OpCodes.Ldc_I4_0 );
+ il.Emit( OpCodes.Stloc, ltCookie );
+
+ // Generate the following code:
+ // m_IFooEventsCP.Advise( SinkHelper, dwCookie );
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Ldfld, fbEventCP );
+ il.Emit( OpCodes.Ldloc, ltSinkHelper );
+ il.Emit( OpCodes.Castclass, typeof(Object) );
+ il.Emit( OpCodes.Ldloca, ltCookie );
+ il.Emit( OpCodes.Callvirt, CPAdviseMethod );
+
+ // Generate the following code:
+ // SinkHelper.m_dwCookie = dwCookie;
+ il.Emit( OpCodes.Ldloc, ltSinkHelper );
+ il.Emit( OpCodes.Ldloc, ltCookie );
+ il.Emit( OpCodes.Stfld, CookieField );
+
+ // Generate the following code:
+ // SinkHelper.m_FooDelegate = d;
+ il.Emit( OpCodes.Ldloc, ltSinkHelper );
+ il.Emit( OpCodes.Ldarg, (short)1 );
+ il.Emit( OpCodes.Stfld, DelegateField );
+
+ // Generate the following code:
+ // m_aIFooEventsHelpers.Add( SinkHelper );
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Ldfld, fbSinkHelperArray );
+ il.Emit( OpCodes.Ldloc, ltSinkHelper );
+ il.Emit( OpCodes.Castclass, typeof(Object) );
+ il.Emit( OpCodes.Callvirt, ArrayListAddMethod );
+ il.Emit( OpCodes.Pop );
+
+ // Generate the following code:
+ // } finally {
+ il.BeginFinallyBlock();
+
+ // Generate the following code:
+ // if (lockTaken)
+ // Monitor.Exit(this);
+ Label skipExit = il.DefineLabel();
+ il.Emit( OpCodes.Ldloc, ltLockTaken );
+ il.Emit( OpCodes.Brfalse_S, skipExit );
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Call, MonitorExitMethod );
+ il.MarkLabel(skipExit);
+
+ // Generate the following code:
+ // }
+ il.EndExceptionBlock();
+
+ // Generate the return opcode.
+ il.Emit( OpCodes.Ret );
+
+ return Meth;
+ }
+
+ private MethodBuilder DefineRemoveEventMethod( TypeBuilder OutputTypeBuilder, MethodInfo SrcItfMethod, Type SinkHelperClass, FieldBuilder fbSinkHelperArray, FieldBuilder fbEventCP )
+ {
+ Type[] aParamTypes;
+
+ // Find the delegate on the event sink helper.
+ FieldInfo DelegateField = SinkHelperClass.GetField( "m_" + SrcItfMethod.Name + "Delegate" );
+ Contract.Assert(DelegateField != null, "Unable to find the field m_" + SrcItfMethod.Name + "Delegate on the sink helper");
+
+ // Find the cookie on the event sink helper.
+ FieldInfo CookieField = SinkHelperClass.GetField( "m_dwCookie" );
+ Contract.Assert(CookieField != null, "Unable to find the field m_dwCookie on the sink helper");
+
+ // Retrieve the ArrayList.RemoveAt method.
+ aParamTypes = new Type[1];
+ aParamTypes[0] = typeof(Int32);
+ MethodInfo ArrayListRemoveMethod = typeof(ArrayList).GetMethod( "RemoveAt", aParamTypes, null );
+ Contract.Assert(ArrayListRemoveMethod != null, "Unable to find the method ArrayList.RemoveAt()");
+
+ // Retrieve the ArrayList.Item property get method.
+ PropertyInfo ArrayListItemProperty = typeof(ArrayList).GetProperty( "Item" );
+ Contract.Assert(ArrayListItemProperty != null, "Unable to find the property ArrayList.Item");
+ MethodInfo ArrayListItemGetMethod = ArrayListItemProperty.GetGetMethod();
+ Contract.Assert(ArrayListItemGetMethod != null, "Unable to find the get method for property ArrayList.Item");
+
+ // Retrieve the ArrayList.Count property get method.
+ PropertyInfo ArrayListSizeProperty = typeof(ArrayList).GetProperty( "Count" );
+ Contract.Assert(ArrayListSizeProperty != null, "Unable to find the property ArrayList.Count");
+ MethodInfo ArrayListSizeGetMethod = ArrayListSizeProperty.GetGetMethod();
+ Contract.Assert(ArrayListSizeGetMethod != null, "Unable to find the get method for property ArrayList.Count");
+
+ // Retrieve the Delegate.Equals() method.
+ aParamTypes[0] = typeof(Delegate);
+ MethodInfo DelegateEqualsMethod = typeof(Delegate).GetMethod( "Equals", aParamTypes, null );
+ Contract.Assert(DelegateEqualsMethod != null, "Unable to find the method Delegate.Equlals()");
+
+ // Retrieve the Monitor.Enter() method.
+ MethodInfo MonitorEnterMethod = typeof(Monitor).GetMethod("Enter", MonitorEnterParamTypes, null);
+ Contract.Assert(MonitorEnterMethod != null, "Unable to find the method Monitor.Enter()");
+
+ // Retrieve the Monitor.Exit() method.
+ aParamTypes[0] = typeof(Object);
+ MethodInfo MonitorExitMethod = typeof(Monitor).GetMethod( "Exit", aParamTypes, null );
+ Contract.Assert(MonitorExitMethod != null, "Unable to find the method Monitor.Exit()");
+
+ // Retrieve the ConnectionPoint.Unadvise() method.
+ MethodInfo CPUnadviseMethod = typeof(IConnectionPoint).GetMethod( "Unadvise" );
+ Contract.Assert(CPUnadviseMethod != null, "Unable to find the method ConnectionPoint.Unadvise()");
+
+ // Retrieve the Marshal.ReleaseComObject() method.
+ MethodInfo ReleaseComObjectMethod = typeof(Marshal).GetMethod( "ReleaseComObject" );
+ Contract.Assert(ReleaseComObjectMethod != null, "Unable to find the method Marshal.ReleaseComObject()");
+
+ // Define the remove_XXX method.
+ Type[] parameterTypes;
+ parameterTypes = new Type[1];
+ parameterTypes[0] = DelegateField.FieldType;
+ MethodBuilder Meth = OutputTypeBuilder.DefineMethod(
+ "remove_" + SrcItfMethod.Name,
+ MethodAttributes.Public | MethodAttributes.Virtual,
+ null,
+ parameterTypes );
+
+ ILGenerator il = Meth.GetILGenerator();
+
+ // Declare the local variables.
+ LocalBuilder ltNumSinkHelpers = il.DeclareLocal( typeof(Int32) );
+ LocalBuilder ltSinkHelperCounter = il.DeclareLocal( typeof(Int32) );
+ LocalBuilder ltCurrSinkHelper = il.DeclareLocal( SinkHelperClass );
+ LocalBuilder ltLockTaken = il.DeclareLocal(typeof(bool));
+
+ // Generate the labels for the for loop.
+ Label ForBeginLabel = il.DefineLabel();
+ Label ForEndLabel = il.DefineLabel();
+ Label FalseIfLabel = il.DefineLabel();
+ Label MonitorExitLabel = il.DefineLabel();
+
+ // Generate the following code:
+ // try {
+ il.BeginExceptionBlock();
+
+ // Generate the following code:
+ // Monitor.Enter(this, ref lockTaken);
+ il.Emit(OpCodes.Ldarg, (short)0);
+ il.Emit(OpCodes.Ldloca_S, ltLockTaken);
+ il.Emit(OpCodes.Call, MonitorEnterMethod);
+
+ // Generate the following code:
+ // if ( m_aIFooEventsHelpers == null ) goto ForEndLabel;
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Ldfld, fbSinkHelperArray );
+ il.Emit( OpCodes.Brfalse, ForEndLabel );
+
+ // Generate the following code:
+ // int NumEventHelpers = m_aIFooEventsHelpers.Count;
+ // int cEventHelpers = 0;
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Ldfld, fbSinkHelperArray );
+ il.Emit( OpCodes.Callvirt, ArrayListSizeGetMethod );
+ il.Emit( OpCodes.Stloc, ltNumSinkHelpers );
+ il.Emit( OpCodes.Ldc_I4, 0 );
+ il.Emit( OpCodes.Stloc, ltSinkHelperCounter );
+
+ // Generate the following code:
+ // if ( 0 >= NumEventHelpers ) goto ForEndLabel;
+ il.Emit( OpCodes.Ldc_I4, 0 );
+ il.Emit( OpCodes.Ldloc, ltNumSinkHelpers );
+ il.Emit( OpCodes.Bge, ForEndLabel );
+
+ // Mark this as the beginning of the for loop's body.
+ il.MarkLabel( ForBeginLabel );
+
+ // Generate the following code:
+ // CurrentHelper = (IFooEvents_SinkHelper)m_aIFooEventsHelpers.Get( cEventHelpers );
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Ldfld, fbSinkHelperArray );
+ il.Emit( OpCodes.Ldloc, ltSinkHelperCounter );
+ il.Emit( OpCodes.Callvirt, ArrayListItemGetMethod );
+ il.Emit( OpCodes.Castclass, SinkHelperClass );
+ il.Emit( OpCodes.Stloc, ltCurrSinkHelper );
+
+ // Generate the following code:
+ // if ( CurrentHelper.m_FooDelegate )
+ il.Emit( OpCodes.Ldloc, ltCurrSinkHelper );
+ il.Emit( OpCodes.Ldfld, DelegateField );
+ il.Emit( OpCodes.Ldnull );
+ il.Emit( OpCodes.Beq, FalseIfLabel );
+
+ // Generate the following code:
+ // if ( CurrentHelper.m_FooDelegate.Equals( d ) )
+ il.Emit( OpCodes.Ldloc, ltCurrSinkHelper );
+ il.Emit( OpCodes.Ldfld, DelegateField );
+ il.Emit( OpCodes.Ldarg, (short)1 );
+ il.Emit( OpCodes.Castclass, typeof(Object) );
+ il.Emit( OpCodes.Callvirt, DelegateEqualsMethod );
+ il.Emit( OpCodes.Ldc_I4, 0xff );
+ il.Emit( OpCodes.And );
+ il.Emit( OpCodes.Ldc_I4, 0 );
+ il.Emit( OpCodes.Beq, FalseIfLabel );
+
+ // Generate the following code:
+ // m_aIFooEventsHelpers.RemoveAt( cEventHelpers );
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Ldfld, fbSinkHelperArray );
+ il.Emit( OpCodes.Ldloc, ltSinkHelperCounter );
+ il.Emit( OpCodes.Callvirt, ArrayListRemoveMethod );
+
+ // Generate the following code:
+ // m_IFooEventsCP.Unadvise( CurrentHelper.m_dwCookie );
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Ldfld, fbEventCP );
+ il.Emit( OpCodes.Ldloc, ltCurrSinkHelper );
+ il.Emit( OpCodes.Ldfld, CookieField );
+ il.Emit( OpCodes.Callvirt, CPUnadviseMethod );
+
+ // Generate the following code:
+ // if ( NumEventHelpers > 1) break;
+ il.Emit( OpCodes.Ldloc, ltNumSinkHelpers );
+ il.Emit( OpCodes.Ldc_I4, 1 );
+ il.Emit( OpCodes.Bgt, ForEndLabel );
+
+ // Generate the following code:
+ // Marshal.ReleaseComObject(m_IFooEventsCP);
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Ldfld, fbEventCP );
+ il.Emit( OpCodes.Call, ReleaseComObjectMethod );
+ il.Emit( OpCodes.Pop );
+
+ // Generate the following code:
+ // m_IFooEventsCP = null;
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Ldnull );
+ il.Emit( OpCodes.Stfld, fbEventCP );
+
+ // Generate the following code:
+ // m_aIFooEventsHelpers = null;
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Ldnull );
+ il.Emit( OpCodes.Stfld, fbSinkHelperArray );
+
+ // Generate the following code:
+ // break;
+ il.Emit( OpCodes.Br, ForEndLabel );
+
+ // Mark this as the label to jump to when the if statement is false.
+ il.MarkLabel( FalseIfLabel );
+
+ // Generate the following code:
+ // cEventHelpers++;
+ il.Emit( OpCodes.Ldloc, ltSinkHelperCounter );
+ il.Emit( OpCodes.Ldc_I4, 1 );
+ il.Emit( OpCodes.Add );
+ il.Emit( OpCodes.Stloc, ltSinkHelperCounter );
+
+ // Generate the following code:
+ // if ( cEventHelpers < NumEventHelpers ) goto ForBeginLabel;
+ il.Emit( OpCodes.Ldloc, ltSinkHelperCounter );
+ il.Emit( OpCodes.Ldloc, ltNumSinkHelpers );
+ il.Emit( OpCodes.Blt, ForBeginLabel );
+
+ // Mark this as the end of the for loop's body.
+ il.MarkLabel( ForEndLabel );
+
+ // Generate the following code:
+ // } finally {
+ il.BeginFinallyBlock();
+
+ // Generate the following code:
+ // if (lockTaken)
+ // Monitor.Exit(this);
+ Label skipExit = il.DefineLabel();
+ il.Emit(OpCodes.Ldloc, ltLockTaken);
+ il.Emit(OpCodes.Brfalse_S, skipExit);
+ il.Emit(OpCodes.Ldarg, (short)0);
+ il.Emit(OpCodes.Call, MonitorExitMethod);
+ il.MarkLabel(skipExit);
+
+ // Generate the following code:
+ // }
+ il.EndExceptionBlock();
+
+ // Generate the return opcode.
+ il.Emit( OpCodes.Ret );
+
+ return Meth;
+ }
+
+ private MethodBuilder DefineInitSrcItfMethod( TypeBuilder OutputTypeBuilder, Type SourceInterface, FieldBuilder fbSinkHelperArray, FieldBuilder fbEventCP, FieldBuilder fbCPC )
+ {
+ // Retrieve the constructor info for the array list's default constructor.
+ ConstructorInfo DefaultArrayListCons = typeof(ArrayList).GetConstructor(EventProviderWriter.DefaultLookup, null, Array.Empty<Type>(), null );
+ Contract.Assert(DefaultArrayListCons != null, "Unable to find the constructor for class ArrayList");
+
+ // Temp byte array for Guid
+ ubyte[] rgByteGuid = new ubyte[16];
+
+ // Retrieve the constructor info for the Guid constructor.
+ Type[] aParamTypes = new Type[1];
+ aParamTypes[0] = typeof(Byte[]);
+ ConstructorInfo ByteArrayGUIDCons = typeof(Guid).GetConstructor(EventProviderWriter.DefaultLookup, null, aParamTypes, null );
+ Contract.Assert(ByteArrayGUIDCons != null, "Unable to find the constructor for GUID that accepts a string as argument");
+
+ // Retrieve the IConnectionPointContainer.FindConnectionPoint() method.
+ MethodInfo CPCFindCPMethod = typeof(IConnectionPointContainer).GetMethod( "FindConnectionPoint" );
+ Contract.Assert(CPCFindCPMethod != null, "Unable to find the method ConnectionPointContainer.FindConnectionPoint()");
+
+ // Define the Init method itself.
+ MethodBuilder Meth = OutputTypeBuilder.DefineMethod(
+ "Init",
+ MethodAttributes.Private,
+ null,
+ null );
+
+ ILGenerator il = Meth.GetILGenerator();
+
+ // Declare the local variables.
+ LocalBuilder ltCP = il.DeclareLocal( typeof(IConnectionPoint) );
+ LocalBuilder ltEvGuid = il.DeclareLocal( typeof(Guid) );
+ LocalBuilder ltByteArrayGuid = il.DeclareLocal( typeof(Byte[]) );
+
+ // Generate the following code:
+ // IConnectionPoint CP = NULL;
+ il.Emit( OpCodes.Ldnull );
+ il.Emit( OpCodes.Stloc, ltCP );
+
+ // Get unsigned byte array for the GUID of the event interface.
+ rgByteGuid = SourceInterface.GUID.ToByteArray();
+
+ // Generate the following code:
+ // ubyte rgByteArray[] = new ubyte [16];
+ il.Emit( OpCodes.Ldc_I4, 0x10 );
+ il.Emit( OpCodes.Newarr, typeof(Byte) );
+ il.Emit( OpCodes.Stloc, ltByteArrayGuid );
+
+ // Generate the following code:
+ // rgByteArray[i] = rgByteGuid[i];
+ for (int i = 0; i < 16; i++ )
+ {
+ il.Emit( OpCodes.Ldloc, ltByteArrayGuid );
+ il.Emit( OpCodes.Ldc_I4, i );
+ il.Emit( OpCodes.Ldc_I4, (int) (rgByteGuid[i]) );
+ il.Emit( OpCodes.Stelem_I1);
+ }
+
+ // Generate the following code:
+ // EventItfGuid = Guid( ubyte b[] );
+ il.Emit( OpCodes.Ldloca, ltEvGuid );
+ il.Emit( OpCodes.Ldloc, ltByteArrayGuid );
+ il.Emit( OpCodes.Call, ByteArrayGUIDCons );
+
+ // Generate the following code:
+ // m_ConnectionPointContainer.FindConnectionPoint( EventItfGuid, CP );
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Ldfld, fbCPC );
+ il.Emit( OpCodes.Ldloca, ltEvGuid );
+ il.Emit( OpCodes.Ldloca, ltCP );
+ il.Emit( OpCodes.Callvirt, CPCFindCPMethod );
+
+ // Generate the following code:
+ // m_ConnectionPoint = (IConnectionPoint)CP;
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Ldloc, ltCP );
+ il.Emit( OpCodes.Castclass, typeof(IConnectionPoint) );
+ il.Emit( OpCodes.Stfld, fbEventCP );
+
+ // Generate the following code:
+ // m_aEventSinkHelpers = new ArrayList;
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Newobj, DefaultArrayListCons );
+ il.Emit( OpCodes.Stfld, fbSinkHelperArray );
+
+ // Generate the return opcode.
+ il.Emit( OpCodes.Ret );
+
+ return Meth;
+ }
+
+ private void DefineConstructor( TypeBuilder OutputTypeBuilder, FieldBuilder fbCPC )
+ {
+ // Retrieve the constructor info for the base class's constructor.
+ ConstructorInfo DefaultBaseClsCons = typeof(Object).GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, Array.Empty<Type>(), null );
+ Contract.Assert(DefaultBaseClsCons != null, "Unable to find the object's public default constructor");
+
+ // Define the default constructor.
+ MethodAttributes ctorAttributes = MethodAttributes.SpecialName | (DefaultBaseClsCons.Attributes & MethodAttributes.MemberAccessMask);
+ MethodBuilder Cons = OutputTypeBuilder.DefineMethod(
+ ".ctor",
+ ctorAttributes,
+ null,
+ new Type[]{typeof(Object)} );
+
+ ILGenerator il = Cons.GetILGenerator();
+
+ // Generate the call to the base class constructor.
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Call, DefaultBaseClsCons );
+
+ // Generate the following code:
+ // m_ConnectionPointContainer = (IConnectionPointContainer)EventSource;
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Ldarg, (short)1 );
+ il.Emit( OpCodes.Castclass, typeof(IConnectionPointContainer) );
+ il.Emit( OpCodes.Stfld, fbCPC );
+
+ // Generate the return opcode.
+ il.Emit( OpCodes.Ret );
+ }
+
+ private MethodBuilder DefineFinalizeMethod( TypeBuilder OutputTypeBuilder, Type SinkHelperClass, FieldBuilder fbSinkHelper, FieldBuilder fbEventCP )
+ {
+ // Find the cookie on the event sink helper.
+ FieldInfo CookieField = SinkHelperClass.GetField( "m_dwCookie" );
+ Contract.Assert(CookieField != null, "Unable to find the field m_dwCookie on the sink helper");
+
+ // Retrieve the ArrayList.Item property get method.
+ PropertyInfo ArrayListItemProperty = typeof(ArrayList).GetProperty( "Item" );
+ Contract.Assert(ArrayListItemProperty != null, "Unable to find the property ArrayList.Item");
+ MethodInfo ArrayListItemGetMethod = ArrayListItemProperty.GetGetMethod();
+ Contract.Assert(ArrayListItemGetMethod != null, "Unable to find the get method for property ArrayList.Item");
+
+ // Retrieve the ArrayList.Count property get method.
+ PropertyInfo ArrayListSizeProperty = typeof(ArrayList).GetProperty( "Count" );
+ Contract.Assert(ArrayListSizeProperty != null, "Unable to find the property ArrayList.Count");
+ MethodInfo ArrayListSizeGetMethod = ArrayListSizeProperty.GetGetMethod();
+ Contract.Assert(ArrayListSizeGetMethod != null, "Unable to find the get method for property ArrayList.Count");
+
+ // Retrieve the ConnectionPoint.Unadvise() method.
+ MethodInfo CPUnadviseMethod = typeof(IConnectionPoint).GetMethod( "Unadvise" );
+ Contract.Assert(CPUnadviseMethod != null, "Unable to find the method ConnectionPoint.Unadvise()");
+
+ // Retrieve the Marshal.ReleaseComObject() method.
+ MethodInfo ReleaseComObjectMethod = typeof(Marshal).GetMethod( "ReleaseComObject" );
+ Contract.Assert(ReleaseComObjectMethod != null, "Unable to find the method Marshal.ReleaseComObject()");
+
+ // Retrieve the Monitor.Enter() method.
+ MethodInfo MonitorEnterMethod = typeof(Monitor).GetMethod("Enter", MonitorEnterParamTypes, null);
+ Contract.Assert(MonitorEnterMethod != null, "Unable to find the method Monitor.Enter()");
+
+ // Retrieve the Monitor.Exit() method.
+ Type[] aParamTypes = new Type[1];
+ aParamTypes[0] = typeof(Object);
+ MethodInfo MonitorExitMethod = typeof(Monitor).GetMethod( "Exit", aParamTypes, null );
+ Contract.Assert(MonitorExitMethod != null, "Unable to find the method Monitor.Exit()");
+
+ // Define the Finalize method itself.
+ MethodBuilder Meth = OutputTypeBuilder.DefineMethod( "Finalize", MethodAttributes.Public | MethodAttributes.Virtual, null, null );
+
+ ILGenerator il = Meth.GetILGenerator();
+
+ // Declare the local variables.
+ LocalBuilder ltNumSinkHelpers = il.DeclareLocal( typeof(Int32) );
+ LocalBuilder ltSinkHelperCounter = il.DeclareLocal( typeof(Int32) );
+ LocalBuilder ltCurrSinkHelper = il.DeclareLocal( SinkHelperClass );
+ LocalBuilder ltLockTaken = il.DeclareLocal(typeof(bool));
+
+ // Generate the following code:
+ // try {
+ il.BeginExceptionBlock();
+
+ // Generate the following code:
+ // Monitor.Enter(this, ref lockTaken);
+ il.Emit(OpCodes.Ldarg, (short)0);
+ il.Emit(OpCodes.Ldloca_S, ltLockTaken);
+ il.Emit(OpCodes.Call, MonitorEnterMethod);
+
+ // Generate the labels.
+ Label ForBeginLabel = il.DefineLabel();
+ Label ReleaseComObjectLabel = il.DefineLabel();
+ Label AfterReleaseComObjectLabel = il.DefineLabel();
+
+ // Generate the following code:
+ // if ( m_IFooEventsCP == null ) goto AfterReleaseComObjectLabel;
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Ldfld, fbEventCP );
+ il.Emit( OpCodes.Brfalse, AfterReleaseComObjectLabel );
+
+ // Generate the following code:
+ // int NumEventHelpers = m_aIFooEventsHelpers.Count;
+ // int cEventHelpers = 0;
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Ldfld, fbSinkHelper );
+ il.Emit( OpCodes.Callvirt, ArrayListSizeGetMethod );
+ il.Emit( OpCodes.Stloc, ltNumSinkHelpers );
+ il.Emit( OpCodes.Ldc_I4, 0 );
+ il.Emit( OpCodes.Stloc, ltSinkHelperCounter );
+
+ // Generate the following code:
+ // if ( 0 >= NumEventHelpers ) goto ReleaseComObjectLabel;
+ il.Emit( OpCodes.Ldc_I4, 0 );
+ il.Emit( OpCodes.Ldloc, ltNumSinkHelpers );
+ il.Emit( OpCodes.Bge, ReleaseComObjectLabel );
+
+ // Mark this as the beginning of the for loop's body.
+ il.MarkLabel( ForBeginLabel );
+
+ // Generate the following code:
+ // CurrentHelper = (IFooEvents_SinkHelper)m_aIFooEventsHelpers.Get( cEventHelpers );
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Ldfld, fbSinkHelper );
+ il.Emit( OpCodes.Ldloc, ltSinkHelperCounter );
+ il.Emit( OpCodes.Callvirt, ArrayListItemGetMethod );
+ il.Emit( OpCodes.Castclass, SinkHelperClass );
+ il.Emit( OpCodes.Stloc, ltCurrSinkHelper );
+
+ // Generate the following code:
+ // m_IFooEventsCP.Unadvise( CurrentHelper.m_dwCookie );
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Ldfld, fbEventCP );
+ il.Emit( OpCodes.Ldloc, ltCurrSinkHelper );
+ il.Emit( OpCodes.Ldfld, CookieField );
+ il.Emit( OpCodes.Callvirt, CPUnadviseMethod );
+
+ // Generate the following code:
+ // cEventHelpers++;
+ il.Emit( OpCodes.Ldloc, ltSinkHelperCounter );
+ il.Emit( OpCodes.Ldc_I4, 1 );
+ il.Emit( OpCodes.Add );
+ il.Emit( OpCodes.Stloc, ltSinkHelperCounter );
+
+ // Generate the following code:
+ // if ( cEventHelpers < NumEventHelpers ) goto ForBeginLabel;
+ il.Emit( OpCodes.Ldloc, ltSinkHelperCounter );
+ il.Emit( OpCodes.Ldloc, ltNumSinkHelpers );
+ il.Emit( OpCodes.Blt, ForBeginLabel );
+
+ // Mark this as the end of the for loop's body.
+ il.MarkLabel( ReleaseComObjectLabel );
+
+ // Generate the following code:
+ // Marshal.ReleaseComObject(m_IFooEventsCP);
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Ldfld, fbEventCP );
+ il.Emit( OpCodes.Call, ReleaseComObjectMethod );
+ il.Emit( OpCodes.Pop );
+
+ // Mark this as the end of the for loop's body.
+ il.MarkLabel( AfterReleaseComObjectLabel );
+
+ // Generate the following code:
+ // } catch {
+ il.BeginCatchBlock(typeof(System.Exception));
+ il.Emit( OpCodes.Pop );
+
+ // Generate the following code:
+ // } finally {
+ il.BeginFinallyBlock();
+
+ // Generate the following code:
+ // if (lockTaken)
+ // Monitor.Exit(this);
+ Label skipExit = il.DefineLabel();
+ il.Emit(OpCodes.Ldloc, ltLockTaken);
+ il.Emit(OpCodes.Brfalse_S, skipExit);
+ il.Emit(OpCodes.Ldarg, (short)0);
+ il.Emit(OpCodes.Call, MonitorExitMethod);
+ il.MarkLabel(skipExit);
+
+ // Generate the following code:
+ // }
+ il.EndExceptionBlock();
+
+ // Generate the return opcode.
+ il.Emit( OpCodes.Ret );
+
+ return Meth;
+ }
+
+ private void DefineDisposeMethod( TypeBuilder OutputTypeBuilder, MethodBuilder FinalizeMethod )
+ {
+ // Retrieve the method info for GC.SuppressFinalize().
+ MethodInfo SuppressFinalizeMethod = typeof(GC).GetMethod("SuppressFinalize");
+ Contract.Assert(SuppressFinalizeMethod != null, "Unable to find the GC.SuppressFinalize");
+
+ // Define the Finalize method itself.
+ MethodBuilder Meth = OutputTypeBuilder.DefineMethod( "Dispose", MethodAttributes.Public | MethodAttributes.Virtual, null, null );
+
+ ILGenerator il = Meth.GetILGenerator();
+
+ // Generate the following code:
+ // Finalize()
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Callvirt, FinalizeMethod );
+
+ // Generate the following code:
+ // GC.SuppressFinalize()
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Call, SuppressFinalizeMethod );
+
+ // Generate the return opcode.
+ il.Emit( OpCodes.Ret );
+ }
+
+ private ModuleBuilder m_OutputModule;
+ private String m_strDestTypeName;
+ private Type m_EventItfType;
+ private Type m_SrcItfType;
+ private Type m_SinkHelperType;
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventSinkHelperWriter.cs b/src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventSinkHelperWriter.cs
new file mode 100644
index 0000000000..0367e79bdd
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventSinkHelperWriter.cs
@@ -0,0 +1,297 @@
+// 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.
+
+namespace System.Runtime.InteropServices.TCEAdapterGen {
+ using System.Runtime.InteropServices;
+ using System;
+ using System.Reflection;
+ using System.Reflection.Emit;
+ using System.Collections;
+ using System.Diagnostics.Contracts;
+ internal class EventSinkHelperWriter
+ {
+ public static readonly String GeneratedTypeNamePostfix = "_SinkHelper";
+
+ public EventSinkHelperWriter( ModuleBuilder OutputModule, Type InputType, Type EventItfType )
+ {
+ m_InputType = InputType;
+ m_OutputModule = OutputModule;
+ m_EventItfType = EventItfType;
+ }
+
+ public Type Perform()
+ {
+ // Create the output Type.
+ Type[] aInterfaces = new Type[1];
+ aInterfaces[0] = m_InputType;
+ String strFullName = null;
+ String strNameSpace = NameSpaceExtractor.ExtractNameSpace( m_EventItfType.FullName );
+
+ if (strNameSpace != "")
+ strFullName = strNameSpace + ".";
+
+ strFullName += m_InputType.Name + GeneratedTypeNamePostfix;
+ TypeBuilder OutputTypeBuilder = TCEAdapterGenerator.DefineUniqueType(
+ strFullName,
+ TypeAttributes.Sealed | TypeAttributes.Public,
+ null,
+ aInterfaces,
+ m_OutputModule
+ );
+ // Hide the _SinkProvider interface
+ TCEAdapterGenerator.SetHiddenAttribute(OutputTypeBuilder);
+
+ // Set the class interface to none.
+ TCEAdapterGenerator.SetClassInterfaceTypeToNone(OutputTypeBuilder);
+
+ // Retrieve the property methods on the input interface and give them a dummy implementation.
+ MethodInfo[] pMethods = TCEAdapterGenerator.GetPropertyMethods(m_InputType);
+ foreach (MethodInfo method in pMethods)
+ {
+ DefineBlankMethod(OutputTypeBuilder, method);
+ }
+
+ // Retrieve the non-property methods on the input interface.
+ MethodInfo[] aMethods = TCEAdapterGenerator.GetNonPropertyMethods(m_InputType);
+
+ // Allocate an array to contain the delegate fields.
+ FieldBuilder[] afbDelegates = new FieldBuilder[aMethods.Length];
+ // Process all the methods on the input interface.
+ for ( int cMethods = 0; cMethods < aMethods.Length; cMethods++ )
+ {
+ if ( m_InputType == aMethods[cMethods].DeclaringType )
+ {
+ // Retrieve the delegate type from the add_XXX method.
+ MethodInfo AddMeth = m_EventItfType.GetMethod( "add_" + aMethods[cMethods].Name );
+ ParameterInfo[] aParams = AddMeth.GetParameters();
+ Contract.Assert(aParams.Length == 1, "All event interface methods must take a single delegate derived type and have a void return type");
+ Type DelegateCls = aParams[0].ParameterType;
+
+ // Define the delegate instance field.
+ afbDelegates[cMethods] = OutputTypeBuilder.DefineField(
+ "m_" + aMethods[cMethods].Name + "Delegate",
+ DelegateCls,
+ FieldAttributes.Public
+ );
+
+ // Define the event method itself.
+ DefineEventMethod( OutputTypeBuilder, aMethods[cMethods], DelegateCls, afbDelegates[cMethods] );
+ }
+ }
+
+ // Create the cookie field.
+ FieldBuilder fbCookie = OutputTypeBuilder.DefineField(
+ "m_dwCookie",
+ typeof(Int32),
+ FieldAttributes.Public
+ );
+
+ // Define the constructor.
+ DefineConstructor( OutputTypeBuilder, fbCookie, afbDelegates );
+
+ return OutputTypeBuilder.CreateType();
+ }
+
+ private void DefineBlankMethod(TypeBuilder OutputTypeBuilder, MethodInfo Method)
+ {
+ ParameterInfo[] PIs = Method.GetParameters();
+ Type[] parameters = new Type[PIs.Length];
+ for (int i=0; i < PIs.Length; i++)
+ {
+ parameters[i] = PIs[i].ParameterType;
+ }
+
+ MethodBuilder Meth = OutputTypeBuilder.DefineMethod(Method.Name,
+ Method.Attributes & ~MethodAttributes.Abstract,
+ Method.CallingConvention,
+ Method.ReturnType,
+ parameters);
+
+ ILGenerator il = Meth.GetILGenerator();
+
+ AddReturn(Method.ReturnType, il, Meth);
+
+ il.Emit(OpCodes.Ret);
+ }
+
+ private void DefineEventMethod( TypeBuilder OutputTypeBuilder, MethodInfo Method, Type DelegateCls, FieldBuilder fbDelegate )
+ {
+ // Retrieve the method info for the invoke method on the delegate.
+ MethodInfo DelegateInvokeMethod = DelegateCls.GetMethod( "Invoke" );
+ Contract.Assert(DelegateInvokeMethod != null, "Unable to find method Delegate.Invoke()");
+
+ // Retrieve the return type.
+ Type ReturnType = Method.ReturnType;
+
+ // Define the actual event method.
+ ParameterInfo[] paramInfos = Method.GetParameters();
+ Type[] parameterTypes;
+ if (paramInfos != null)
+ {
+ parameterTypes = new Type[paramInfos.Length];
+ for (int i = 0; i < paramInfos.Length; i++)
+ {
+ parameterTypes[i] = paramInfos[i].ParameterType;
+ }
+ }
+ else
+ parameterTypes = null;
+
+ MethodAttributes attr = MethodAttributes.Public | MethodAttributes.Virtual;
+ MethodBuilder Meth = OutputTypeBuilder.DefineMethod( Method.Name,
+ attr,
+ CallingConventions.Standard,
+ ReturnType,
+ parameterTypes);
+
+ // We explicitly do not specify parameter name and attributes since this Type
+ // is not meant to be exposed to the user. It is only used internally to do the
+ // connection point to TCE mapping.
+
+ ILGenerator il = Meth.GetILGenerator();
+
+ // Create the exit branch.
+ Label ExitLabel = il.DefineLabel();
+
+ // Generate the code that verifies that the delegate is not null.
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Ldfld, fbDelegate );
+ il.Emit( OpCodes.Brfalse, ExitLabel );
+
+ // The delegate is not NULL so we need to invoke it.
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Ldfld, fbDelegate );
+
+ // Generate the code to load the arguments before we call invoke.
+ ParameterInfo[] aParams = Method.GetParameters();
+ for ( int cParams = 0; cParams < aParams.Length; cParams++ )
+ {
+ il.Emit( OpCodes.Ldarg, (short)(cParams + 1) );
+ }
+
+ // Generate a tail call to invoke. This will cause the callvirt to return
+ // directly to the caller of the current method instead of actually coming
+ // back to the current method and returning. This will cause the value returned
+ // from the call to the COM server to be returned to the caller of this method.
+
+ il.Emit( OpCodes.Callvirt, DelegateInvokeMethod );
+ il.Emit( OpCodes.Ret );
+
+ // This is the label that will be jumped to if no delegate is present.
+ il.MarkLabel( ExitLabel );
+
+ AddReturn(ReturnType, il, Meth);
+
+ il.Emit( OpCodes.Ret );
+
+ }
+
+ private void AddReturn(Type ReturnType, ILGenerator il, MethodBuilder Meth)
+ {
+ // Place a dummy return value on the stack before we return.
+ if ( ReturnType == typeof(void) )
+ {
+ // There is nothing to place on the stack.
+ }
+ else if ( ReturnType.IsPrimitive )
+ {
+ switch (System.Type.GetTypeCode(ReturnType))
+ {
+ case TypeCode.Boolean:
+ case TypeCode.Char:
+ case TypeCode.Byte:
+ case TypeCode.SByte:
+ case TypeCode.Int16:
+ case TypeCode.UInt16:
+ case TypeCode.Int32:
+ case TypeCode.UInt32:
+ il.Emit( OpCodes.Ldc_I4_0 );
+ break;
+
+ case TypeCode.Int64:
+ case TypeCode.UInt64:
+ il.Emit( OpCodes.Ldc_I4_0 );
+ il.Emit( OpCodes.Conv_I8 );
+ break;
+
+ case TypeCode.Single:
+ il.Emit( OpCodes.Ldc_R4, 0 );
+ break;
+
+ case TypeCode.Double:
+ il.Emit( OpCodes.Ldc_R4, 0 );
+ il.Emit( OpCodes.Conv_R8 );
+ break;
+
+ default:
+ // "TypeCode" does not include IntPtr, so special case it.
+ if ( ReturnType == typeof(IntPtr) )
+ il.Emit( OpCodes.Ldc_I4_0 );
+ else
+ Contract.Assert(false, "Unexpected type for Primitive type.");
+ break;
+ }
+ }
+ else if ( ReturnType.IsValueType )
+ {
+ // Allocate stack space for the return value type. Zero-init.
+ Meth.InitLocals = true;
+ LocalBuilder ltRetVal = il.DeclareLocal( ReturnType );
+
+ // Load the value class on the stack.
+ il.Emit( OpCodes.Ldloc_S, ltRetVal );
+
+ }
+ else
+ {
+ // The return type is a normal type.
+ il.Emit( OpCodes.Ldnull );
+ }
+ }
+
+ private void DefineConstructor( TypeBuilder OutputTypeBuilder, FieldBuilder fbCookie, FieldBuilder[] afbDelegates )
+ {
+ // Retrieve the constructor info for the base classe's constructor.
+ ConstructorInfo DefaultBaseClsCons = typeof(Object).GetConstructor(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public, null, Array.Empty<Type>(), null );
+ Contract.Assert(DefaultBaseClsCons != null, "Unable to find the constructor for class " + m_InputType.Name);
+
+ // Define the default constructor.
+ MethodBuilder Cons = OutputTypeBuilder.DefineMethod( ".ctor",
+ MethodAttributes.Assembly | MethodAttributes.SpecialName,
+ CallingConventions.Standard,
+ null,
+ null);
+
+ ILGenerator il = Cons.GetILGenerator();
+
+ // Generate the code to call the constructor of the base class.
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Call, DefaultBaseClsCons );
+
+ // Generate the code to set the cookie field to 0.
+ il.Emit( OpCodes.Ldarg, (short)0 );
+ il.Emit( OpCodes.Ldc_I4, 0 );
+ il.Emit( OpCodes.Stfld, fbCookie );
+
+ // Generate the code to set all the delegates to NULL.
+ for ( int cDelegates = 0; cDelegates < afbDelegates.Length; cDelegates++ )
+ {
+ if (afbDelegates[cDelegates] != null)
+ {
+ il.Emit( OpCodes.Ldarg,(short)0 );
+ il.Emit( OpCodes.Ldnull );
+ il.Emit( OpCodes.Stfld, afbDelegates[cDelegates] );
+ }
+ }
+
+ // Emit the return opcode.
+ il.Emit( OpCodes.Ret );
+
+ }
+
+ private Type m_InputType;
+ private Type m_EventItfType;
+ private ModuleBuilder m_OutputModule;
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/NameSpaceExtractor.cs b/src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/NameSpaceExtractor.cs
new file mode 100644
index 0000000000..8018ad4c66
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/NameSpaceExtractor.cs
@@ -0,0 +1,21 @@
+// 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.
+
+namespace System.Runtime.InteropServices.TCEAdapterGen {
+
+ using System;
+ internal static class NameSpaceExtractor
+ {
+ private static char NameSpaceSeperator = '.';
+
+ public static String ExtractNameSpace(String FullyQualifiedTypeName)
+ {
+ int TypeNameStartPos = FullyQualifiedTypeName.LastIndexOf(NameSpaceSeperator);
+ if (TypeNameStartPos == -1)
+ return "";
+ else
+ return FullyQualifiedTypeName.Substring(0, TypeNameStartPos);
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/TCEAdapterGenerator.cs b/src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/TCEAdapterGenerator.cs
new file mode 100644
index 0000000000..c6e4415246
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/TCEAdapterGenerator.cs
@@ -0,0 +1,141 @@
+// 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.
+
+namespace System.Runtime.InteropServices.TCEAdapterGen {
+ using System.Runtime.InteropServices;
+ using System;
+ using System.Reflection;
+ using System.Reflection.Emit;
+ using System.Collections;
+ using System.Threading;
+
+ internal class TCEAdapterGenerator
+ {
+ public void Process(ModuleBuilder ModBldr, ArrayList EventItfList)
+ {
+ // Store the input/output module.
+ m_Module = ModBldr;
+
+ // Generate the TCE adapters for all the event sources.
+ int NumEvItfs = EventItfList.Count;
+ for ( int cEventItfs = 0; cEventItfs < NumEvItfs; cEventItfs++ )
+ {
+ // Retrieve the event interface info.
+ EventItfInfo CurrEventItf = (EventItfInfo)EventItfList[cEventItfs];
+
+ // Retrieve the information from the event interface info.
+ Type EventItfType = CurrEventItf.GetEventItfType();
+ Type SrcItfType = CurrEventItf.GetSrcItfType();
+ String EventProviderName = CurrEventItf.GetEventProviderName();
+
+ // Generate the sink interface helper.
+ Type SinkHelperType = new EventSinkHelperWriter( m_Module, SrcItfType, EventItfType ).Perform();
+
+ // Generate the event provider.
+ new EventProviderWriter( m_Module, EventProviderName, EventItfType, SrcItfType, SinkHelperType ).Perform();
+ }
+ }
+
+ internal static void SetClassInterfaceTypeToNone(TypeBuilder tb)
+ {
+ // Create the ClassInterface(ClassInterfaceType.None) CA builder if we haven't created it yet.
+ if (s_NoClassItfCABuilder == null)
+ {
+ Type []aConsParams = new Type[1];
+ aConsParams[0] = typeof(ClassInterfaceType);
+ ConstructorInfo Cons = typeof(ClassInterfaceAttribute).GetConstructor(aConsParams);
+
+ Object[] aArgs = new Object[1];
+ aArgs[0] = ClassInterfaceType.None;
+ s_NoClassItfCABuilder = new CustomAttributeBuilder(Cons, aArgs);
+ }
+
+ // Set the class interface type to none.
+ tb.SetCustomAttribute(s_NoClassItfCABuilder);
+ }
+
+ internal static TypeBuilder DefineUniqueType(String strInitFullName, TypeAttributes attrs, Type BaseType, Type[] aInterfaceTypes, ModuleBuilder mb)
+ {
+ String strFullName = strInitFullName;
+ int PostFix = 2;
+
+ // Find the first unique name for the type.
+ for (; mb.GetType(strFullName) != null; strFullName = strInitFullName + "_" + PostFix, PostFix++);
+
+ // Define a type with the determined unique name.
+ return mb.DefineType(strFullName, attrs, BaseType, aInterfaceTypes);
+ }
+
+ internal static void SetHiddenAttribute(TypeBuilder tb)
+ {
+ if (s_HiddenCABuilder == null)
+ {
+ // Hide the type from Object Browsers
+ Type []aConsParams = new Type[1];
+ aConsParams[0] = typeof(TypeLibTypeFlags);
+ ConstructorInfo Cons = typeof(TypeLibTypeAttribute).GetConstructor(aConsParams);
+
+ Object []aArgs = new Object[1];
+ aArgs[0] = TypeLibTypeFlags.FHidden;
+ s_HiddenCABuilder = new CustomAttributeBuilder(Cons, aArgs);
+ }
+
+ tb.SetCustomAttribute(s_HiddenCABuilder);
+ }
+
+ internal static MethodInfo[] GetNonPropertyMethods(Type type)
+ {
+ MethodInfo[] aMethods = type.GetMethods();
+ ArrayList methods = new ArrayList(aMethods);
+
+ PropertyInfo[] props = type.GetProperties();
+
+ foreach(PropertyInfo prop in props)
+ {
+ MethodInfo[] accessors = prop.GetAccessors();
+ foreach (MethodInfo accessor in accessors)
+ {
+ for (int i=0; i < methods.Count; i++)
+ {
+ if ((MethodInfo)methods[i] == accessor)
+ methods.RemoveAt(i);
+ }
+ }
+ }
+
+ MethodInfo[] retMethods = new MethodInfo[methods.Count];
+ methods.CopyTo(retMethods);
+
+ return retMethods;
+ }
+
+ internal static MethodInfo[] GetPropertyMethods(Type type)
+ {
+ MethodInfo[] aMethods = type.GetMethods();
+ ArrayList methods = new ArrayList();
+
+ PropertyInfo[] props = type.GetProperties();
+
+ foreach(PropertyInfo prop in props)
+ {
+ MethodInfo[] accessors = prop.GetAccessors();
+ foreach (MethodInfo accessor in accessors)
+ {
+ methods.Add(accessor);
+ }
+ }
+
+ MethodInfo[] retMethods = new MethodInfo[methods.Count];
+ methods.CopyTo(retMethods);
+
+ return retMethods;
+ }
+
+
+ private ModuleBuilder m_Module = null;
+ private Hashtable m_SrcItfToSrcItfInfoMap = new Hashtable();
+ private static volatile CustomAttributeBuilder s_NoClassItfCABuilder = null;
+ private static volatile CustomAttributeBuilder s_HiddenCABuilder = null;
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/TypeLibConverter.cs b/src/mscorlib/src/System/Runtime/InteropServices/TypeLibConverter.cs
new file mode 100644
index 0000000000..e6b148a0a5
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/TypeLibConverter.cs
@@ -0,0 +1,595 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: Component that implements the ITypeLibConverter interface and
+** does the actual work of converting a typelib to metadata and
+** vice versa.
+**
+**
+=============================================================================*/
+#if !FEATURE_CORECLR // current implementation requires reflection only load
+namespace System.Runtime.InteropServices {
+
+ using System;
+ using System.Diagnostics.Contracts;
+ using System.Collections;
+ using System.Collections.Generic;
+ using System.Threading;
+ using System.Runtime.InteropServices.TCEAdapterGen;
+ using System.IO;
+ using System.Reflection;
+ using System.Reflection.Emit;
+ using System.Configuration.Assemblies;
+ using Microsoft.Win32;
+ using System.Runtime.CompilerServices;
+ using System.Globalization;
+ using System.Security;
+ using System.Security.Permissions;
+ using System.Runtime.InteropServices.ComTypes;
+ using System.Runtime.Versioning;
+ using WORD = System.UInt16;
+ using DWORD = System.UInt32;
+ using _TYPELIBATTR = System.Runtime.InteropServices.ComTypes.TYPELIBATTR;
+
+ [Guid("F1C3BF79-C3E4-11d3-88E7-00902754C43A")]
+ [ClassInterface(ClassInterfaceType.None)]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class TypeLibConverter : ITypeLibConverter
+ {
+ private const String s_strTypeLibAssemblyTitlePrefix = "TypeLib ";
+ private const String s_strTypeLibAssemblyDescPrefix = "Assembly generated from typelib ";
+ private const int MAX_NAMESPACE_LENGTH = 1024;
+
+
+ //
+ // ITypeLibConverter interface.
+ //
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+ [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)]
+ public AssemblyBuilder ConvertTypeLibToAssembly([MarshalAs(UnmanagedType.Interface)] Object typeLib,
+ String asmFileName,
+ int flags,
+ ITypeLibImporterNotifySink notifySink,
+ byte[] publicKey,
+ StrongNameKeyPair keyPair,
+ bool unsafeInterfaces)
+ {
+ return ConvertTypeLibToAssembly(typeLib,
+ asmFileName,
+ (unsafeInterfaces
+ ? TypeLibImporterFlags.UnsafeInterfaces
+ : 0),
+ notifySink,
+ publicKey,
+ keyPair,
+ null,
+ null);
+ }
+
+
+
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+ [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)]
+ public AssemblyBuilder ConvertTypeLibToAssembly([MarshalAs(UnmanagedType.Interface)] Object typeLib,
+ String asmFileName,
+ TypeLibImporterFlags flags,
+ ITypeLibImporterNotifySink notifySink,
+ byte[] publicKey,
+ StrongNameKeyPair keyPair,
+ String asmNamespace,
+ Version asmVersion)
+ {
+ // Validate the arguments.
+ if (typeLib == null)
+ throw new ArgumentNullException("typeLib");
+ if (asmFileName == null)
+ throw new ArgumentNullException("asmFileName");
+ if (notifySink == null)
+ throw new ArgumentNullException("notifySink");
+ if (String.Empty.Equals(asmFileName))
+ throw new ArgumentException(Environment.GetResourceString("Arg_InvalidFileName"), "asmFileName");
+ if (asmFileName.Length > Path.MaxPath)
+ throw new ArgumentException(Environment.GetResourceString("IO.PathTooLong"), asmFileName);
+ if ((flags & TypeLibImporterFlags.PrimaryInteropAssembly) != 0 && publicKey == null && keyPair == null)
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_PIAMustBeStrongNamed"));
+ Contract.EndContractBlock();
+
+ ArrayList eventItfInfoList = null;
+
+ // Determine the AssemblyNameFlags
+ AssemblyNameFlags asmNameFlags = AssemblyNameFlags.None;
+
+ // Retrieve the assembly name from the typelib.
+ AssemblyName asmName = GetAssemblyNameFromTypelib(typeLib, asmFileName, publicKey, keyPair, asmVersion, asmNameFlags);
+
+ // Create the dynamic assembly that will contain the converted typelib types.
+ AssemblyBuilder asmBldr = CreateAssemblyForTypeLib(typeLib, asmFileName, asmName,
+ (flags & TypeLibImporterFlags.PrimaryInteropAssembly) != 0,
+ (flags & TypeLibImporterFlags.ReflectionOnlyLoading) != 0,
+ (flags & TypeLibImporterFlags.NoDefineVersionResource) != 0);
+
+ // Define a dynamic module that will contain the contain the imported types.
+ String strNonQualifiedAsmFileName = Path.GetFileName(asmFileName);
+ ModuleBuilder modBldr = asmBldr.DefineDynamicModule(strNonQualifiedAsmFileName, strNonQualifiedAsmFileName);
+
+ // If the namespace hasn't been specified, then use the assembly name.
+ if (asmNamespace == null)
+ asmNamespace = asmName.Name;
+
+ // Create a type resolve handler that will also intercept resolve ref messages
+ // on the sink interface to build up a list of referenced assemblies.
+ TypeResolveHandler typeResolveHandler = new TypeResolveHandler(modBldr, notifySink);
+
+ // Add a listener for the type resolve events.
+ AppDomain currentDomain = Thread.GetDomain();
+ ResolveEventHandler resolveHandler = new ResolveEventHandler(typeResolveHandler.ResolveEvent);
+ ResolveEventHandler asmResolveHandler = new ResolveEventHandler(typeResolveHandler.ResolveAsmEvent);
+ ResolveEventHandler ROAsmResolveHandler = new ResolveEventHandler(typeResolveHandler.ResolveROAsmEvent);
+ currentDomain.TypeResolve += resolveHandler;
+ currentDomain.AssemblyResolve += asmResolveHandler;
+ currentDomain.ReflectionOnlyAssemblyResolve += ROAsmResolveHandler;
+
+ // Convert the types contained in the typelib into metadata and add them to the assembly.
+ nConvertTypeLibToMetadata(typeLib, asmBldr.InternalAssembly, modBldr.InternalModule, asmNamespace, flags, typeResolveHandler, out eventItfInfoList);
+
+ // Update the COM types in the assembly.
+ UpdateComTypesInAssembly(asmBldr, modBldr);
+
+ // If there are any event sources then generate the TCE adapters.
+ if (eventItfInfoList.Count > 0)
+ new TCEAdapterGenerator().Process(modBldr, eventItfInfoList);
+
+ // Remove the listener for the type resolve events.
+ currentDomain.TypeResolve -= resolveHandler;
+ currentDomain.AssemblyResolve -= asmResolveHandler;
+ currentDomain.ReflectionOnlyAssemblyResolve -= ROAsmResolveHandler;
+
+ // We have finished converting the typelib and now have a fully formed assembly.
+ return asmBldr;
+ }
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+ [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)]
+ [return : MarshalAs(UnmanagedType.Interface)]
+ public Object ConvertAssemblyToTypeLib(Assembly assembly, String strTypeLibName, TypeLibExporterFlags flags, ITypeLibExporterNotifySink notifySink)
+ {
+ RuntimeAssembly rtAssembly;
+ AssemblyBuilder ab = assembly as AssemblyBuilder;
+ if (ab != null)
+ rtAssembly = ab.InternalAssembly;
+ else
+ rtAssembly = assembly as RuntimeAssembly;
+
+ return nConvertAssemblyToTypeLib(rtAssembly, strTypeLibName, flags, notifySink);
+ }
+
+ public bool GetPrimaryInteropAssembly(Guid g, Int32 major, Int32 minor, Int32 lcid, out String asmName, out String asmCodeBase)
+ {
+ String strTlbId = "{" + g.ToString().ToUpper(CultureInfo.InvariantCulture) + "}";
+ String strVersion = major.ToString("x", CultureInfo.InvariantCulture) + "." + minor.ToString("x", CultureInfo.InvariantCulture);
+
+ // Set the two out values to null before we start.
+ asmName = null;
+ asmCodeBase = null;
+
+ // Try to open the HKEY_CLASS_ROOT\TypeLib key.
+ using (RegistryKey TypeLibKey = Registry.ClassesRoot.OpenSubKey("TypeLib", false))
+ {
+ if (TypeLibKey != null)
+ {
+ // Try to open the HKEY_CLASS_ROOT\TypeLib\<TLBID> key.
+ using (RegistryKey TypeLibSubKey = TypeLibKey.OpenSubKey(strTlbId))
+ {
+ if (TypeLibSubKey != null)
+ {
+ // Try to open the HKEY_CLASS_ROOT\TypeLib\<TLBID>\<Major.Minor> key.
+ using (RegistryKey VersionKey = TypeLibSubKey.OpenSubKey(strVersion, false))
+ {
+ if (VersionKey != null)
+ {
+ // Attempt to retrieve the assembly name and codebase under the version key.
+ asmName = (String)VersionKey.GetValue("PrimaryInteropAssemblyName");
+ asmCodeBase = (String)VersionKey.GetValue("PrimaryInteropAssemblyCodeBase");
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // If the assembly name isn't null, then we found an PIA.
+ return asmName != null;
+ }
+
+
+ //
+ // Non native helper methods.
+ //
+
+ [System.Security.SecurityCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ private static AssemblyBuilder CreateAssemblyForTypeLib(Object typeLib, String asmFileName, AssemblyName asmName, bool bPrimaryInteropAssembly, bool bReflectionOnly, bool bNoDefineVersionResource)
+ {
+ // Retrieve the current app domain.
+ AppDomain currentDomain = Thread.GetDomain();
+
+ // Retrieve the directory from the assembly file name.
+ String dir = null;
+ if (asmFileName != null)
+ {
+ dir = Path.GetDirectoryName(asmFileName);
+ if (String.IsNullOrEmpty(dir))
+ dir = null;
+ }
+
+ AssemblyBuilderAccess aba;
+ if (bReflectionOnly)
+ {
+ aba = AssemblyBuilderAccess.ReflectionOnly;
+ }
+ else
+ {
+ aba = AssemblyBuilderAccess.RunAndSave;
+ }
+
+ // Create the dynamic assembly itself.
+ AssemblyBuilder asmBldr;
+
+ List<CustomAttributeBuilder> assemblyAttributes = new List<CustomAttributeBuilder>();
+#if !FEATURE_CORECLR
+ // mscorlib.dll must specify the security rules that assemblies it emits are to use, since by
+ // default all assemblies will follow security rule set level 2, and we want to make that an
+ // explicit decision.
+ ConstructorInfo securityRulesCtor = typeof(SecurityRulesAttribute).GetConstructor(new Type[] { typeof(SecurityRuleSet) });
+ CustomAttributeBuilder securityRulesAttribute =
+ new CustomAttributeBuilder(securityRulesCtor, new object[] { SecurityRuleSet.Level2 });
+ assemblyAttributes.Add(securityRulesAttribute);
+#endif // !FEATURE_CORECLR
+
+ asmBldr = currentDomain.DefineDynamicAssembly(asmName, aba, dir, false, assemblyAttributes);
+
+ // Set the Guid custom attribute on the assembly.
+ SetGuidAttributeOnAssembly(asmBldr, typeLib);
+
+ // Set the imported from COM attribute on the assembly and return it.
+ SetImportedFromTypeLibAttrOnAssembly(asmBldr, typeLib);
+
+ // Set the version information on the typelib.
+ if (bNoDefineVersionResource)
+ {
+ SetTypeLibVersionAttribute(asmBldr, typeLib);
+ }
+ else
+ {
+ SetVersionInformation(asmBldr, typeLib, asmName);
+ }
+
+ // If we are generating a PIA, then set the PIA custom attribute.
+ if (bPrimaryInteropAssembly)
+ SetPIAAttributeOnAssembly(asmBldr, typeLib);
+
+ return asmBldr;
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ internal static AssemblyName GetAssemblyNameFromTypelib(Object typeLib, String asmFileName, byte[] publicKey, StrongNameKeyPair keyPair, Version asmVersion, AssemblyNameFlags asmNameFlags)
+ {
+ // Extract the name of the typelib.
+ String strTypeLibName = null;
+ String strDocString = null;
+ int dwHelpContext = 0;
+ String strHelpFile = null;
+ ITypeLib pTLB = (ITypeLib)typeLib;
+ pTLB.GetDocumentation(-1, out strTypeLibName, out strDocString, out dwHelpContext, out strHelpFile);
+
+ // Retrieve the name to use for the assembly.
+ if (asmFileName == null)
+ {
+ asmFileName = strTypeLibName;
+ }
+ else
+ {
+ Contract.Assert((asmFileName != null) && (asmFileName.Length > 0), "The assembly file name cannot be an empty string!");
+
+ String strFileNameNoPath = Path.GetFileName(asmFileName);
+ String strExtension = Path.GetExtension(asmFileName);
+
+ // Validate that the extension is valid.
+ bool bExtensionValid = ".dll".Equals(strExtension, StringComparison.OrdinalIgnoreCase);
+
+ // If the extension is not valid then tell the user and quit.
+ if (!bExtensionValid)
+ throw new ArgumentException(Environment.GetResourceString("Arg_InvalidFileExtension"));
+
+ // The assembly cannot contain the path nor the extension.
+ asmFileName = strFileNameNoPath.Substring(0, strFileNameNoPath.Length - ".dll".Length);
+ }
+
+ // If the version information was not specified, then retrieve it from the typelib.
+ if (asmVersion == null)
+ {
+ int major;
+ int minor;
+ Marshal.GetTypeLibVersion(pTLB, out major, out minor);
+ asmVersion = new Version(major, minor, 0, 0);
+ }
+
+ // Create the assembly name for the imported typelib's assembly.
+ AssemblyName AsmName = new AssemblyName();
+ AsmName.Init(
+ asmFileName,
+ publicKey,
+ null,
+ asmVersion,
+ null,
+ AssemblyHashAlgorithm.None,
+ AssemblyVersionCompatibility.SameMachine,
+ null,
+ asmNameFlags,
+ keyPair);
+
+ return AsmName;
+ }
+
+ private static void UpdateComTypesInAssembly(AssemblyBuilder asmBldr, ModuleBuilder modBldr)
+ {
+ // Retrieve the AssemblyBuilderData associated with the assembly builder.
+ AssemblyBuilderData AsmBldrData = asmBldr.m_assemblyData;
+
+ // Go through the types in the module and add them as public COM types.
+ Type[] aTypes = modBldr.GetTypes();
+ int NumTypes = aTypes.Length;
+ for (int cTypes = 0; cTypes < NumTypes; cTypes++)
+ AsmBldrData.AddPublicComType(aTypes[cTypes]);
+ }
+
+
+ [System.Security.SecurityCritical] // auto-generated
+ private static void SetGuidAttributeOnAssembly(AssemblyBuilder asmBldr, Object typeLib)
+ {
+ // Retrieve the GuidAttribute constructor.
+ Type []aConsParams = new Type[1] {typeof(String)};
+ ConstructorInfo GuidAttrCons = typeof(GuidAttribute).GetConstructor(aConsParams);
+
+ // Create an instance of the custom attribute builder.
+ Object[] aArgs = new Object[1] {Marshal.GetTypeLibGuid((ITypeLib)typeLib).ToString()};
+ CustomAttributeBuilder GuidCABuilder = new CustomAttributeBuilder(GuidAttrCons, aArgs);
+
+ // Set the GuidAttribute on the assembly builder.
+ asmBldr.SetCustomAttribute(GuidCABuilder);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ private static void SetImportedFromTypeLibAttrOnAssembly(AssemblyBuilder asmBldr, Object typeLib)
+ {
+ // Retrieve the ImportedFromTypeLibAttribute constructor.
+ Type []aConsParams = new Type[1] {typeof(String)};
+ ConstructorInfo ImpFromComAttrCons = typeof(ImportedFromTypeLibAttribute).GetConstructor(aConsParams);
+
+ // Retrieve the name of the typelib.
+ String strTypeLibName = Marshal.GetTypeLibName((ITypeLib)typeLib);
+
+ // Create an instance of the custom attribute builder.
+ Object[] aArgs = new Object[1] {strTypeLibName};
+ CustomAttributeBuilder ImpFromComCABuilder = new CustomAttributeBuilder(ImpFromComAttrCons, aArgs);
+
+ // Set the ImportedFromTypeLibAttribute on the assembly builder.
+ asmBldr.SetCustomAttribute(ImpFromComCABuilder);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ private static void SetTypeLibVersionAttribute(AssemblyBuilder asmBldr, Object typeLib)
+ {
+ Type []aConsParams = new Type[2] {typeof(int), typeof(int)};
+ ConstructorInfo TypeLibVerCons = typeof(TypeLibVersionAttribute).GetConstructor(aConsParams);
+
+ // Get the typelib version
+ int major;
+ int minor;
+ Marshal.GetTypeLibVersion((ITypeLib)typeLib, out major, out minor);
+
+ // Create an instance of the custom attribute builder.
+ Object[] aArgs = new Object[2] {major, minor};
+ CustomAttributeBuilder TypeLibVerBuilder = new CustomAttributeBuilder(TypeLibVerCons, aArgs);
+
+ // Set the attribute on the assembly builder.
+ asmBldr.SetCustomAttribute(TypeLibVerBuilder);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ private static void SetVersionInformation(AssemblyBuilder asmBldr, Object typeLib, AssemblyName asmName)
+ {
+ // Extract the name of the typelib.
+ String strTypeLibName = null;
+ String strDocString = null;
+ int dwHelpContext = 0;
+ String strHelpFile = null;
+ ITypeLib pTLB = (ITypeLib)typeLib;
+ pTLB.GetDocumentation(-1, out strTypeLibName, out strDocString, out dwHelpContext, out strHelpFile);
+
+ // Generate the product name string from the named of the typelib.
+ String strProductName = String.Format(CultureInfo.InvariantCulture, Environment.GetResourceString("TypeLibConverter_ImportedTypeLibProductName"), strTypeLibName);
+
+ // Set the OS version information.
+ asmBldr.DefineVersionInfoResource(strProductName, asmName.Version.ToString(), null, null, null);
+
+ // Set the TypeLibVersion attribute
+ SetTypeLibVersionAttribute(asmBldr, typeLib);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ private static void SetPIAAttributeOnAssembly(AssemblyBuilder asmBldr, Object typeLib)
+ {
+ IntPtr pAttr = IntPtr.Zero;
+ _TYPELIBATTR Attr;
+ ITypeLib pTLB = (ITypeLib)typeLib;
+ int Major = 0;
+ int Minor = 0;
+
+ // Retrieve the PrimaryInteropAssemblyAttribute constructor.
+ Type []aConsParams = new Type[2] {typeof(int), typeof(int)};
+ ConstructorInfo PIAAttrCons = typeof(PrimaryInteropAssemblyAttribute).GetConstructor(aConsParams);
+
+ // Retrieve the major and minor version from the typelib.
+ try
+ {
+ pTLB.GetLibAttr(out pAttr);
+ Attr = (_TYPELIBATTR)Marshal.PtrToStructure(pAttr, typeof(_TYPELIBATTR));
+ Major = Attr.wMajorVerNum;
+ Minor = Attr.wMinorVerNum;
+ }
+ finally
+ {
+ // Release the typelib attributes.
+ if (pAttr != IntPtr.Zero)
+ pTLB.ReleaseTLibAttr(pAttr);
+ }
+
+ // Create an instance of the custom attribute builder.
+ Object[] aArgs = new Object[2] {Major, Minor};
+ CustomAttributeBuilder PIACABuilder = new CustomAttributeBuilder(PIAAttrCons, aArgs);
+
+ // Set the PrimaryInteropAssemblyAttribute on the assembly builder.
+ asmBldr.SetCustomAttribute(PIACABuilder);
+ }
+
+
+ //
+ // Native helper methods.
+ //
+
+ [System.Security.SecurityCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern void nConvertTypeLibToMetadata(Object typeLib, RuntimeAssembly asmBldr, RuntimeModule modBldr, String nameSpace, TypeLibImporterFlags flags, ITypeLibImporterNotifySink notifySink, out ArrayList eventItfInfoList);
+
+ // Must use assembly versioning or GuidAttribute to avoid collisions in typelib export or registration.
+ [System.Security.SecurityCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern Object nConvertAssemblyToTypeLib(RuntimeAssembly assembly, String strTypeLibName, TypeLibExporterFlags flags, ITypeLibExporterNotifySink notifySink);
+
+ [System.Security.SecurityCritical] // auto-generated
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
+ internal extern static void LoadInMemoryTypeByName(RuntimeModule module, String className);
+
+ //
+ // Helper class called when a resolve type event is fired.
+ //
+
+ private class TypeResolveHandler : ITypeLibImporterNotifySink
+ {
+ public TypeResolveHandler(ModuleBuilder mod, ITypeLibImporterNotifySink userSink)
+ {
+ m_Module = mod;
+ m_UserSink = userSink;
+ }
+
+ public void ReportEvent(ImporterEventKind eventKind, int eventCode, String eventMsg)
+ {
+ m_UserSink.ReportEvent(eventKind, eventCode, eventMsg);
+ }
+
+ public Assembly ResolveRef(Object typeLib)
+ {
+ Contract.Ensures(Contract.Result<Assembly>() != null && Contract.Result<Assembly>() is RuntimeAssembly);
+ Contract.EndContractBlock();
+
+ // Call the user sink to resolve the reference.
+ Assembly asm = m_UserSink.ResolveRef(typeLib);
+
+ if (asm == null)
+ throw new ArgumentNullException();
+
+ // Return the resolved assembly. We extract the internal assembly because we are called
+ // by the VM which accesses fields of the object directly and does not go via those
+ // delegating properties (the fields are empty if asm is an (external) AssemblyBuilder).
+
+ RuntimeAssembly rtAssembly = asm as RuntimeAssembly;
+ if (rtAssembly == null)
+ {
+ AssemblyBuilder ab = asm as AssemblyBuilder;
+ if (ab != null)
+ rtAssembly = ab.InternalAssembly;
+ }
+
+ if (rtAssembly == null)
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeAssembly"));
+
+ // Add the assembly to the list of assemblies.
+ m_AsmList.Add(rtAssembly);
+
+ return rtAssembly;
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ public Assembly ResolveEvent(Object sender, ResolveEventArgs args)
+ {
+ // We need to load the type in the resolve event so that we will deal with
+ // cases where we are trying to load the CoClass before the interface has
+ // been loaded.
+ try
+ {
+ LoadInMemoryTypeByName(m_Module.GetNativeHandle(), args.Name);
+ return m_Module.Assembly;
+ }
+ catch (TypeLoadException e)
+ {
+ if (e.ResourceId != System.__HResults.COR_E_TYPELOAD) // type not found
+ throw;
+ }
+
+ foreach (RuntimeAssembly asm in m_AsmList)
+ {
+ try
+ {
+ asm.GetType(args.Name, true, false);
+ return asm;
+ }
+ catch (TypeLoadException e)
+ {
+ if (e._HResult != System.__HResults.COR_E_TYPELOAD) // type not found
+ throw;
+ }
+ }
+
+ return null;
+ }
+
+ public Assembly ResolveAsmEvent(Object sender, ResolveEventArgs args)
+ {
+ foreach (RuntimeAssembly asm in m_AsmList)
+ {
+ if (String.Compare(asm.FullName, args.Name, StringComparison.OrdinalIgnoreCase) == 0)
+ return asm;
+ }
+
+ return null;
+ }
+
+ public Assembly ResolveROAsmEvent(Object sender, ResolveEventArgs args)
+ {
+ foreach (RuntimeAssembly asm in m_AsmList)
+ {
+ if (String.Compare(asm.FullName, args.Name, StringComparison.OrdinalIgnoreCase) == 0)
+ return asm;
+ }
+
+ // We failed to find the referenced assembly in our pre-loaded assemblies, so try to load it based on policy.
+ string asmName = AppDomain.CurrentDomain.ApplyPolicy(args.Name);
+ return Assembly.ReflectionOnlyLoad(asmName);
+ }
+
+ private ModuleBuilder m_Module;
+ private ITypeLibImporterNotifySink m_UserSink;
+ private List<RuntimeAssembly> m_AsmList = new List<RuntimeAssembly>();
+ }
+ }
+}
+#endif // !FEATURE_CORECLR // current implementation requires reflection only load
+
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/UCOMIBindCtx.cs b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIBindCtx.cs
new file mode 100644
index 0000000000..8c6e1bcd64
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIBindCtx.cs
@@ -0,0 +1,46 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: UCOMIBindCtx interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices {
+
+ using System;
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.BIND_OPTS instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [StructLayout(LayoutKind.Sequential)]
+
+ public struct BIND_OPTS
+ {
+ public int cbStruct;
+ public int grfFlags;
+ public int grfMode;
+ public int dwTickCountDeadline;
+ }
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.IBindCtx instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [Guid("0000000e-0000-0000-C000-000000000046")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface UCOMIBindCtx
+ {
+ void RegisterObjectBound([MarshalAs(UnmanagedType.Interface)] Object punk);
+ void RevokeObjectBound([MarshalAs(UnmanagedType.Interface)] Object punk);
+ void ReleaseBoundObjects();
+ void SetBindOptions([In()] ref BIND_OPTS pbindopts);
+ void GetBindOptions(ref BIND_OPTS pbindopts);
+ void GetRunningObjectTable(out UCOMIRunningObjectTable pprot);
+ void RegisterObjectParam([MarshalAs(UnmanagedType.LPWStr)] String pszKey, [MarshalAs(UnmanagedType.Interface)] Object punk);
+ void GetObjectParam([MarshalAs(UnmanagedType.LPWStr)] String pszKey, [MarshalAs(UnmanagedType.Interface)] out Object ppunk);
+ void EnumObjectParam(out UCOMIEnumString ppenum);
+ void RevokeObjectParam([MarshalAs(UnmanagedType.LPWStr)] String pszKey);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/UCOMIConnectionPoint.cs b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIConnectionPoint.cs
new file mode 100644
index 0000000000..b12e1f7a8c
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIConnectionPoint.cs
@@ -0,0 +1,30 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: UCOMIConnectionPoint interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices
+{
+ using System;
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.IConnectionPoint instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [Guid("B196B286-BAB4-101A-B69C-00AA00341D07")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface UCOMIConnectionPoint
+ {
+ void GetConnectionInterface(out Guid pIID);
+ void GetConnectionPointContainer(out UCOMIConnectionPointContainer ppCPC);
+ void Advise([MarshalAs(UnmanagedType.Interface)] Object pUnkSink, out int pdwCookie);
+ void Unadvise(int dwCookie);
+ void EnumConnections(out UCOMIEnumConnections ppEnum);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/UCOMIConnectionPointContainer.cs b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIConnectionPointContainer.cs
new file mode 100644
index 0000000000..212d643e03
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIConnectionPointContainer.cs
@@ -0,0 +1,27 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: UCOMIConnectionPointContainer interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices
+{
+ using System;
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.IConnectionPointContainer instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [Guid("B196B284-BAB4-101A-B69C-00AA00341D07")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface UCOMIConnectionPointContainer
+ {
+ void EnumConnectionPoints(out UCOMIEnumConnectionPoints ppEnum);
+ void FindConnectionPoint(ref Guid riid, out UCOMIConnectionPoint ppCP);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/UCOMIEnumConnectionPoints.cs b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIEnumConnectionPoints.cs
new file mode 100644
index 0000000000..5180018088
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIEnumConnectionPoints.cs
@@ -0,0 +1,32 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: UCOMIEnumConnectionPoints interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices
+{
+ using System;
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.IEnumConnectionPoints instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [Guid("B196B285-BAB4-101A-B69C-00AA00341D07")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface UCOMIEnumConnectionPoints
+ {
+ [PreserveSig]
+ int Next(int celt, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0), Out] UCOMIConnectionPoint[] rgelt, out int pceltFetched);
+ [PreserveSig]
+ int Skip(int celt);
+ [PreserveSig]
+ int Reset();
+ void Clone(out UCOMIEnumConnectionPoints ppenum);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/UCOMIEnumConnections.cs b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIEnumConnections.cs
new file mode 100644
index 0000000000..87273b34f7
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIEnumConnections.cs
@@ -0,0 +1,42 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: UCOMIEnumConnections interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices
+{
+ using System;
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.CONNECTDATA instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+
+ public struct CONNECTDATA
+ {
+ [MarshalAs(UnmanagedType.Interface)]
+ public Object pUnk;
+ public int dwCookie;
+ }
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.IEnumConnections instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [Guid("B196B287-BAB4-101A-B69C-00AA00341D07")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface UCOMIEnumConnections
+ {
+ [PreserveSig]
+ int Next(int celt, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0), Out] CONNECTDATA[] rgelt, out int pceltFetched);
+ [PreserveSig]
+ int Skip(int celt);
+ [PreserveSig]
+ void Reset();
+ void Clone(out UCOMIEnumConnections ppenum);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/UCOMIEnumMoniker.cs b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIEnumMoniker.cs
new file mode 100644
index 0000000000..40787fcd5c
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIEnumMoniker.cs
@@ -0,0 +1,33 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: UCOMIEnumMoniker interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices
+{
+ using System;
+ using DWORD = System.UInt32;
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.IEnumMoniker instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [Guid("00000102-0000-0000-C000-000000000046")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface UCOMIEnumMoniker
+ {
+ [PreserveSig]
+ int Next(int celt, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0), Out] UCOMIMoniker[] rgelt, out int pceltFetched);
+ [PreserveSig]
+ int Skip(int celt);
+ [PreserveSig]
+ int Reset();
+ void Clone(out UCOMIEnumMoniker ppenum);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/UCOMIEnumString.cs b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIEnumString.cs
new file mode 100644
index 0000000000..9d0552a0df
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIEnumString.cs
@@ -0,0 +1,32 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: UCOMIEnumString interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices
+{
+ using System;
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.IEnumString instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [Guid("00000101-0000-0000-C000-000000000046")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface UCOMIEnumString
+ {
+ [PreserveSig]
+ int Next(int celt, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 0), Out] String[] rgelt, out int pceltFetched);
+ [PreserveSig]
+ int Skip(int celt);
+ [PreserveSig]
+ int Reset();
+ void Clone(out UCOMIEnumString ppenum);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/UCOMIEnumVARIANT.cs b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIEnumVARIANT.cs
new file mode 100644
index 0000000000..0d8585ffdb
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIEnumVARIANT.cs
@@ -0,0 +1,35 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: UCOMIEnumVARIANT interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices
+{
+ using System;
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.IEnumVARIANT instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [Guid("00020404-0000-0000-C000-000000000046")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface UCOMIEnumVARIANT
+ {
+ [PreserveSig]
+ int Next(int celt, int rgvar, int pceltFetched);
+
+ [PreserveSig]
+ int Skip(int celt);
+
+ [PreserveSig]
+ int Reset();
+
+ void Clone(int ppenum);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/UCOMIEnumerable.cs b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIEnumerable.cs
new file mode 100644
index 0000000000..81e0133923
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIEnumerable.cs
@@ -0,0 +1,30 @@
+// 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.
+
+/*==========================================================================
+**
+** Interface: UCOMIEnumerable
+**
+**
+** Purpose:
+** This interface is redefined here since the original IEnumerable interface
+** has all its methods marked as ecall's since it is a managed standard
+** interface. This interface is used from within the runtime to make a call
+** on the COM server directly when it implements the IEnumerable interface.
+**
+**
+==========================================================================*/
+namespace System.Runtime.InteropServices
+{
+ using System;
+ using System.Collections;
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.IEnumerable instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [Guid("496B0ABE-CDEE-11d3-88E8-00902754C43A")]
+ internal interface UCOMIEnumerable
+ {
+ [DispId(-4)]
+ IEnumerator GetEnumerator();
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/UCOMIEnumerator.cs b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIEnumerator.cs
new file mode 100644
index 0000000000..af886c46ac
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIEnumerator.cs
@@ -0,0 +1,32 @@
+// 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.
+
+/*==========================================================================
+**
+** Interface: UCOMIEnumerator
+**
+**
+** Purpose:
+** This interface is redefined here since the original IEnumerator interface
+** has all its methods marked as ecall's since it is a managed standard
+** interface. This interface is used from within the runtime to make a call
+** on the COM server directly when it implements the IEnumerator interface.
+**
+**
+==========================================================================*/
+namespace System.Runtime.InteropServices
+{
+ using System;
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.IEnumerator instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [Guid("496B0ABF-CDEE-11d3-88E8-00902754C43A")]
+ internal interface UCOMIEnumerator
+ {
+ bool MoveNext();
+ Object Current {
+ get;
+ }
+ void Reset();
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/UCOMIExpando.cs b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIExpando.cs
new file mode 100644
index 0000000000..2f85c14bc6
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIExpando.cs
@@ -0,0 +1,33 @@
+// 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.
+
+/*==========================================================================
+**
+** Interface: UCOMIExpando
+**
+**
+** Purpose:
+** This interface is redefined here since the original IExpando interface
+** has all its methods marked as ecall's since it is a managed standard
+** interface. This interface is used from within the runtime to make a call
+** on the COM server directly when it implements the IExpando interface.
+**
+**
+==========================================================================*/
+namespace System.Runtime.InteropServices
+{
+
+ using System;
+ using System.Reflection;
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.IExpando instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [Guid("AFBF15E6-C37C-11d2-B88E-00A0C9B471B8")]
+ internal interface UCOMIExpando : UCOMIReflect
+ {
+ FieldInfo AddField(String name);
+ PropertyInfo AddProperty(String name);
+ MethodInfo AddMethod(String name, Delegate method);
+ void RemoveMember(MemberInfo m);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/UCOMIMoniker.cs b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIMoniker.cs
new file mode 100644
index 0000000000..bd5b6f4916
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIMoniker.cs
@@ -0,0 +1,60 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: UCOMIMoniker interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices
+{
+ using System;
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.FILETIME instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [StructLayout(LayoutKind.Sequential)]
+
+ public struct FILETIME
+ {
+ public int dwLowDateTime;
+ public int dwHighDateTime;
+ }
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.IMoniker instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [Guid("0000000f-0000-0000-C000-000000000046")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface UCOMIMoniker
+ {
+ // IPersist portion
+ void GetClassID(out Guid pClassID);
+
+ // IPersistStream portion
+ [PreserveSig]
+ int IsDirty();
+ void Load(UCOMIStream pStm);
+ void Save(UCOMIStream pStm, [MarshalAs(UnmanagedType.Bool)] bool fClearDirty);
+ void GetSizeMax(out Int64 pcbSize);
+
+ // IMoniker portion
+ void BindToObject(UCOMIBindCtx pbc, UCOMIMoniker pmkToLeft, [In()] ref Guid riidResult, [MarshalAs(UnmanagedType.Interface)] out Object ppvResult);
+ void BindToStorage(UCOMIBindCtx pbc, UCOMIMoniker pmkToLeft, [In()] ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out Object ppvObj);
+ void Reduce(UCOMIBindCtx pbc, int dwReduceHowFar, ref UCOMIMoniker ppmkToLeft, out UCOMIMoniker ppmkReduced);
+ void ComposeWith(UCOMIMoniker pmkRight, [MarshalAs(UnmanagedType.Bool)] bool fOnlyIfNotGeneric, out UCOMIMoniker ppmkComposite);
+ void Enum([MarshalAs(UnmanagedType.Bool)] bool fForward, out UCOMIEnumMoniker ppenumMoniker);
+ void IsEqual(UCOMIMoniker pmkOtherMoniker);
+ void Hash(out int pdwHash);
+ void IsRunning(UCOMIBindCtx pbc, UCOMIMoniker pmkToLeft, UCOMIMoniker pmkNewlyRunning);
+ void GetTimeOfLastChange(UCOMIBindCtx pbc, UCOMIMoniker pmkToLeft, out FILETIME pFileTime);
+ void Inverse(out UCOMIMoniker ppmk);
+ void CommonPrefixWith(UCOMIMoniker pmkOther, out UCOMIMoniker ppmkPrefix);
+ void RelativePathTo(UCOMIMoniker pmkOther, out UCOMIMoniker ppmkRelPath);
+ void GetDisplayName(UCOMIBindCtx pbc, UCOMIMoniker pmkToLeft, [MarshalAs(UnmanagedType.LPWStr)] out String ppszDisplayName);
+ void ParseDisplayName(UCOMIBindCtx pbc, UCOMIMoniker pmkToLeft, [MarshalAs(UnmanagedType.LPWStr)] String pszDisplayName, out int pchEaten, out UCOMIMoniker ppmkOut);
+ void IsSystemMoniker(out int pdwMksys);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/UCOMIPersistFile.cs b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIPersistFile.cs
new file mode 100644
index 0000000000..ac465e771f
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIPersistFile.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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: UCOMIPersistFile interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices {
+
+ using System;
+ using DWORD = System.UInt32;
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.IPersistFile instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [Guid("0000010b-0000-0000-C000-000000000046")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface UCOMIPersistFile
+ {
+ // IPersist portion
+ void GetClassID(out Guid pClassID);
+
+ // IPersistFile portion
+ [PreserveSig]
+ int IsDirty();
+ void Load([MarshalAs(UnmanagedType.LPWStr)] String pszFileName, int dwMode);
+ void Save([MarshalAs(UnmanagedType.LPWStr)] String pszFileName, [MarshalAs(UnmanagedType.Bool)] bool fRemember);
+ void SaveCompleted([MarshalAs(UnmanagedType.LPWStr)] String pszFileName);
+ void GetCurFile([MarshalAs(UnmanagedType.LPWStr)] out String ppszFileName);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/UCOMIReflect.cs b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIReflect.cs
new file mode 100644
index 0000000000..d6cdd6828e
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIReflect.cs
@@ -0,0 +1,79 @@
+// 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.
+
+/*==========================================================================
+**
+** Interface: UCOMIReflect
+**
+**
+** Purpose:
+** This interface is redefined here since the original IReflect interface
+** has all its methods marked as ecall's since it is a managed standard
+** interface. This interface is used from within the runtime to make a call
+** on the COM server directly when it implements the IReflect interface.
+**
+**
+==========================================================================*/
+namespace System.Runtime.InteropServices
+{
+ using System;
+ using System.Reflection;
+ using CultureInfo = System.Globalization.CultureInfo;
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.IReflect instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [Guid("AFBF15E5-C37C-11d2-B88E-00A0C9B471B8")]
+ internal interface UCOMIReflect
+ {
+ MethodInfo GetMethod(String name,BindingFlags bindingAttr,Binder binder,
+ Type[] types,ParameterModifier[] modifiers);
+
+ MethodInfo GetMethod(String name,BindingFlags bindingAttr);
+
+ MethodInfo[] GetMethods(
+ BindingFlags bindingAttr);
+
+ FieldInfo GetField(
+ String name,
+ BindingFlags bindingAttr);
+
+ FieldInfo[] GetFields(
+ BindingFlags bindingAttr);
+
+ PropertyInfo GetProperty(
+ String name,
+ BindingFlags bindingAttr);
+
+ PropertyInfo GetProperty(
+ String name,
+ BindingFlags bindingAttr,
+ Binder binder,
+ Type returnType,
+ Type[] types,
+ ParameterModifier[] modifiers);
+
+ PropertyInfo[] GetProperties(
+ BindingFlags bindingAttr);
+
+ MemberInfo[] GetMember(
+ String name,
+ BindingFlags bindingAttr);
+
+ MemberInfo[] GetMembers(
+ BindingFlags bindingAttr);
+
+ Object InvokeMember(
+ String name,
+ BindingFlags invokeAttr,
+ Binder binder,
+ Object target,
+ Object[] args,
+ ParameterModifier[] modifiers,
+ CultureInfo culture,
+ String[] namedParameters);
+
+ Type UnderlyingSystemType {
+ get;
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/UCOMIRunningObjectTable.cs b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIRunningObjectTable.cs
new file mode 100644
index 0000000000..8088c0417f
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIRunningObjectTable.cs
@@ -0,0 +1,32 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: UCOMIRunningObjectTable interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices
+{
+ using System;
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.IRunningObjectTable instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [Guid("00000010-0000-0000-C000-000000000046")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface UCOMIRunningObjectTable
+ {
+ void Register(int grfFlags, [MarshalAs(UnmanagedType.Interface)] Object punkObject, UCOMIMoniker pmkObjectName, out int pdwRegister);
+ void Revoke(int dwRegister);
+ void IsRunning(UCOMIMoniker pmkObjectName);
+ void GetObject(UCOMIMoniker pmkObjectName, [MarshalAs(UnmanagedType.Interface)] out Object ppunkObject);
+ void NoteChangeTime(int dwRegister, ref FILETIME pfiletime);
+ void GetTimeOfLastChange(UCOMIMoniker pmkObjectName, out FILETIME pfiletime);
+ void EnumRunning(out UCOMIEnumMoniker ppenumMoniker);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/UCOMIStream.cs b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIStream.cs
new file mode 100644
index 0000000000..dc2cb53d97
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/UCOMIStream.cs
@@ -0,0 +1,57 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: UCOMIStream interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices
+{
+ using System;
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.STATSTG instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+
+ public struct STATSTG
+ {
+ public String pwcsName;
+ public int type;
+ public Int64 cbSize;
+ public FILETIME mtime;
+ public FILETIME ctime;
+ public FILETIME atime;
+ public int grfMode;
+ public int grfLocksSupported;
+ public Guid clsid;
+ public int grfStateBits;
+ public int reserved;
+ }
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.IStream instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [Guid("0000000c-0000-0000-C000-000000000046")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface UCOMIStream
+ {
+ // ISequentialStream portion
+ void Read([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1), Out] Byte[] pv, int cb,IntPtr pcbRead);
+ void Write([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] Byte[] pv, int cb, IntPtr pcbWritten);
+
+ // IStream portion
+ void Seek(Int64 dlibMove, int dwOrigin, IntPtr plibNewPosition);
+ void SetSize(Int64 libNewSize);
+ void CopyTo(UCOMIStream pstm, Int64 cb, IntPtr pcbRead, IntPtr pcbWritten);
+ void Commit(int grfCommitFlags);
+ void Revert();
+ void LockRegion(Int64 libOffset, Int64 cb, int dwLockType);
+ void UnlockRegion(Int64 libOffset, Int64 cb, int dwLockType);
+ void Stat(out STATSTG pstatstg, int grfStatFlag);
+ void Clone(out UCOMIStream ppstm);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/UCOMITypeComp.cs b/src/mscorlib/src/System/Runtime/InteropServices/UCOMITypeComp.cs
new file mode 100644
index 0000000000..0ef1e549a5
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/UCOMITypeComp.cs
@@ -0,0 +1,52 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: UCOMITypeComp interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices
+{
+ using System;
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.DESCKIND instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [Serializable]
+ public enum DESCKIND
+ {
+ DESCKIND_NONE = 0,
+ DESCKIND_FUNCDESC = DESCKIND_NONE + 1,
+ DESCKIND_VARDESC = DESCKIND_FUNCDESC + 1,
+ DESCKIND_TYPECOMP = DESCKIND_VARDESC + 1,
+ DESCKIND_IMPLICITAPPOBJ = DESCKIND_TYPECOMP + 1,
+ DESCKIND_MAX = DESCKIND_IMPLICITAPPOBJ + 1
+ }
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.BINDPTR instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [StructLayout(LayoutKind.Explicit, CharSet=CharSet.Unicode)]
+
+ public struct BINDPTR
+ {
+ [FieldOffset(0)]
+ public IntPtr lpfuncdesc;
+ [FieldOffset(0)]
+ public IntPtr lpvardesc;
+ [FieldOffset(0)]
+ public IntPtr lptcomp;
+ }
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.ITypeComp instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [Guid("00020403-0000-0000-C000-000000000046")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface UCOMITypeComp
+ {
+ void Bind([MarshalAs(UnmanagedType.LPWStr)] String szName, int lHashVal, Int16 wFlags, out UCOMITypeInfo ppTInfo, out DESCKIND pDescKind, out BINDPTR pBindPtr);
+ void BindType([MarshalAs(UnmanagedType.LPWStr)] String szName, int lHashVal, out UCOMITypeInfo ppTInfo, out UCOMITypeComp ppTComp);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/UCOMITypeInfo.cs b/src/mscorlib/src/System/Runtime/InteropServices/UCOMITypeInfo.cs
new file mode 100644
index 0000000000..e26964f5a3
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/UCOMITypeInfo.cs
@@ -0,0 +1,330 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: UCOMITypeInfo interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices
+{
+ using System;
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.TYPEKIND instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [Serializable]
+ public enum TYPEKIND
+ {
+ TKIND_ENUM = 0,
+ TKIND_RECORD = TKIND_ENUM + 1,
+ TKIND_MODULE = TKIND_RECORD + 1,
+ TKIND_INTERFACE = TKIND_MODULE + 1,
+ TKIND_DISPATCH = TKIND_INTERFACE + 1,
+ TKIND_COCLASS = TKIND_DISPATCH + 1,
+ TKIND_ALIAS = TKIND_COCLASS + 1,
+ TKIND_UNION = TKIND_ALIAS + 1,
+ TKIND_MAX = TKIND_UNION + 1
+ }
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.TYPEFLAGS instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+[Serializable]
+[Flags()]
+ public enum TYPEFLAGS : short
+ {
+ TYPEFLAG_FAPPOBJECT = 0x1,
+ TYPEFLAG_FCANCREATE = 0x2,
+ TYPEFLAG_FLICENSED = 0x4,
+ TYPEFLAG_FPREDECLID = 0x8,
+ TYPEFLAG_FHIDDEN = 0x10,
+ TYPEFLAG_FCONTROL = 0x20,
+ TYPEFLAG_FDUAL = 0x40,
+ TYPEFLAG_FNONEXTENSIBLE = 0x80,
+ TYPEFLAG_FOLEAUTOMATION = 0x100,
+ TYPEFLAG_FRESTRICTED = 0x200,
+ TYPEFLAG_FAGGREGATABLE = 0x400,
+ TYPEFLAG_FREPLACEABLE = 0x800,
+ TYPEFLAG_FDISPATCHABLE = 0x1000,
+ TYPEFLAG_FREVERSEBIND = 0x2000,
+ TYPEFLAG_FPROXY = 0x4000
+ }
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.IMPLTYPEFLAGS instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+[Serializable]
+[Flags()]
+ public enum IMPLTYPEFLAGS
+ {
+ IMPLTYPEFLAG_FDEFAULT = 0x1,
+ IMPLTYPEFLAG_FSOURCE = 0x2,
+ IMPLTYPEFLAG_FRESTRICTED = 0x4,
+ IMPLTYPEFLAG_FDEFAULTVTABLE = 0x8,
+ }
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.TYPEATTR instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+ public struct TYPEATTR
+ {
+ // Constant used with the memid fields.
+ public const int MEMBER_ID_NIL = unchecked((int)0xFFFFFFFF);
+
+ // Actual fields of the TypeAttr struct.
+ public Guid guid;
+ public Int32 lcid;
+ public Int32 dwReserved;
+ public Int32 memidConstructor;
+ public Int32 memidDestructor;
+ public IntPtr lpstrSchema;
+ public Int32 cbSizeInstance;
+ public TYPEKIND typekind;
+ public Int16 cFuncs;
+ public Int16 cVars;
+ public Int16 cImplTypes;
+ public Int16 cbSizeVft;
+ public Int16 cbAlignment;
+ public TYPEFLAGS wTypeFlags;
+ public Int16 wMajorVerNum;
+ public Int16 wMinorVerNum;
+ public TYPEDESC tdescAlias;
+ public IDLDESC idldescType;
+ }
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.FUNCDESC instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [StructLayout(LayoutKind.Sequential)]
+ public struct FUNCDESC
+ {
+ public int memid; //MEMBERID memid;
+ public IntPtr lprgscode; // /* [size_is(cScodes)] */ SCODE RPC_FAR *lprgscode;
+ public IntPtr lprgelemdescParam; // /* [size_is(cParams)] */ ELEMDESC __RPC_FAR *lprgelemdescParam;
+ public FUNCKIND funckind; //FUNCKIND funckind;
+ public INVOKEKIND invkind; //INVOKEKIND invkind;
+ public CALLCONV callconv; //CALLCONV callconv;
+ public Int16 cParams; //short cParams;
+ public Int16 cParamsOpt; //short cParamsOpt;
+ public Int16 oVft; //short oVft;
+ public Int16 cScodes; //short cScodes;
+ public ELEMDESC elemdescFunc; //ELEMDESC elemdescFunc;
+ public Int16 wFuncFlags; //WORD wFuncFlags;
+ }
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.IDLFLAG instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+[Serializable]
+[Flags()]
+ public enum IDLFLAG : short
+ {
+ IDLFLAG_NONE = PARAMFLAG.PARAMFLAG_NONE,
+ IDLFLAG_FIN = PARAMFLAG.PARAMFLAG_FIN,
+ IDLFLAG_FOUT = PARAMFLAG.PARAMFLAG_FOUT,
+ IDLFLAG_FLCID = PARAMFLAG.PARAMFLAG_FLCID,
+ IDLFLAG_FRETVAL = PARAMFLAG.PARAMFLAG_FRETVAL
+ }
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.IDLDESC instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+ public struct IDLDESC
+ {
+ public int dwReserved;
+ public IDLFLAG wIDLFlags;
+ }
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.PARAMFLAG instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+[Serializable]
+[Flags()]
+ public enum PARAMFLAG :short
+ {
+ PARAMFLAG_NONE = 0,
+ PARAMFLAG_FIN = 0x1,
+ PARAMFLAG_FOUT = 0x2,
+ PARAMFLAG_FLCID = 0x4,
+ PARAMFLAG_FRETVAL = 0x8,
+ PARAMFLAG_FOPT = 0x10,
+ PARAMFLAG_FHASDEFAULT = 0x20,
+ PARAMFLAG_FHASCUSTDATA = 0x40
+ }
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.PARAMDESC instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+ public struct PARAMDESC
+ {
+ public IntPtr lpVarValue;
+ public PARAMFLAG wParamFlags;
+ }
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.TYPEDESC instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+ public struct TYPEDESC
+ {
+ public IntPtr lpValue;
+ public Int16 vt;
+ }
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.ELEMDESC instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+ public struct ELEMDESC
+ {
+ public TYPEDESC tdesc;
+
+ [System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit, CharSet=CharSet.Unicode)]
+ [ComVisible(false)]
+ public struct DESCUNION
+ {
+ [FieldOffset(0)]
+ public IDLDESC idldesc;
+ [FieldOffset(0)]
+ public PARAMDESC paramdesc;
+ };
+ public DESCUNION desc;
+ }
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.VARDESC instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+ public struct VARDESC
+ {
+ public int memid;
+ public String lpstrSchema;
+
+ [System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit, CharSet=CharSet.Unicode)]
+ [ComVisible(false)]
+ public struct DESCUNION
+ {
+ [FieldOffset(0)]
+ public int oInst;
+ [FieldOffset(0)]
+ public IntPtr lpvarValue;
+ };
+
+ public ELEMDESC elemdescVar;
+ public short wVarFlags;
+ public VarEnum varkind;
+ }
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.DISPPARAMS instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+ public struct DISPPARAMS
+ {
+ public IntPtr rgvarg;
+ public IntPtr rgdispidNamedArgs;
+ public int cArgs;
+ public int cNamedArgs;
+ }
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.EXCEPINFO instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+ public struct EXCEPINFO
+ {
+ public Int16 wCode;
+ public Int16 wReserved;
+ [MarshalAs(UnmanagedType.BStr)] public String bstrSource;
+ [MarshalAs(UnmanagedType.BStr)] public String bstrDescription;
+ [MarshalAs(UnmanagedType.BStr)] public String bstrHelpFile;
+ public int dwHelpContext;
+ public IntPtr pvReserved;
+ public IntPtr pfnDeferredFillIn;
+ }
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.FUNCKIND instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [Serializable]
+ public enum FUNCKIND : int
+ {
+ FUNC_VIRTUAL = 0,
+ FUNC_PUREVIRTUAL = 1,
+ FUNC_NONVIRTUAL = 2,
+ FUNC_STATIC = 3,
+ FUNC_DISPATCH = 4
+ }
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.INVOKEKIND instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [Serializable]
+ public enum INVOKEKIND : int
+ {
+ INVOKE_FUNC = 0x1,
+ INVOKE_PROPERTYGET = 0x2,
+ INVOKE_PROPERTYPUT = 0x4,
+ INVOKE_PROPERTYPUTREF = 0x8
+ }
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.CALLCONV instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [Serializable]
+ public enum CALLCONV : int
+ {
+ CC_CDECL =1,
+ CC_MSCPASCAL=2,
+ CC_PASCAL =CC_MSCPASCAL,
+ CC_MACPASCAL=3,
+ CC_STDCALL =4,
+ CC_RESERVED =5,
+ CC_SYSCALL =6,
+ CC_MPWCDECL =7,
+ CC_MPWPASCAL=8,
+ CC_MAX =9
+ }
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.FUNCFLAGS instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+[Serializable]
+[Flags()]
+ public enum FUNCFLAGS : short
+ {
+ FUNCFLAG_FRESTRICTED= 0x1,
+ FUNCFLAG_FSOURCE = 0x2,
+ FUNCFLAG_FBINDABLE = 0x4,
+ FUNCFLAG_FREQUESTEDIT = 0x8,
+ FUNCFLAG_FDISPLAYBIND = 0x10,
+ FUNCFLAG_FDEFAULTBIND = 0x20,
+ FUNCFLAG_FHIDDEN = 0x40,
+ FUNCFLAG_FUSESGETLASTERROR= 0x80,
+ FUNCFLAG_FDEFAULTCOLLELEM= 0x100,
+ FUNCFLAG_FUIDEFAULT = 0x200,
+ FUNCFLAG_FNONBROWSABLE = 0x400,
+ FUNCFLAG_FREPLACEABLE = 0x800,
+ FUNCFLAG_FIMMEDIATEBIND = 0x1000
+ }
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.VARFLAGS instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+[Serializable]
+[Flags()]
+ public enum VARFLAGS : short
+ {
+ VARFLAG_FREADONLY =0x1,
+ VARFLAG_FSOURCE =0x2,
+ VARFLAG_FBINDABLE =0x4,
+ VARFLAG_FREQUESTEDIT =0x8,
+ VARFLAG_FDISPLAYBIND =0x10,
+ VARFLAG_FDEFAULTBIND =0x20,
+ VARFLAG_FHIDDEN =0x40,
+ VARFLAG_FRESTRICTED =0x80,
+ VARFLAG_FDEFAULTCOLLELEM =0x100,
+ VARFLAG_FUIDEFAULT =0x200,
+ VARFLAG_FNONBROWSABLE =0x400,
+ VARFLAG_FREPLACEABLE =0x800,
+ VARFLAG_FIMMEDIATEBIND =0x1000
+ }
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.ITypeInfo instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [Guid("00020401-0000-0000-C000-000000000046")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface UCOMITypeInfo
+ {
+ void GetTypeAttr(out IntPtr ppTypeAttr);
+ void GetTypeComp(out UCOMITypeComp ppTComp);
+ void GetFuncDesc(int index, out IntPtr ppFuncDesc);
+ void GetVarDesc(int index, out IntPtr ppVarDesc);
+ void GetNames(int memid, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2), Out] String[] rgBstrNames, int cMaxNames, out int pcNames);
+ void GetRefTypeOfImplType(int index, out int href);
+ void GetImplTypeFlags(int index, out int pImplTypeFlags);
+ void GetIDsOfNames([MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 1), In] String[] rgszNames, int cNames, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1), Out] int[] pMemId);
+ void Invoke([MarshalAs(UnmanagedType.IUnknown)] Object pvInstance, int memid, Int16 wFlags, ref DISPPARAMS pDispParams, out Object pVarResult, out EXCEPINFO pExcepInfo, out int puArgErr);
+ void GetDocumentation(int index, out String strName, out String strDocString, out int dwHelpContext, out String strHelpFile);
+ void GetDllEntry(int memid, INVOKEKIND invKind, out String pBstrDllName, out String pBstrName, out Int16 pwOrdinal);
+ void GetRefTypeInfo(int hRef, out UCOMITypeInfo ppTI);
+ void AddressOfMember(int memid, INVOKEKIND invKind, out IntPtr ppv);
+ void CreateInstance([MarshalAs(UnmanagedType.IUnknown)] Object pUnkOuter, ref Guid riid, [MarshalAs(UnmanagedType.IUnknown), Out] out Object ppvObj);
+ void GetMops(int memid, out String pBstrMops);
+ void GetContainingTypeLib(out UCOMITypeLib ppTLB, out int pIndex);
+ void ReleaseTypeAttr(IntPtr pTypeAttr);
+ void ReleaseFuncDesc(IntPtr pFuncDesc);
+ void ReleaseVarDesc(IntPtr pVarDesc);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/UCOMITypeLib.cs b/src/mscorlib/src/System/Runtime/InteropServices/UCOMITypeLib.cs
new file mode 100644
index 0000000000..c8b63deff6
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/UCOMITypeLib.cs
@@ -0,0 +1,71 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: UCOMITypeLib interface definition.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices
+{
+ using System;
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.SYSKIND instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [Serializable]
+ public enum SYSKIND
+ {
+ SYS_WIN16 = 0,
+ SYS_WIN32 = SYS_WIN16 + 1,
+ SYS_MAC = SYS_WIN32 + 1
+ }
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.LIBFLAGS instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+[Serializable]
+[Flags()]
+ public enum LIBFLAGS : short
+ {
+ LIBFLAG_FRESTRICTED = 0x1,
+ LIBFLAG_FCONTROL = 0x2,
+ LIBFLAG_FHIDDEN = 0x4,
+ LIBFLAG_FHASDISKIMAGE = 0x8
+ }
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.TYPELIBATTR instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+ [Serializable]
+ public struct TYPELIBATTR
+ {
+ public Guid guid;
+ public int lcid;
+ public SYSKIND syskind;
+ public Int16 wMajorVerNum;
+ public Int16 wMinorVerNum;
+ public LIBFLAGS wLibFlags;
+ }
+
+ [Obsolete("Use System.Runtime.InteropServices.ComTypes.ITypeLib instead. http://go.microsoft.com/fwlink/?linkid=14202", false)]
+ [Guid("00020402-0000-0000-C000-000000000046")]
+ [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ [ComImport]
+ public interface UCOMITypeLib
+ {
+ [PreserveSig]
+ int GetTypeInfoCount();
+ void GetTypeInfo(int index, out UCOMITypeInfo ppTI);
+ void GetTypeInfoType(int index, out TYPEKIND pTKind);
+ void GetTypeInfoOfGuid(ref Guid guid, out UCOMITypeInfo ppTInfo);
+ void GetLibAttr(out IntPtr ppTLibAttr);
+ void GetTypeComp(out UCOMITypeComp ppTComp);
+ void GetDocumentation(int index, out String strName, out String strDocString, out int dwHelpContext, out String strHelpFile);
+ [return : MarshalAs(UnmanagedType.Bool)]
+ bool IsName([MarshalAs(UnmanagedType.LPWStr)] String szNameBuf, int lHashVal);
+ void FindName([MarshalAs(UnmanagedType.LPWStr)] String szNameBuf, int lHashVal, [MarshalAs(UnmanagedType.LPArray), Out] UCOMITypeInfo[] ppTInfo, [MarshalAs(UnmanagedType.LPArray), Out] int[] rgMemId, ref Int16 pcFound);
+ [PreserveSig]
+ void ReleaseTLibAttr(IntPtr pTLibAttr);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/UnknownWrapper.cs b/src/mscorlib/src/System/Runtime/InteropServices/UnknownWrapper.cs
new file mode 100644
index 0000000000..69ef2dcc06
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/UnknownWrapper.cs
@@ -0,0 +1,37 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: Wrapper that is converted to a variant with VT_UNKNOWN.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.InteropServices {
+
+ using System;
+
+ [Serializable]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class UnknownWrapper
+ {
+ public UnknownWrapper(Object obj)
+ {
+ m_WrappedObject = obj;
+ }
+
+ public Object WrappedObject
+ {
+ get
+ {
+ return m_WrappedObject;
+ }
+ }
+
+ private Object m_WrappedObject;
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/Variant.cs b/src/mscorlib/src/System/Runtime/InteropServices/Variant.cs
new file mode 100644
index 0000000000..9be1588ac0
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/InteropServices/Variant.cs
@@ -0,0 +1,659 @@
+// 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.
+
+namespace System.Runtime.InteropServices {
+ using System.Diagnostics;
+
+ /// <summary>
+ /// Variant is the basic COM type for late-binding. It can contain any other COM data type.
+ /// This type definition precisely matches the unmanaged data layout so that the struct can be passed
+ /// to and from COM calls.
+ /// </summary>
+ [StructLayout(LayoutKind.Explicit)]
+ [System.Security.SecurityCritical]
+ internal struct Variant {
+
+#if DEBUG
+ static Variant() {
+ // Variant size is the size of 4 pointers (16 bytes) on a 32-bit processor,
+ // and 3 pointers (24 bytes) on a 64-bit processor.
+ int variantSize = Marshal.SizeOf(typeof(Variant));
+ if (IntPtr.Size == 4) {
+ BCLDebug.Assert(variantSize == (4 * IntPtr.Size), "variant");
+ } else {
+ BCLDebug.Assert(IntPtr.Size == 8, "variant");
+ BCLDebug.Assert(variantSize == (3 * IntPtr.Size), "variant");
+ }
+ }
+#endif
+
+ // Most of the data types in the Variant are carried in _typeUnion
+ [FieldOffset(0)] private TypeUnion _typeUnion;
+
+ // Decimal is the largest data type and it needs to use the space that is normally unused in TypeUnion._wReserved1, etc.
+ // Hence, it is declared to completely overlap with TypeUnion. A Decimal does not use the first two bytes, and so
+ // TypeUnion._vt can still be used to encode the type.
+ [FieldOffset(0)] private Decimal _decimal;
+
+ [StructLayout(LayoutKind.Sequential)]
+ private struct TypeUnion {
+ internal ushort _vt;
+ internal ushort _wReserved1;
+ internal ushort _wReserved2;
+ internal ushort _wReserved3;
+
+ internal UnionTypes _unionTypes;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ private struct Record {
+ private IntPtr _record;
+ private IntPtr _recordInfo;
+ }
+
+ [System.D