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
- UnsafeNativeMethodsMilCoreApi.cs
- Environment.cs
- IncrementalHitTester.cs
- CustomTypeDescriptor.cs
- Enumerable.cs
- mediapermission.cs
- DataContractSerializerMessageContractImporter.cs
- KnownIds.cs
- UserValidatedEventArgs.cs
- CLSCompliantAttribute.cs
- SoapAttributeOverrides.cs
- GridViewUpdateEventArgs.cs
- AbandonedMutexException.cs
- DeviceContext.cs
- ListBindingConverter.cs
- UidManager.cs
- HttpSysSettings.cs
- DecoderBestFitFallback.cs
- HierarchicalDataSourceDesigner.cs
- VectorKeyFrameCollection.cs
- WebBrowserProgressChangedEventHandler.cs
- OrderedHashRepartitionEnumerator.cs
- _Win32.cs
- Substitution.cs
- ToolStripSeparatorRenderEventArgs.cs
- XmlWhitespace.cs
- PopOutPanel.cs
- CodeTypeDeclarationCollection.cs
- OdbcDataAdapter.cs
- BlurBitmapEffect.cs
- ActivityContext.cs
- DirectionalLight.cs
- WebBrowserPermission.cs
- AnnotationHelper.cs
- ToolStripPanelRenderEventArgs.cs
- RepeaterCommandEventArgs.cs
- TextModifierScope.cs
- DurableMessageDispatchInspector.cs
- PerformanceCounter.cs
- JapaneseLunisolarCalendar.cs
- LinearQuaternionKeyFrame.cs
- DataContract.cs
- FileClassifier.cs
- FileDialogCustomPlace.cs
- MediaElementAutomationPeer.cs
- SelectedDatesCollection.cs
- XPathCompiler.cs
- MessageSecurityTokenVersion.cs
- RuleSet.cs
- NonParentingControl.cs
- BamlTreeUpdater.cs
- followingquery.cs
- ScrollViewer.cs
- Accessors.cs
- SR.Designer.cs
- CrossSiteScriptingValidation.cs
- LinqDataSourceStatusEventArgs.cs
- CRYPTPROTECT_PROMPTSTRUCT.cs
- InternalMappingException.cs
- WizardStepBase.cs
- HtmlElement.cs
- ServiceObjectContainer.cs
- DataStreamFromComStream.cs
- FileVersionInfo.cs
- TrackBarRenderer.cs
- SignedXmlDebugLog.cs
- ToolStripProgressBar.cs
- IntegerValidatorAttribute.cs
- HttpHandlersSection.cs
- Convert.cs
- SqlRemoveConstantOrderBy.cs
- PointCollectionConverter.cs
- RoleManagerSection.cs
- OperationContractAttribute.cs
- WebSysDefaultValueAttribute.cs
- sqlpipe.cs
- StaticExtension.cs
- RuleEngine.cs
- relpropertyhelper.cs
- QuaternionAnimationBase.cs
- ControlPersister.cs
- TrustManagerMoreInformation.cs
- AccessViolationException.cs
- PriorityQueue.cs
- ConditionalExpression.cs
- PreviewKeyDownEventArgs.cs
- DependencyProperty.cs
- _SingleItemRequestCache.cs
- DataGridViewComboBoxColumn.cs
- AnonymousIdentificationSection.cs
- XmlNodeReader.cs
- Keyboard.cs
- SmtpFailedRecipientsException.cs
- ListItemConverter.cs
- UnionCqlBlock.cs
- LogPolicy.cs
- TTSEngineProxy.cs
- ClientSideProviderDescription.cs
- EdmScalarPropertyAttribute.cs
- DeflateStreamAsyncResult.cs