Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / AddIn / AddIn / System / Addin / Hosting / Utils.cs / 1305376 / Utils.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== /*============================================================ ** ** Class: Utils ** ** Purpose: Random functionality that is useful for the ** Add-In model ** ===========================================================*/ using System; using System.Collections.Generic; using System.Collections; using System.Collections.ObjectModel; using System.IO; using System.Reflection; using System.Security; using System.Security.Permissions; using System.Security.Policy; using System.Text; using System.Diagnostics; using System.AddIn.MiniReflection; using System.Diagnostics.Contracts; namespace System.AddIn.Hosting { [Serializable] internal static class Utils { // This method requires that the types passed in are from the same CLR // loader context. The V2 loader defines 4 loader contexts, and only 2 of // them will exist in the CLR V3. A type from an assembly loaded in one // loader context is not assignable to the same type in a different loader // context. This applies for normal assignment, but also shows up in // Reflection, as getting different System.Type instances. This method // wants to be relatively fast, so instead of doing string comparisons on // type names, we leverage Reflection's guarantees about singleton Type // instances for assemblies loaded in the same loader context. That's why // the loop below can do a reference equality test. internal static bool HasCustomAttribute(Type attributeType, Type inspectType) { return GetCustomAttributeData(attributeType, inspectType) != null; } internal static CustomAttributeData GetCustomAttributeData(Type attributeType, Type inspectType) { // Spec#: Should this be a DebugRequires or RequiresExpensive? System.Diagnostics.Contracts.Contract.Requires(typeof(Attribute).IsAssignableFrom(attributeType)); // The following precondition isn't strictly sufficient for the V2 CLR // because we define 4 loader contexts and expose only one boolean // predicate for testing which loader context an assembly is loaded in. // But it is still very useful - our types must be in the same loader context. // // Removed because sometimes we look for attributes on a type's Base type which may be Object // System.Diagnostics.Contracts.Contract.Requires(attributeType.Assembly.ReflectionOnly == inspectType.Assembly.ReflectionOnly); foreach (CustomAttributeData ca in CustomAttributeData.GetCustomAttributes(inspectType)) { if (Object.ReferenceEquals(ca.Constructor.DeclaringType, attributeType)) return ca; } return null; } /* internal static bool PublicKeyTokensEqual(String token1, byte[] token2) { if (token2 == null || token2.Length == 0) return token1 == "null"; if (token1 == "null") return false; Contract.Assert(token1.Length == 2 * token2.Length, "Lengths didn't match"); for (int i = 0; i < token2.Length; i++) { int firstPart = (token1[2 * i] <= '9') ? token1[2 * i] - '0' : token1[2 * i] - 'a' + 10; int secondPart = (token1[2 * i + 1] <= '9') ? token1[2 * i + 1] - '0' : token1[2 * i + 1] - 'a' + 10; byte b1 = (byte)((firstPart << 4) + secondPart); if (b1 != token2[i]) return false; } return true; } */ /* internal static bool PublicKeyTokensEqual(byte[] token1, byte[] token2) { if (token2 == null || token2.Length == 0) return token1 == null || token1.Length == 0; if (token1 == null) return false; System.Diagnostics.Contracts.Contract.Assert(token1.Length == token2.Length, "Lengths didn't match"); for (int i = 0; i < token1.Length; i++) if (token1[i] != token2[i]) return false; return true; } */ internal static bool PublicKeyMatches(AssemblyName a1, AssemblyName a2) { byte[] key = a2.GetPublicKey(); return PublicKeyMatches(a1, key); } internal static bool PublicKeyMatches(System.Reflection.AssemblyName a1, byte[] publicKeyOrToken) { if (publicKeyOrToken == null) return a1.GetPublicKey() == null; byte[] publicKey = a1.GetPublicKey(); if (publicKey != null && publicKeyOrToken.Length == publicKey.Length) { for (int i = 0; i < publicKey.Length; i++) if (publicKey[i] != publicKeyOrToken[i]) return false; return true; } byte[] publicKeyToken = a1.GetPublicKeyToken(); if (publicKeyOrToken.Length == publicKeyToken.Length) { for (int i = 0; i < publicKeyToken.Length; i++) if (publicKeyToken[i] != publicKeyOrToken[i]) return false; return true; } return false; } internal static String PublicKeyToString(byte[] key) { if (key == null || key.Length == 0) return "null"; StringBuilder sb = new StringBuilder(key.Length); foreach (byte b in key) { sb.Append(b.ToString("x2", System.Globalization.CultureInfo.InvariantCulture)); } return sb.ToString(); } // You must have already normalized the paths! internal static String MakeRelativePath(String path, String root) { System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(path)); System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(root)); if (!path.StartsWith(root, StringComparison.OrdinalIgnoreCase)) throw new ArgumentException(Res.MakeRelativePathArgs); System.Diagnostics.Contracts.Contract.Requires(String.Equals(path, Path.GetFullPath(path))); System.Diagnostics.Contracts.Contract.Requires(String.Equals(root, Path.GetFullPath(root))); System.Diagnostics.Contracts.Contract.Ensures(!Path.IsPathRooted(System.Diagnostics.Contracts.Contract.Result())); System.Diagnostics.Contracts.Contract.EndContractBlock(); int skip = 0; char lastChar = root[root.Length - 1]; if (lastChar != Path.DirectorySeparatorChar && lastChar != Path.AltDirectorySeparatorChar) skip++; String relPath = path.Substring(root.Length + skip); return relPath; } // Pass in fully qualified names. We've factored out our assembly names // comparisons so that we can handle policy if necessary, and also deal with // potentially mal-formed assembly refs, or assembly refs that include // processor architecture, etc. (I haven't implemented that, but it could be done.) internal static bool AssemblyRefEqualsDef(String assemblyRef, String assemblyDef) { System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(assemblyRef)); System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(assemblyDef)); return String.Equals(assemblyRef, assemblyDef); } // Pass in fully qualified names. We've factored out our assembly names // comparisons so that we can handle policy if necessary. internal static bool AssemblyDefEqualsDef(String assemblyDef1, String assemblyDef2) { System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(assemblyDef1)); System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(assemblyDef2)); return String.Equals(assemblyDef1, assemblyDef2); } // Pass in fully qualified type names. We've factored out our assembly names // comparisons so that we can handle policy if necessary. internal static bool FullTypeNameDefEqualsDef(String typeAndAssemblyName1, String typeAndAssemblyName2) { System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(typeAndAssemblyName1)); System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(typeAndAssemblyName2)); return String.Equals(typeAndAssemblyName1, typeAndAssemblyName2); } // If you're calling this method, you suspect that you've already loaded this // assembly, but you need to upgrade the assembly from the LoadFrom loader // context to the default loader context. However, we'll have to call it // for an unbound set of assemblies. internal static Assembly FindLoadedAssemblyRef(String assemblyRef) { System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(assemblyRef)); foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies()) { if (Utils.AssemblyRefEqualsDef(assemblyRef, a.FullName)) { //Console.WriteLine("FindLoadedAssemblyRef found its target (probably in the LoadFrom context). Returning, in hopes of upgrading to default loader context. Code base: {0}", a.CodeBase); return a; } } return null; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Reflection.Assembly.LoadFrom", Justification="LoadFrom was designed for addins")] internal static Assembly LoadAssemblyFrom(List dirsToLookIn, String assemblyRef) { int firstComma = assemblyRef.IndexOf(','); if (firstComma == -1) return null; String simpleName = assemblyRef.Substring(0, firstComma); List potentialFileNames = new List (dirsToLookIn.Count * 2); foreach (String path in dirsToLookIn) { String simpleFileName = Path.Combine(path, simpleName); String dllName = simpleFileName + ".dll"; if (File.Exists(dllName)) potentialFileNames.Add(dllName); else if (File.Exists(simpleFileName + ".exe")) potentialFileNames.Add(simpleFileName + ".exe"); } foreach (String fileName in potentialFileNames) { try { Assembly assembly = Assembly.LoadFrom(fileName); // We should at least be comparing the public key token // for the two assemblies here. The version numbers may // potentially be different, dependent on publisher policy. if (Utils.AssemblyRefEqualsDef(assemblyRef, assembly.FullName)) { return assembly; } } catch (BadImageFormatException) { } } return null; } // If they have full trust, give a good error message. Otherwise, prevent information disclosure. internal static bool HasFullTrust() { try { new PermissionSet(PermissionState.Unrestricted).Demand(); return true; } catch(SecurityException) { return false; } } //Utility method to assert permission and unload the appdomain [System.Security.SecurityCritical] [SecurityPermission(SecurityAction.Assert, ControlAppDomain = true)] internal static void UnloadAppDomain(AppDomain domain) { AppDomain.Unload(domain); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- TempEnvironment.cs
- WSSecurityPolicy.cs
- MsmqIntegrationMessagePool.cs
- SafePEFileHandle.cs
- IssuedTokenServiceElement.cs
- MetafileHeaderEmf.cs
- _Rfc2616CacheValidators.cs
- CollectionViewSource.cs
- DispatcherFrame.cs
- Selection.cs
- SpeechEvent.cs
- AssemblySettingAttributes.cs
- ListDictionary.cs
- VerticalAlignConverter.cs
- IItemProperties.cs
- ImageAnimator.cs
- ExtractedStateEntry.cs
- AnnotationResourceCollection.cs
- SudsWriter.cs
- ReadonlyMessageFilter.cs
- ReliableMessagingVersionConverter.cs
- TreeNodeCollection.cs
- DbParameterCollectionHelper.cs
- ParameterBuilder.cs
- DictionaryManager.cs
- AddToCollection.cs
- CodeTypeConstructor.cs
- ScrollData.cs
- ValidationHelper.cs
- sitestring.cs
- ListBase.cs
- XmlSecureResolver.cs
- PeerNameResolver.cs
- ResourceType.cs
- EmbeddedMailObjectsCollection.cs
- HtmlTableCell.cs
- XPathNodePointer.cs
- TextServicesPropertyRanges.cs
- TableHeaderCell.cs
- ConfigurationStrings.cs
- DateTimeConstantAttribute.cs
- MailBnfHelper.cs
- Deserializer.cs
- odbcmetadatacollectionnames.cs
- OdbcConnectionStringbuilder.cs
- ObjectSelectorEditor.cs
- OleDbException.cs
- InputReferenceExpression.cs
- MatrixTransform.cs
- EventHandlerList.cs
- externdll.cs
- DrawingContextWalker.cs
- RtfToXamlLexer.cs
- BasicExpandProvider.cs
- InstanceKeyCompleteException.cs
- ResXBuildProvider.cs
- RemotingServices.cs
- DataViewListener.cs
- PieceNameHelper.cs
- ValueQuery.cs
- DocumentationServerProtocol.cs
- EncryptedKey.cs
- VectorAnimationBase.cs
- SqlTriggerContext.cs
- XsdBuilder.cs
- Version.cs
- MaskInputRejectedEventArgs.cs
- SqlNamer.cs
- UnsafeNativeMethods.cs
- DesignTable.cs
- DrawingCollection.cs
- input.cs
- UrlMappingsSection.cs
- SafeBitVector32.cs
- webbrowsersite.cs
- DataGridViewCell.cs
- TdsParserHelperClasses.cs
- webbrowsersite.cs
- PolyLineSegment.cs
- RecognizedAudio.cs
- SymmetricAlgorithm.cs
- Section.cs
- ExcCanonicalXml.cs
- TextEditorContextMenu.cs
- KeyboardNavigation.cs
- InheritanceAttribute.cs
- TableLayoutCellPaintEventArgs.cs
- DragAssistanceManager.cs
- XmlElementCollection.cs
- CompiledXpathExpr.cs
- SqlRewriteScalarSubqueries.cs
- DesignTimeResourceProviderFactoryAttribute.cs
- ActivationService.cs
- TrackingServices.cs
- StreamSecurityUpgradeAcceptorAsyncResult.cs
- EmptyQuery.cs
- InvalidPrinterException.cs
- AccessViolationException.cs
- ActivitiesCollection.cs
- Atom10FormatterFactory.cs