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
- Lazy.cs
- FolderLevelBuildProvider.cs
- TextBoxLine.cs
- ParserOptions.cs
- MultiBinding.cs
- TreeNodeSelectionProcessor.cs
- AuthenticationService.cs
- path.cs
- ContractMethodInfo.cs
- DataGridViewComboBoxEditingControl.cs
- ZoneButton.cs
- returneventsaver.cs
- ListViewItemSelectionChangedEvent.cs
- AppSettingsReader.cs
- OleDbInfoMessageEvent.cs
- SoapAttributes.cs
- IpcManager.cs
- SpellCheck.cs
- RadioButton.cs
- XmlWrappingReader.cs
- AuthenticationManager.cs
- Psha1DerivedKeyGenerator.cs
- nulltextnavigator.cs
- ChineseLunisolarCalendar.cs
- CodeAccessPermission.cs
- ReliableOutputSessionChannel.cs
- GeneratedCodeAttribute.cs
- VariantWrapper.cs
- ProxyGenerator.cs
- TypeRestriction.cs
- _ListenerRequestStream.cs
- DependencySource.cs
- CopyOnWriteList.cs
- OlePropertyStructs.cs
- CriticalFinalizerObject.cs
- complextypematerializer.cs
- externdll.cs
- XPathMultyIterator.cs
- recordstate.cs
- mansign.cs
- LabelEditEvent.cs
- sqlinternaltransaction.cs
- NetTcpSectionData.cs
- ListViewDataItem.cs
- securitycriticaldataformultiplegetandset.cs
- PrimaryKeyTypeConverter.cs
- TextSelectionHighlightLayer.cs
- WebBrowserNavigatingEventHandler.cs
- Sequence.cs
- FactoryId.cs
- NativeMethodsCLR.cs
- LogicalExpr.cs
- DataFieldConverter.cs
- MinimizableAttributeTypeConverter.cs
- OrderedDictionary.cs
- EdgeProfileValidation.cs
- LicFileLicenseProvider.cs
- TableCellsCollectionEditor.cs
- ApplicationFileCodeDomTreeGenerator.cs
- BitmapImage.cs
- DataColumnMapping.cs
- ImageMapEventArgs.cs
- SecurityUtils.cs
- FocusTracker.cs
- SpoolingTask.cs
- InvalidCastException.cs
- AuthorizationSection.cs
- BindingEntityInfo.cs
- XamlFigureLengthSerializer.cs
- ConfigurationPropertyCollection.cs
- ObjectFactoryCodeDomTreeGenerator.cs
- WebPartDeleteVerb.cs
- PrimitiveType.cs
- ComplexType.cs
- WebPartUserCapability.cs
- ClaimComparer.cs
- LogLogRecord.cs
- DocumentSchemaValidator.cs
- TextRange.cs
- MatrixTransform.cs
- Rect.cs
- DataGridViewUtilities.cs
- WebSysDisplayNameAttribute.cs
- IndexerNameAttribute.cs
- NotifyCollectionChangedEventArgs.cs
- ExpressionBuilder.cs
- AuthenticatedStream.cs
- BindingSource.cs
- OdbcDataReader.cs
- IISMapPath.cs
- IERequestCache.cs
- documentsequencetextpointer.cs
- ReadWriteObjectLock.cs
- EmptyEnumerable.cs
- SpellerInterop.cs
- ImportOptions.cs
- MouseActionConverter.cs
- EpmContentDeSerializerBase.cs
- CustomAttribute.cs
- EntityViewGenerator.cs