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
- AspNetSynchronizationContext.cs
- DataGridViewMethods.cs
- NodeInfo.cs
- SourceLocation.cs
- FormsAuthenticationUserCollection.cs
- PopOutPanel.cs
- OrderingQueryOperator.cs
- OleDbConnectionPoolGroupProviderInfo.cs
- QuotaExceededException.cs
- SlotInfo.cs
- UInt32Storage.cs
- AdornerHitTestResult.cs
- Converter.cs
- OleTxTransaction.cs
- TextBounds.cs
- DataTrigger.cs
- OrderedDictionary.cs
- SymbolTable.cs
- ContourSegment.cs
- FormatterServices.cs
- XmlSerializer.cs
- FontDifferentiator.cs
- DocumentReference.cs
- GridViewCancelEditEventArgs.cs
- Sql8ExpressionRewriter.cs
- StringWriter.cs
- InputEventArgs.cs
- DbDeleteCommandTree.cs
- StatusBar.cs
- BatchWriter.cs
- SerializationException.cs
- FatalException.cs
- WebPartConnectionsEventArgs.cs
- SByteConverter.cs
- WebPartDeleteVerb.cs
- DataGridRowClipboardEventArgs.cs
- RoleManagerEventArgs.cs
- XsdBuilder.cs
- DataControlFieldCollection.cs
- CqlWriter.cs
- PseudoWebRequest.cs
- HashSetDebugView.cs
- MergeLocalizationDirectives.cs
- GlyphRunDrawing.cs
- UnionCodeGroup.cs
- StringConcat.cs
- VerifyHashRequest.cs
- Tuple.cs
- MessageLoggingElement.cs
- KeyedHashAlgorithm.cs
- FileDetails.cs
- ServiceCredentialsElement.cs
- MapPathBasedVirtualPathProvider.cs
- ServiceObjectContainer.cs
- SecurityTokenValidationException.cs
- UnsafeNativeMethods.cs
- InputLanguageCollection.cs
- MsdtcWrapper.cs
- WindowsIdentity.cs
- BamlBinaryWriter.cs
- UserInitiatedNavigationPermission.cs
- CompilerTypeWithParams.cs
- UserControlDocumentDesigner.cs
- RegistryKey.cs
- TraceSection.cs
- TcpProcessProtocolHandler.cs
- DbProviderFactories.cs
- XmlQueryContext.cs
- BigInt.cs
- FixedTextSelectionProcessor.cs
- PrivateFontCollection.cs
- GenerateHelper.cs
- DefaultIfEmptyQueryOperator.cs
- ListViewEditEventArgs.cs
- MemoryPressure.cs
- Visual3D.cs
- ContentPlaceHolder.cs
- DoubleAverageAggregationOperator.cs
- DbConnectionHelper.cs
- RtfFormatStack.cs
- TreeChangeInfo.cs
- NonDualMessageSecurityOverHttp.cs
- CodeDelegateInvokeExpression.cs
- XmlSerializerVersionAttribute.cs
- AdapterDictionary.cs
- DragStartedEventArgs.cs
- ProcessThreadCollection.cs
- GenericPrincipal.cs
- CodeAttributeDeclarationCollection.cs
- ConfigPathUtility.cs
- Zone.cs
- SqlMethodCallConverter.cs
- PageThemeParser.cs
- Size3DValueSerializer.cs
- SoapIgnoreAttribute.cs
- DrawingVisual.cs
- TableFieldsEditor.cs
- SQLDouble.cs
- ParameterBuilder.cs
- MSG.cs