Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / ComIntegration / TypeCacheManager.cs / 2 / TypeCacheManager.cs
//------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- namespace System.ServiceModel.ComIntegration { using System; using System.Globalization; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using Microsoft.Win32; using System.Reflection; using System.Collections.Generic; using System.Collections.Specialized; using System.Threading; using System.Diagnostics; using System.ServiceModel.Diagnostics; internal class TypeCacheManager : ITypeCacheManager { private enum RegKind { Default = 0, Register = 1, None = 2 } // TypeCacheManager.Provider will give access to the static instance of the TypeCache private static Guid clrAssemblyCustomID = new Guid("90883F05-3D28-11D2-8F17-00A0C9A6186D"); private static object instanceLock = new object(); static public ITypeCacheManager Provider { get { lock (instanceLock) { if (instance == null) { ITypeCacheManager localInstance = new TypeCacheManager (); Thread.MemoryBarrier (); instance = localInstance; } } return instance; } } static internal ITypeCacheManager instance; // Convert to typeLibrary ID (GUID) private DictionaryassemblyTable ; private Dictionary typeTable; private object typeTableLock; private object assemblyTableLock; internal TypeCacheManager () { assemblyTable = new Dictionary (); typeTable = new Dictionary (); typeTableLock = new object (); assemblyTableLock = new object (); } private Guid GettypeLibraryIDFromIID (Guid iid, bool isServer, out String version) { // In server we need to open the the User hive for the Process User. RegistryKey interfaceKey = null; try { string keyName = null; if (isServer) { keyName = String.Concat("software\\classes\\interface\\{", iid.ToString(), "}\\typelib"); interfaceKey = Registry.LocalMachine.OpenSubKey(keyName, false); } else { keyName = String.Concat("interface\\{", iid.ToString(), "}\\typelib"); interfaceKey = Registry.ClassesRoot.OpenSubKey(keyName, false); } if (interfaceKey == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError (new InvalidOperationException (SR.GetString (SR.InterfaceNotRegistered))); string typeLibID = interfaceKey.GetValue ("").ToString (); if (string.IsNullOrEmpty(typeLibID)) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError (new InvalidOperationException (SR.GetString (SR.NoTypeLibraryFoundForInterface))); version = interfaceKey.GetValue ("Version").ToString (); if (string.IsNullOrEmpty(version)) version = "1.0"; Guid typeLibraryID ; if ( !DiagnosticUtility.Utility.TryCreateGuid(typeLibID, out typeLibraryID)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError (new InvalidOperationException (SR.GetString (SR.BadInterfaceRegistration))); } return typeLibraryID; } finally { if (interfaceKey != null) interfaceKey.Close (); } } private void ParseVersion (string version, out ushort major, out ushort minor) { major = 0; minor = 0; if (String.IsNullOrEmpty(version)) return; int indexOfDot = version.IndexOf (".", StringComparison.Ordinal); try { if (indexOfDot == -1) { major = Convert.ToUInt16 (version, NumberFormatInfo.InvariantInfo); minor = 0; } else { major = Convert.ToUInt16 (version.Substring (0, indexOfDot ), NumberFormatInfo.InvariantInfo); string minorVersion = version.Substring (indexOfDot + 1); int indexOfDot2 = version.IndexOf (".", StringComparison.Ordinal); if (indexOfDot2 != -1) // Ignore anything beyond the first minor version. minorVersion = minorVersion.Substring (0, indexOfDot2); minor = Convert.ToUInt16 (minorVersion, NumberFormatInfo.InvariantInfo); } } catch (FormatException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError (new InvalidOperationException (SR.GetString (SR.BadInterfaceVersion))); } catch (OverflowException ) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError (new InvalidOperationException (SR.GetString (SR.BadInterfaceVersion))); } } private ITypeLib2 GettypeLibrary (Guid typeLibraryID, string version) { ushort major = 0; ushort minor = 0; const int lcidLocalIndependent = 0; ParseVersion (version, out major, out minor); object otlb; int hr = SafeNativeMethods.LoadRegTypeLib (ref typeLibraryID, major, minor, lcidLocalIndependent, out otlb); if (hr != 0 || null == otlb) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError (new COMException (SR.GetString (SR.FailedToLoadTypeLibrary), hr)); return otlb as ITypeLib2; } private Assembly ResolveAssemblyFromIID (Guid iid, bool noAssemblyGeneration, bool isServer) { String version; Guid typeLibraryID = GettypeLibraryIDFromIID (iid, isServer, out version); return ResolveAssemblyFromTypeLibID(iid, typeLibraryID, version, noAssemblyGeneration); } private Assembly ResolveAssemblyFromTypeLibID(Guid iid, Guid typeLibraryID, string version, bool noAssemblyGeneration) { ComPlusTLBImportTrace.Trace(TraceEventType.Verbose, TraceCode.ComIntegrationTLBImportStarting, SR.TraceCodeComIntegrationTLBImportStarting, iid, typeLibraryID); Assembly asm; bool generateNativeAssembly = false; ITypeLib2 typeLibrary = null; try { lock (assemblyTableLock) { assemblyTable.TryGetValue(typeLibraryID, out asm); if (asm == null) { typeLibrary = GettypeLibrary(typeLibraryID, version); object opaqueData = null; typeLibrary.GetCustData(ref clrAssemblyCustomID, out opaqueData); if (opaqueData == null) generateNativeAssembly = true; // No custom data for this IID this is not a CLR typeLibrary String assembly = opaqueData as String; if (String.IsNullOrEmpty(assembly)) generateNativeAssembly = true; // No custom data for this IID this is not a CLR typeLibrary if (noAssemblyGeneration && generateNativeAssembly) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.NativeTypeLibraryNotAllowed, typeLibraryID))); else if (!generateNativeAssembly) { ComPlusTLBImportTrace.Trace(TraceEventType.Verbose, TraceCode.ComIntegrationTLBImportFromAssembly, SR.TraceCodeComIntegrationTLBImportFromAssembly, iid, typeLibraryID, assembly); asm = Assembly.Load(assembly); // Assembly.Load will get a full assembly name } else { ComPlusTLBImportTrace.Trace(TraceEventType.Verbose, TraceCode.ComIntegrationTLBImportFromTypelib, SR.TraceCodeComIntegrationTLBImportFromTypelib, iid, typeLibraryID); asm = TypeLibraryHelper.GenerateAssemblyFromNativeTypeLibrary(iid, typeLibraryID, typeLibrary as ITypeLib); } assemblyTable[typeLibraryID] = asm; } } } catch (Exception e) { DiagnosticUtility.EventLog.LogEvent(TraceEventType.Error, EventLogCategory.ComPlus, EventLogEventId.ComPlusTLBImportError, iid.ToString(), typeLibraryID.ToString(), e.ToString()); throw; } finally { // Add Try Finally to cleanup typeLibrary if (typeLibrary != null) Marshal.ReleaseComObject((object)typeLibrary); } if (null == asm) { DiagnosticUtility.DebugAssert("Assembly should not be null"); throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(true); } ComPlusTLBImportTrace.Trace(TraceEventType.Verbose, TraceCode.ComIntegrationTLBImportFinished, SR.TraceCodeComIntegrationTLBImportFinished, iid, typeLibraryID); return asm; } private bool NoCoClassAttributeOnType (ICustomAttributeProvider attrProvider) { object[] attrs = System.ServiceModel.Description.ServiceReflector.GetCustomAttributes(attrProvider, typeof(CoClassAttribute), false); if (attrs.Length == 0) return true; else return false; } Assembly ITypeCacheManager.ResolveAssembly(Guid assembly) { Assembly ret = null; lock (assemblyTableLock) { this.assemblyTable.TryGetValue(assembly, out ret); } return ret; } void ITypeCacheManager.FindOrCreateType(Guid typeLibId, string typeLibVersion, Guid typeDefId, out Type userDefinedType, bool noAssemblyGeneration) { lock (typeTableLock) { typeTable.TryGetValue(typeDefId, out userDefinedType); if (userDefinedType == null) { Assembly asm = ResolveAssemblyFromTypeLibID(Guid.Empty, typeLibId, typeLibVersion, noAssemblyGeneration); foreach (Type t in asm.GetTypes()) { if (t.GUID == typeDefId) { if (t.IsValueType) { userDefinedType = t; break; } } } if (userDefinedType == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.UdtNotFoundInAssembly, typeDefId))); typeTable[typeDefId] = userDefinedType; } } } public void FindOrCreateType (Guid iid, out Type interfaceType, bool noAssemblyGeneration, bool isServer) { lock(typeTableLock) { typeTable.TryGetValue (iid, out interfaceType); if (interfaceType == null) { Type coClassInterface = null; Assembly asm = ResolveAssemblyFromIID (iid, noAssemblyGeneration, isServer); foreach (Type t in asm.GetTypes ()) { if (t.GUID == iid) { if (t.IsInterface && NoCoClassAttributeOnType (t) ) { interfaceType = t; break; } else if (t.IsInterface && !NoCoClassAttributeOnType (t)) { coClassInterface = t; } } } if ((interfaceType == null) && (coClassInterface != null)) interfaceType = coClassInterface; else if (interfaceType == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError (new InvalidOperationException (SR.GetString(SR.InterfaceNotFoundInAssembly))); typeTable[iid] = interfaceType; } } } void ITypeCacheManager.FindOrCreateType (Type serverType, Guid iid, out Type interfaceType, bool noAssemblyGeneration, bool isServer) { interfaceType = null; if (serverType == null) FindOrCreateType (iid, out interfaceType, noAssemblyGeneration, isServer); else { if (!serverType.IsClass) { DiagnosticUtility.DebugAssert("This should be a class"); throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); } foreach (Type interfaceInType in serverType.GetInterfaces ()) { if (interfaceInType.GUID == iid) { interfaceType = interfaceInType; break; } } if (interfaceType == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError (new InvalidOperationException (SR.GetString(SR.InterfaceNotFoundInAssembly))); } } public static Type ResolveClsidToType (Guid clsid) { string keyName = String.Concat("software\\classes\\clsid\\{", clsid.ToString(), "}\\InprocServer32"); using (RegistryKey clsidKey = Registry.LocalMachine.OpenSubKey(keyName, false)) { if (clsidKey != null) { using (RegistryKey assemblyKey = clsidKey.OpenSubKey (typeof (TypeCacheManager).Assembly.ImageRuntimeVersion)) { string assemblyName = null; if (assemblyKey == null) { keyName = null; foreach(string subKeyName in clsidKey.GetSubKeyNames()) { keyName = subKeyName; if (String.IsNullOrEmpty (keyName)) continue; using (RegistryKey assemblyKeyAny = clsidKey.OpenSubKey (keyName)) { assemblyName = (string) assemblyKeyAny.GetValue ("Assembly"); if (String.IsNullOrEmpty (assemblyName)) continue; else break; } } } else { assemblyName = (string) assemblyKey.GetValue ("Assembly"); } if (String.IsNullOrEmpty (assemblyName)) return null; Assembly asm = Assembly.Load (assemblyName); foreach (Type type in asm.GetTypes ()) { if (type.IsClass && (type.GUID == clsid)) return type; } return null; } } } // We failed to get the hive information from a native process hive lets go for the alternative bitness using (RegistryHandle hkcr = RegistryHandle.GetBitnessHKCR (IntPtr.Size == 8 ? false : true)) { if (hkcr != null) { using (RegistryHandle clsidKey = hkcr.OpenSubKey (String.Concat ("CLSID\\{" , clsid.ToString () , "}\\InprocServer32"))) { using (RegistryHandle assemblyKey = clsidKey.OpenSubKey (typeof (TypeCacheManager).Assembly.ImageRuntimeVersion)) { string assemblyName = null; if (assemblyKey == null) { keyName = null; foreach(string subKeyName in clsidKey.GetSubKeyNames()) { keyName = subKeyName; if (String.IsNullOrEmpty (keyName)) continue; using (RegistryHandle assemblyKeyAny = clsidKey.OpenSubKey (keyName)) { assemblyName = (string) assemblyKeyAny.GetStringValue ("Assembly"); if (String.IsNullOrEmpty (assemblyName)) continue; else break; } } } else { assemblyName = assemblyKey.GetStringValue ("Assembly"); } if (String.IsNullOrEmpty (assemblyName)) return null; Assembly asm = Assembly.Load (assemblyName); foreach (Type type in asm.GetTypes ()) { if (type.IsClass && (type.GUID == clsid)) return type; } return null; } } } } return null; } internal Type VerifyType (Guid iid ) { Type interfaceType = null; ((ITypeCacheManager)(this)).FindOrCreateType (iid, out interfaceType, false, true); return interfaceType; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- EventHandlingScope.cs
- NotificationContext.cs
- TextEditorTables.cs
- TransactionFlowBindingElement.cs
- CaseStatement.cs
- InfoCardRSACryptoProvider.cs
- StructuredProperty.cs
- Exceptions.cs
- KeyValueSerializer.cs
- ComplexType.cs
- StylusEditingBehavior.cs
- GeneralTransformGroup.cs
- OdbcConnectionHandle.cs
- ProviderIncompatibleException.cs
- SqlWorkflowInstanceStore.cs
- ConfigurationLockCollection.cs
- SessionParameter.cs
- CallTemplateAction.cs
- HMACSHA512.cs
- VirtualizedItemPattern.cs
- WindowsToolbarAsMenu.cs
- NewArrayExpression.cs
- ModelServiceImpl.cs
- Evidence.cs
- NetworkAddressChange.cs
- DigitalSignatureProvider.cs
- UnicastIPAddressInformationCollection.cs
- SortQueryOperator.cs
- Fault.cs
- XsdDuration.cs
- FatalException.cs
- DesignerDataColumn.cs
- KernelTypeValidation.cs
- WebPartEventArgs.cs
- DoubleAnimationBase.cs
- HttpErrorTraceRecord.cs
- ResourceReader.cs
- DataGridViewSelectedRowCollection.cs
- BmpBitmapEncoder.cs
- ReachFixedPageSerializerAsync.cs
- unsafeIndexingFilterStream.cs
- XmlTextReaderImplHelpers.cs
- EmptyStringExpandableObjectConverter.cs
- cache.cs
- XmlNodeChangedEventArgs.cs
- ChildTable.cs
- ShaderEffect.cs
- Pool.cs
- Set.cs
- LayoutTable.cs
- Point3DCollectionValueSerializer.cs
- BamlLocalizer.cs
- VisualBrush.cs
- Line.cs
- TargetFrameworkUtil.cs
- ControlBindingsConverter.cs
- ContainerCodeDomSerializer.cs
- AtomContentProperty.cs
- RegexCaptureCollection.cs
- XmlAttributeHolder.cs
- DataGridBoolColumn.cs
- SmtpTransport.cs
- BehaviorEditorPart.cs
- OptimalTextSource.cs
- securestring.cs
- CharStorage.cs
- GZipStream.cs
- InheritanceContextChangedEventManager.cs
- XmlSchemaAttributeGroup.cs
- DateTimeHelper.cs
- SchemaDeclBase.cs
- Variable.cs
- Queue.cs
- TargetParameterCountException.cs
- CompositeFontFamily.cs
- StreamMarshaler.cs
- ContentDisposition.cs
- PrefixHandle.cs
- DbConnectionClosed.cs
- cookiecollection.cs
- DataGridViewIntLinkedList.cs
- newitemfactory.cs
- PageAdapter.cs
- Environment.cs
- GPPOINTF.cs
- BounceEase.cs
- ActivityMarkupSerializer.cs
- RoleService.cs
- Int64Animation.cs
- SafeCoTaskMem.cs
- ResourceAttributes.cs
- BypassElementCollection.cs
- WindowsGraphicsCacheManager.cs
- TimelineGroup.cs
- SafeProcessHandle.cs
- TextElement.cs
- SoapTypeAttribute.cs
- StylusButtonCollection.cs
- EnterpriseServicesHelper.cs
- EncryptedPackageFilter.cs