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
- PropertyEntry.cs
- EventSource.cs
- PropertyIDSet.cs
- InvalidOperationException.cs
- StateItem.cs
- CheckBoxBaseAdapter.cs
- IdentityReference.cs
- PeerTransportListenAddressConverter.cs
- OracleDataReader.cs
- MSHTMLHost.cs
- PrinterSettings.cs
- ControllableStoryboardAction.cs
- EventsTab.cs
- StateMachineWorkflow.cs
- HashSet.cs
- CqlBlock.cs
- RequiredAttributeAttribute.cs
- FrameDimension.cs
- FtpCachePolicyElement.cs
- FieldToken.cs
- DataGridBoolColumn.cs
- DependencyPropertyKind.cs
- QueryContinueDragEventArgs.cs
- ConditionBrowserDialog.cs
- CustomAttributeBuilder.cs
- SafeArrayRankMismatchException.cs
- ScheduleChanges.cs
- ListViewSortEventArgs.cs
- XmlReflectionImporter.cs
- BlurBitmapEffect.cs
- AmbientLight.cs
- ManagementOptions.cs
- FaultPropagationRecord.cs
- QilReference.cs
- DataGridViewRowPrePaintEventArgs.cs
- AttachedPropertyBrowsableForTypeAttribute.cs
- XmlAttributeOverrides.cs
- CapabilitiesRule.cs
- CodeSubDirectoriesCollection.cs
- ToolStripDropDownItem.cs
- DataGridViewTextBoxCell.cs
- ZipIOCentralDirectoryDigitalSignature.cs
- GrammarBuilderWildcard.cs
- StylusLogic.cs
- WmfPlaceableFileHeader.cs
- ParameterToken.cs
- StrokeFIndices.cs
- Stroke.cs
- ValidatingPropertiesEventArgs.cs
- SqlInternalConnectionTds.cs
- BaseParser.cs
- InstanceCreationEditor.cs
- CodeThrowExceptionStatement.cs
- GeneralTransform.cs
- ElapsedEventArgs.cs
- ForeignConstraint.cs
- HttpContext.cs
- RenderingEventArgs.cs
- UpdateCommand.cs
- ManifestBasedResourceGroveler.cs
- LocatorPartList.cs
- TimeSpanStorage.cs
- ClientConfigurationHost.cs
- Transform3DGroup.cs
- CodeDOMUtility.cs
- NonBatchDirectoryCompiler.cs
- _CookieModule.cs
- HttpValueCollection.cs
- DataGridToolTip.cs
- ComboBox.cs
- SqlTriggerAttribute.cs
- DesignerLoader.cs
- CodeTypeDeclarationCollection.cs
- CharacterShapingProperties.cs
- sqlser.cs
- BridgeDataReader.cs
- ZipFileInfoCollection.cs
- TreeView.cs
- XmlSchemaSubstitutionGroup.cs
- OletxCommittableTransaction.cs
- DefaultHttpHandler.cs
- UTF8Encoding.cs
- MenuItemBindingCollection.cs
- PolyQuadraticBezierSegment.cs
- ClipboardData.cs
- StylusPointDescription.cs
- BindingCollection.cs
- glyphs.cs
- CommonXSendMessage.cs
- TextServicesDisplayAttributePropertyRanges.cs
- ProjectedSlot.cs
- TdsParserStaticMethods.cs
- NativeMethods.cs
- RowsCopiedEventArgs.cs
- ChannelServices.cs
- LongCountAggregationOperator.cs
- FilterException.cs
- UdpContractFilterBehavior.cs
- RenderDataDrawingContext.cs
- mansign.cs