3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 /*============================================================
10 ** <OWNER>Microsoft</OWNER>
11 ** <OWNER>Microsoft</OWNER>
14 ** Purpose: Used for binding and retrieving info about an assembly
17 ===========================================================*/
18 namespace System.Reflection {
21 using System.Configuration.Assemblies;
22 using System.Runtime.CompilerServices;
23 using CultureInfo = System.Globalization.CultureInfo;
24 using System.Runtime.Serialization;
25 using System.Security.Permissions;
26 using System.Runtime.InteropServices;
27 using System.Runtime.Versioning;
28 using System.Diagnostics.Contracts;
31 [ClassInterface(ClassInterfaceType.None)]
32 [ComDefaultInterface(typeof(_AssemblyName))]
33 [System.Runtime.InteropServices.ComVisible(true)]
34 public sealed class AssemblyName : _AssemblyName, ICloneable, ISerializable, IDeserializationCallback
38 // If you modify any of these fields, you must also update the
39 // AssemblyBaseObject structure in object.h
41 private String _Name; // Name
42 private byte[] _PublicKey;
43 private byte[] _PublicKeyToken;
44 private CultureInfo _CultureInfo;
45 private String _CodeBase; // Potential location to get the file
46 private Version _Version;
48 private StrongNameKeyPair _StrongNameKeyPair;
50 #if FEATURE_SERIALIZATION
51 private SerializationInfo m_siInfo; //A temporary variable which we need during deserialization.
54 private byte[] _HashForControl;
55 private AssemblyHashAlgorithm _HashAlgorithm;
56 private AssemblyHashAlgorithm _HashAlgorithmForControl;
58 private AssemblyVersionCompatibility _VersionCompatibility;
59 private AssemblyNameFlags _Flags;
63 _HashAlgorithm = AssemblyHashAlgorithm.None;
64 _VersionCompatibility = AssemblyVersionCompatibility.SameMachine;
65 _Flags = AssemblyNameFlags.None;
68 // Set and get the name of the assembly. If this is a weak Name
69 // then it optionally contains a site. For strong assembly names,
70 // the name partitions up the strong name's namespace
74 set { _Name = value; }
77 public Version Version
87 // Locales, internally the LCID is used for the match.
88 public CultureInfo CultureInfo
98 public String CultureName
101 return (_CultureInfo == null) ? null : _CultureInfo.Name;
104 _CultureInfo = (value == null) ? null : new CultureInfo(value);
108 public String CodeBase
111 [System.Security.SecurityCritical] // auto-generated
113 [ResourceExposure(ResourceScope.Machine)]
114 get { return _CodeBase; }
116 [System.Security.SecurityCritical] // auto-generated
118 [ResourceExposure(ResourceScope.Machine)]
119 set { _CodeBase = value; }
122 public String EscapedCodeBase
124 [System.Security.SecuritySafeCritical] // auto-generated
125 [ResourceExposure(ResourceScope.Machine)]
126 [ResourceConsumption(ResourceScope.Machine)]
129 if (_CodeBase == null)
132 return EscapeCodeBase(_CodeBase);
136 public ProcessorArchitecture ProcessorArchitecture
139 int x = (((int)_Flags) & 0x70) >> 4;
142 return (ProcessorArchitecture)x;
145 int x = ((int)value) & 0x07;
147 _Flags = (AssemblyNameFlags)((int)_Flags & 0xFFFFFF0F);
148 _Flags |= (AssemblyNameFlags)(x << 4);
153 [System.Runtime.InteropServices.ComVisible(false)]
154 public AssemblyContentType ContentType
158 int x = (((int)_Flags) & 0x00000E00) >> 9;
161 return (AssemblyContentType)x;
165 int x = ((int)value) & 0x07;
168 _Flags = (AssemblyNameFlags)((int)_Flags & 0xFFFFF1FF);
169 _Flags |= (AssemblyNameFlags)(x << 9);
176 // Make a copy of this assembly name.
177 public Object Clone()
179 AssemblyName name = new AssemblyName();
186 _VersionCompatibility,
190 name._HashForControl=_HashForControl;
191 name._HashAlgorithmForControl=_HashAlgorithmForControl;
196 * Get the AssemblyName for a given file. This will only work
197 * if the file contains an assembly manifest. This method causes
198 * the file to be opened and closed.
200 [System.Security.SecuritySafeCritical] // auto-generated
201 [ResourceExposure(ResourceScope.None)]
202 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
203 static public AssemblyName GetAssemblyName(String assemblyFile)
205 if(assemblyFile == null)
206 throw new ArgumentNullException("assemblyFile");
207 Contract.EndContractBlock();
209 // Assembly.GetNameInternal() will not demand path discovery
210 // permission, so do that first.
211 String fullPath = Path.GetFullPathInternal(assemblyFile);
212 new FileIOPermission( FileIOPermissionAccess.PathDiscovery, fullPath ).Demand();
213 return nGetFileInformation(fullPath);
216 internal void SetHashControl(byte[] hash, AssemblyHashAlgorithm hashAlgorithm)
218 _HashForControl=hash;
219 _HashAlgorithmForControl=hashAlgorithm;
222 // The public key that is used to verify an assemblies
223 // inclusion into the namespace. If the public key associated
224 // with the namespace cannot verify the assembly the assembly
225 // will fail to load.
226 public byte[] GetPublicKey()
228 #if FEATURE_LEGACYNETCF
229 if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8 && _PublicKey == null)
230 return EmptyArray<Byte>.Value;
236 public void SetPublicKey(byte[] publicKey)
238 _PublicKey = publicKey;
240 if (publicKey == null)
241 _Flags &= ~AssemblyNameFlags.PublicKey;
243 _Flags |= AssemblyNameFlags.PublicKey;
246 // The compressed version of the public key formed from a truncated hash.
247 // Will throw a SecurityException if _PublicKey is invalid
248 [System.Security.SecuritySafeCritical] // auto-generated
249 public byte[] GetPublicKeyToken()
251 if (_PublicKeyToken == null)
252 _PublicKeyToken = nGetPublicKeyToken();
253 return _PublicKeyToken;
256 public void SetPublicKeyToken(byte[] publicKeyToken)
258 _PublicKeyToken = publicKeyToken;
261 // Flags modifying the name. So far the only flag is PublicKey, which
262 // indicates that a full public key and not the compressed version is
264 // Processor Architecture flags are set only through ProcessorArchitecture
265 // property and can't be set or retrieved directly
266 // Content Type flags are set only through ContentType property and can't be
267 // set or retrieved directly
268 public AssemblyNameFlags Flags
270 get { return (AssemblyNameFlags)((uint)_Flags & 0xFFFFF10F); }
272 _Flags &= unchecked((AssemblyNameFlags)0x00000EF0);
273 _Flags |= (value & unchecked((AssemblyNameFlags)0xFFFFF10F));
277 public AssemblyHashAlgorithm HashAlgorithm
279 get { return _HashAlgorithm; }
280 set { _HashAlgorithm = value; }
283 public AssemblyVersionCompatibility VersionCompatibility
285 get { return _VersionCompatibility; }
286 set { _VersionCompatibility = value; }
289 public StrongNameKeyPair KeyPair
291 get { return _StrongNameKeyPair; }
292 set { _StrongNameKeyPair = value; }
295 public String FullName
297 [System.Security.SecuritySafeCritical] // auto-generated
299 String name = nToString();
300 if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8 && string.IsNullOrEmpty(name))
301 return base.ToString();
307 // Returns the stringized version of the assembly name.
308 public override String ToString()
312 return base.ToString();
317 #if FEATURE_SERIALIZATION
318 [System.Security.SecurityCritical] // auto-generated_required
319 public void GetObjectData(SerializationInfo info, StreamingContext context)
322 throw new ArgumentNullException("info");
323 Contract.EndContractBlock();
325 //Allocate the serialization info and serialize our static data.
326 info.AddValue("_Name", _Name);
327 info.AddValue("_PublicKey", _PublicKey, typeof(byte[]));
328 info.AddValue("_PublicKeyToken", _PublicKeyToken, typeof(byte[]));
330 info.AddValue("_CultureInfo", (_CultureInfo == null) ? -1 :_CultureInfo.LCID);
332 info.AddValue("_CodeBase", _CodeBase);
333 info.AddValue("_Version", _Version);
334 info.AddValue("_HashAlgorithm", _HashAlgorithm, typeof(AssemblyHashAlgorithm));
335 info.AddValue("_HashAlgorithmForControl", _HashAlgorithmForControl, typeof(AssemblyHashAlgorithm));
336 info.AddValue("_StrongNameKeyPair", _StrongNameKeyPair, typeof(StrongNameKeyPair));
337 info.AddValue("_VersionCompatibility", _VersionCompatibility, typeof(AssemblyVersionCompatibility));
338 info.AddValue("_Flags", _Flags, typeof(AssemblyNameFlags));
339 info.AddValue("_HashForControl",_HashForControl,typeof(byte[]));
342 public void OnDeserialization(Object sender)
344 // Deserialization has already been performed
345 if (m_siInfo == null)
348 _Name = m_siInfo.GetString("_Name");
349 _PublicKey = (byte[]) m_siInfo.GetValue("_PublicKey", typeof(byte[]));
350 _PublicKeyToken = (byte[]) m_siInfo.GetValue("_PublicKeyToken", typeof(byte[]));
352 int lcid = (int)m_siInfo.GetInt32("_CultureInfo");
354 _CultureInfo = new CultureInfo(lcid);
357 _CodeBase = m_siInfo.GetString("_CodeBase");
358 _Version = (Version) m_siInfo.GetValue("_Version", typeof(Version));
359 _HashAlgorithm = (AssemblyHashAlgorithm) m_siInfo.GetValue("_HashAlgorithm", typeof(AssemblyHashAlgorithm));
360 _StrongNameKeyPair = (StrongNameKeyPair) m_siInfo.GetValue("_StrongNameKeyPair", typeof(StrongNameKeyPair));
361 _VersionCompatibility = (AssemblyVersionCompatibility)m_siInfo.GetValue("_VersionCompatibility", typeof(AssemblyVersionCompatibility));
362 _Flags = (AssemblyNameFlags) m_siInfo.GetValue("_Flags", typeof(AssemblyNameFlags));
365 _HashAlgorithmForControl = (AssemblyHashAlgorithm) m_siInfo.GetValue("_HashAlgorithmForControl", typeof(AssemblyHashAlgorithm));
366 _HashForControl = (byte[]) m_siInfo.GetValue("_HashForControl", typeof(byte[]));
368 catch (SerializationException) { // RTM did not have these defined
369 _HashAlgorithmForControl = AssemblyHashAlgorithm.None;
370 _HashForControl = null;
376 // Constructs a new AssemblyName during deserialization.
377 internal AssemblyName(SerializationInfo info, StreamingContext context)
379 //The graph is not valid until OnDeserialization() has been called.
382 #endif // FEATURE_SERIALIZATION
384 [System.Security.SecuritySafeCritical] // auto-generated
385 public AssemblyName(String assemblyName)
387 if (assemblyName == null)
388 throw new ArgumentNullException("assemblyName");
389 Contract.EndContractBlock();
390 if ((assemblyName.Length == 0) ||
391 (assemblyName[0] == '\0'))
392 throw new ArgumentException(Environment.GetResourceString("Format_StringZeroLength"));
394 _Name = assemblyName;
398 [System.Security.SecuritySafeCritical] // auto-generated
399 [ResourceExposure(ResourceScope.None)]
400 static public bool ReferenceMatchesDefinition(AssemblyName reference,
401 AssemblyName definition)
403 // Optimization for common use case
404 if (Object.ReferenceEquals(reference, definition))
408 return ReferenceMatchesDefinitionInternal(reference, definition, true);
412 /// "parse" tells us to parse the simple name of the assembly as if it was the full name
413 /// almost never the right thing to do, but needed for compat
414 [System.Security.SecuritySafeCritical] // auto-generated
415 [ResourceExposure(ResourceScope.None)]
416 [MethodImplAttribute(MethodImplOptions.InternalCall)]
417 static internal extern bool ReferenceMatchesDefinitionInternal(AssemblyName reference,
418 AssemblyName definition,
423 [System.Security.SecurityCritical] // auto-generated
424 [ResourceExposure(ResourceScope.None)]
425 [MethodImplAttribute(MethodImplOptions.InternalCall)]
426 internal extern void nInit(out RuntimeAssembly assembly, bool forIntrospection, bool raiseResolveEvent);
428 [System.Security.SecurityCritical] // auto-generated
429 internal void nInit()
431 RuntimeAssembly dummy = null;
432 nInit(out dummy, false, false);
435 internal void SetProcArchIndex(PortableExecutableKinds pek, ImageFileMachine ifm)
437 ProcessorArchitecture = CalculateProcArchIndex(pek, ifm, _Flags);
440 internal static ProcessorArchitecture CalculateProcArchIndex(PortableExecutableKinds pek, ImageFileMachine ifm, AssemblyNameFlags flags)
442 if (((uint)flags & 0xF0) == 0x70)
443 return ProcessorArchitecture.None;
445 if ((pek & System.Reflection.PortableExecutableKinds.PE32Plus) == System.Reflection.PortableExecutableKinds.PE32Plus)
449 case System.Reflection.ImageFileMachine.IA64:
450 return ProcessorArchitecture.IA64;
451 case System.Reflection.ImageFileMachine.AMD64:
452 return ProcessorArchitecture.Amd64;
453 case System.Reflection.ImageFileMachine.I386:
454 if ((pek & System.Reflection.PortableExecutableKinds.ILOnly) == System.Reflection.PortableExecutableKinds.ILOnly)
455 return ProcessorArchitecture.MSIL;
461 if (ifm == System.Reflection.ImageFileMachine.I386)
463 if ((pek & System.Reflection.PortableExecutableKinds.Required32Bit) == System.Reflection.PortableExecutableKinds.Required32Bit)
464 return ProcessorArchitecture.X86;
466 if ((pek & System.Reflection.PortableExecutableKinds.ILOnly) == System.Reflection.PortableExecutableKinds.ILOnly)
467 return ProcessorArchitecture.MSIL;
469 return ProcessorArchitecture.X86;
471 if (ifm == System.Reflection.ImageFileMachine.ARM)
473 return ProcessorArchitecture.Arm;
476 return ProcessorArchitecture.None;
479 internal void Init(String name,
481 byte[] publicKeyToken,
483 CultureInfo cultureInfo,
484 AssemblyHashAlgorithm hashAlgorithm,
485 AssemblyVersionCompatibility versionCompatibility,
487 AssemblyNameFlags flags,
488 StrongNameKeyPair keyPair) // Null if ref, matching Assembly if def
492 if (publicKey != null) {
493 _PublicKey = new byte[publicKey.Length];
494 Array.Copy(publicKey, _PublicKey, publicKey.Length);
497 if (publicKeyToken != null) {
498 _PublicKeyToken = new byte[publicKeyToken.Length];
499 Array.Copy(publicKeyToken, _PublicKeyToken, publicKeyToken.Length);
503 _Version = (Version) version.Clone();
505 _CultureInfo = cultureInfo;
506 _HashAlgorithm = hashAlgorithm;
507 _VersionCompatibility = versionCompatibility;
508 _CodeBase = codeBase;
510 _StrongNameKeyPair = keyPair;
514 void _AssemblyName.GetTypeInfoCount(out uint pcTInfo)
516 throw new NotImplementedException();
519 void _AssemblyName.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
521 throw new NotImplementedException();
524 void _AssemblyName.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
526 throw new NotImplementedException();
529 void _AssemblyName.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
531 throw new NotImplementedException();
536 internal string GetNameWithPublicKey()
538 byte[] key = GetPublicKey();
540 // The following string should not be localized because it is used in security decisions.
541 return Name + ", PublicKey=" + System.Security.Util.Hex.EncodeHexString(key);
545 // This call opens and closes the file, but does not add the
546 // assembly to the domain.
547 [System.Security.SecurityCritical] // auto-generated
548 [ResourceExposure(ResourceScope.Machine)]
549 [MethodImplAttribute(MethodImplOptions.InternalCall)]
550 static internal extern AssemblyName nGetFileInformation(String s);
552 [System.Security.SecurityCritical] // auto-generated
553 [ResourceExposure(ResourceScope.None)]
554 [MethodImplAttribute(MethodImplOptions.InternalCall)]
555 private extern String nToString();
557 [System.Security.SecurityCritical] // auto-generated
558 [ResourceExposure(ResourceScope.None)]
559 [MethodImplAttribute(MethodImplOptions.InternalCall)]
560 private extern byte[] nGetPublicKeyToken();
562 [System.Security.SecurityCritical] // auto-generated
563 [ResourceExposure(ResourceScope.Machine)]
564 [MethodImplAttribute(MethodImplOptions.InternalCall)]
565 static internal extern String EscapeCodeBase(String codeBase);