X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2Fcorlib%2FSystem.Reflection%2FAssemblyName.cs;h=8e96227d2d292eda1c4e7a36b07fac64f2699cf3;hb=83dccf8fe7cf27e92061daec886e235ce6c7c57b;hp=42b32953736273ff92d03d6e24f8f374b9bbfd24;hpb=53497da09c4928635f4d4c4776c8c7e48c6098c3;p=mono.git diff --git a/mcs/class/corlib/System.Reflection/AssemblyName.cs b/mcs/class/corlib/System.Reflection/AssemblyName.cs index 42b32953736..8e96227d2d2 100644 --- a/mcs/class/corlib/System.Reflection/AssemblyName.cs +++ b/mcs/class/corlib/System.Reflection/AssemblyName.cs @@ -7,7 +7,7 @@ // // (C) 2001 Ximian, Inc. http://www.ximian.com // Portions (C) 2002 Motus Technologies Inc. (http://www.motus.com) -// Copyright (C) 2004 Novell, Inc (http://www.novell.com) +// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com) // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -29,15 +29,19 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -using System; using System.Configuration.Assemblies; using System.Globalization; -using System.Reflection; using System.Runtime.Serialization; +using System.Security; using System.Security.Cryptography; +using System.Security.Permissions; using System.Text; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; +using System.IO; + +using Mono.Security; +using Mono.Security.Cryptography; namespace System.Reflection { @@ -45,9 +49,15 @@ namespace System.Reflection { // a. Uniform Resource Identifiers (URI): Generic Syntax // http://www.ietf.org/rfc/rfc2396.txt + [ComVisible (true)] + [ComDefaultInterfaceAttribute (typeof (_AssemblyName))] [Serializable] - [MonoTODO ("Fix serialization compatibility with MS.NET")] - public sealed class AssemblyName : ICloneable, ISerializable, IDeserializationCallback { + [ClassInterfaceAttribute (ClassInterfaceType.None)] + [StructLayout (LayoutKind.Sequential)] + public sealed class AssemblyName : ICloneable, ISerializable, IDeserializationCallback, _AssemblyName { + +#pragma warning disable 169 + #region Synch with object-internals.h string name; string codebase; int major, minor, build, revision; @@ -59,6 +69,9 @@ namespace System.Reflection { byte[] keyToken; AssemblyVersionCompatibility versioncompat; Version version; + ProcessorArchitecture processor_architecture = ProcessorArchitecture.None; + #endregion +#pragma warning restore 169 public AssemblyName () { @@ -66,12 +79,29 @@ namespace System.Reflection { versioncompat = AssemblyVersionCompatibility.SameMachine; } -#if NET_2_0 + [MethodImpl (MethodImplOptions.InternalCall)] + static extern bool ParseName (AssemblyName aname, string assemblyName); + public AssemblyName (string assemblyName) { - name = assemblyName; + if (assemblyName == null) + throw new ArgumentNullException ("assemblyName"); + if (assemblyName.Length < 1) + throw new ArgumentException ("assemblyName cannot have zero length."); + + if (!ParseName (this, assemblyName)) + throw new FileLoadException ("The assembly name is invalid."); + } + + [MonoLimitation ("Not used, as the values are too limited; Mono supports more")] + public ProcessorArchitecture ProcessorArchitecture { + get { + return processor_architecture; + } + set { + processor_architecture = value; + } } -#endif internal AssemblyName (SerializationInfo si, StreamingContext sc) { @@ -79,7 +109,7 @@ namespace System.Reflection { codebase = si.GetString ("_CodeBase"); version = (Version)si.GetValue ("_Version", typeof (Version)); publicKey = (byte[])si.GetValue ("_PublicKey", typeof (byte[])); - keyToken = (byte[])si.GetValue ("_PublicToken", typeof (byte[])); + keyToken = (byte[])si.GetValue ("_PublicKeyToken", typeof (byte[])); hashalg = (AssemblyHashAlgorithm)si.GetValue ("_HashAlgorithm", typeof (AssemblyHashAlgorithm)); keypair = (StrongNameKeyPair)si.GetValue ("_StrongNameKeyPair", typeof (StrongNameKeyPair)); versioncompat = (AssemblyVersionCompatibility)si.GetValue ("_VersionCompatibility", typeof (AssemblyVersionCompatibility)); @@ -98,17 +128,12 @@ namespace System.Reflection { set { codebase = value; } } - [MonoTODO("RFC 2396")] - private string Escape (string url) - { - // we already have code in mcs\class\System\System\Uri.cs - // but Uri class ins't part of corlib ! - // TODO - return url; - } - public string EscapedCodeBase { - get { return Escape (codebase); } + get { + if (codebase == null) + return null; + return Uri.EscapeString (codebase, false, true, true); + } } public CultureInfo CultureInfo { @@ -124,10 +149,13 @@ namespace System.Reflection { public string FullName { get { if (name == null) - return null; + return string.Empty; StringBuilder fname = new StringBuilder (); - fname.Append (name); - if (Version.ToString () != "0.0.0.0") { + if (Char.IsWhiteSpace (name [0])) + fname.Append ("\"" + name + "\""); + else + fname.Append (name); + if (Version != null) { fname.Append (", Version="); fname.Append (Version.ToString ()); } @@ -138,7 +166,7 @@ namespace System.Reflection { else fname.Append (cultureinfo.Name); } - byte[] pub_tok = GetPublicKeyToken (); + byte [] pub_tok = InternalGetPublicKeyToken (); if (pub_tok != null) { if (pub_tok.Length == 0) fname.Append (", PublicKeyToken=null"); @@ -148,6 +176,10 @@ namespace System.Reflection { fname.Append (pub_tok[i].ToString ("x2")); } } + + if ((Flags & AssemblyNameFlags.Retargetable) != 0) + fname.Append (", Retargetable=Yes"); + return fname.ToString (); } } @@ -164,27 +196,19 @@ namespace System.Reflection { public Version Version { get { - if (version != null) return version; - - if (name == null) - return null; - if (build == -1) - version = new Version (major, minor); - else - if (revision == -1) - version = new Version (major, minor, build); - else - version = new Version (major, minor, build, revision); - return version; } set { - major = value.Major; - minor = value.Minor; - build = value.Build; - revision = value.Revision; version = value; + if (value == null) + major = minor = build = revision = 0; + else { + major = value.Major; + minor = value.Minor; + build = value.Build; + revision = value.Revision; + } } } @@ -199,46 +223,113 @@ namespace System.Reflection { return (name != null) ? name : base.ToString (); } - public byte[] GetPublicKey() + public byte[] GetPublicKey() { - // to match MS implementation -- funny one - if (publicKey != null) - return publicKey; - else if (name == null) - return null; - else - return new byte [0]; + return publicKey; } - public byte[] GetPublicKeyToken() + public byte[] GetPublicKeyToken () { if (keyToken != null) return keyToken; else if (publicKey == null) return null; else { - HashAlgorithm ha = null; - switch (hashalg) { - case AssemblyHashAlgorithm.MD5: - ha = MD5.Create (); - break; - default: - // None default to SHA1 - ha = SHA1.Create (); - break; - } - byte[] hash = ha.ComputeHash (publicKey); - // we need the last 8 bytes in reverse order - keyToken = new byte [8]; - Array.Copy (hash, (hash.Length - 8), keyToken, 0, 8); - Array.Reverse (keyToken, 0, 8); + if (publicKey.Length == 0) + return new byte [0]; + + if (!IsPublicKeyValid) + throw new SecurityException ("The public key is not valid."); + + keyToken = ComputePublicKeyToken (); return keyToken; } } + private bool IsPublicKeyValid { + get { + // check for ECMA key + if (publicKey.Length == 16) { + int i = 0; + int sum = 0; + while (i < publicKey.Length) + sum += publicKey [i++]; + if (sum == 4) + return true; + } + + switch (publicKey [0]) { + case 0x00: // public key inside a header + if (publicKey.Length > 12 && publicKey [12] == 0x06) { + try { + CryptoConvert.FromCapiPublicKeyBlob ( + publicKey, 12); + return true; + } catch (CryptographicException) { + } + } + break; + case 0x06: // public key + try { + CryptoConvert.FromCapiPublicKeyBlob (publicKey); + return true; + } catch (CryptographicException) { + } + break; + case 0x07: // private key + break; + } + + return false; + } + } + + private byte [] InternalGetPublicKeyToken () + { + if (keyToken != null) + return keyToken; + + if (publicKey == null) + return null; + + if (publicKey.Length == 0) + return new byte [0]; + + if (!IsPublicKeyValid) + throw new SecurityException ("The public key is not valid."); + + return ComputePublicKeyToken (); + } + + private byte [] ComputePublicKeyToken () + { + HashAlgorithm ha = SHA1.Create (); + byte [] hash = ha.ComputeHash (publicKey); + // we need the last 8 bytes in reverse order + byte [] token = new byte [8]; + Array.Copy (hash, (hash.Length - 8), token, 0, 8); + Array.Reverse (token, 0, 8); + return token; + } + + [MonoTODO] + public static bool ReferenceMatchesDefinition (AssemblyName reference, AssemblyName definition) + { + if (reference == null) + throw new ArgumentNullException ("reference"); + if (definition == null) + throw new ArgumentNullException ("definition"); + if (reference.Name != definition.Name) + return false; + throw new NotImplementedException (); + } + public void SetPublicKey (byte[] publicKey) { - flags = AssemblyNameFlags.PublicKey; + if (publicKey == null) + flags ^= AssemblyNameFlags.PublicKey; + else + flags |= AssemblyNameFlags.PublicKey; this.publicKey = publicKey; } @@ -247,11 +338,15 @@ namespace System.Reflection { keyToken = publicKeyToken; } + [SecurityPermission (SecurityAction.Demand, SerializationFormatter = true)] public void GetObjectData (SerializationInfo info, StreamingContext context) { + if (info == null) + throw new ArgumentNullException ("info"); + info.AddValue ("_Name", name); info.AddValue ("_PublicKey", publicKey); - info.AddValue ("_PublicToken", keyToken); + info.AddValue ("_PublicKeyToken", keyToken); info.AddValue ("_CultureInfo", cultureinfo != null ? cultureinfo.LCID : -1); info.AddValue ("_CodeBase", codebase); info.AddValue ("_Version", Version); @@ -272,6 +367,7 @@ namespace System.Reflection { an.minor = minor; an.build = build; an.revision = revision; + an.version = version; an.cultureinfo = cultureinfo; an.flags = flags; an.hashalg = hashalg; @@ -293,8 +389,29 @@ namespace System.Reflection { throw new ArgumentNullException ("assemblyFile"); AssemblyName aname = new AssemblyName (); - Assembly.InternalGetAssemblyName (System.IO.Path.GetFullPath (assemblyFile), aname); + Assembly.InternalGetAssemblyName (Path.GetFullPath (assemblyFile), aname); return aname; } + + void _AssemblyName.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) + { + throw new NotImplementedException (); + } + + void _AssemblyName.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo) + { + throw new NotImplementedException (); + } + + void _AssemblyName.GetTypeInfoCount (out uint pcTInfo) + { + throw new NotImplementedException (); + } + + void _AssemblyName.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, + IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) + { + throw new NotImplementedException (); + } } }