3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 /*============================================================
10 ** <OWNER>[....]</OWNER>
11 ** <OWNER>[....]</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;
49 private SerializationInfo m_siInfo; //A temporary variable which we need during deserialization.
51 private byte[] _HashForControl;
52 private AssemblyHashAlgorithm _HashAlgorithm;
53 private AssemblyHashAlgorithm _HashAlgorithmForControl;
55 private AssemblyVersionCompatibility _VersionCompatibility;
56 private AssemblyNameFlags _Flags;
60 _HashAlgorithm = AssemblyHashAlgorithm.None;
61 _VersionCompatibility = AssemblyVersionCompatibility.SameMachine;
62 _Flags = AssemblyNameFlags.None;
65 // Set and get the name of the assembly. If this is a weak Name
66 // then it optionally contains a site. For strong assembly names,
67 // the name partitions up the strong name's namespace
71 set { _Name = value; }
74 public Version Version
84 // Locales, internally the LCID is used for the match.
85 public CultureInfo CultureInfo
95 public String CultureName
99 return (_CultureInfo == null) ? null : _CultureInfo.Name;
103 public String CodeBase
106 [System.Security.SecurityCritical] // auto-generated
108 [ResourceExposure(ResourceScope.Machine)]
109 get { return _CodeBase; }
111 [System.Security.SecurityCritical] // auto-generated
113 [ResourceExposure(ResourceScope.Machine)]
114 set { _CodeBase = value; }
117 public String EscapedCodeBase
119 [System.Security.SecuritySafeCritical] // auto-generated
120 [ResourceExposure(ResourceScope.Machine)]
121 [ResourceConsumption(ResourceScope.Machine)]
124 if (_CodeBase == null)
127 return EscapeCodeBase(_CodeBase);
131 public ProcessorArchitecture ProcessorArchitecture
134 int x = (((int)_Flags) & 0x70) >> 4;
137 return (ProcessorArchitecture)x;
140 int x = ((int)value) & 0x07;
142 _Flags = (AssemblyNameFlags)((int)_Flags & 0xFFFFFF0F);
143 _Flags |= (AssemblyNameFlags)(x << 4);
148 [System.Runtime.InteropServices.ComVisible(false)]
149 public AssemblyContentType ContentType
153 int x = (((int)_Flags) & 0x00000E00) >> 9;
156 return (AssemblyContentType)x;
160 int x = ((int)value) & 0x07;
163 _Flags = (AssemblyNameFlags)((int)_Flags & 0xFFFFF1FF);
164 _Flags |= (AssemblyNameFlags)(x << 9);
171 // Make a copy of this assembly name.
172 public Object Clone()
174 AssemblyName name = new AssemblyName();
181 _VersionCompatibility,
185 name._HashForControl=_HashForControl;
186 name._HashAlgorithmForControl=_HashAlgorithmForControl;
191 * Get the AssemblyName for a given file. This will only work
192 * if the file contains an assembly manifest. This method causes
193 * the file to be opened and closed.
195 [System.Security.SecuritySafeCritical] // auto-generated
196 [ResourceExposure(ResourceScope.None)]
197 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
198 static public AssemblyName GetAssemblyName(String assemblyFile)
200 if(assemblyFile == null)
201 throw new ArgumentNullException("assemblyFile");
202 Contract.EndContractBlock();
204 // Assembly.GetNameInternal() will not demand path discovery
205 // permission, so do that first.
206 String fullPath = Path.GetFullPathInternal(assemblyFile);
207 new FileIOPermission( FileIOPermissionAccess.PathDiscovery, fullPath ).Demand();
208 return nGetFileInformation(fullPath);
211 internal void SetHashControl(byte[] hash, AssemblyHashAlgorithm hashAlgorithm)
213 _HashForControl=hash;
214 _HashAlgorithmForControl=hashAlgorithm;
217 // The public key that is used to verify an assemblies
218 // inclusion into the namespace. If the public key associated
219 // with the namespace cannot verify the assembly the assembly
220 // will fail to load.
221 public byte[] GetPublicKey()
223 #if FEATURE_LEGACYNETCF
224 if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8 && _PublicKey == null)
225 return EmptyArray<Byte>.Value;
231 public void SetPublicKey(byte[] publicKey)
233 _PublicKey = publicKey;
235 if (publicKey == null)
236 _Flags &= ~AssemblyNameFlags.PublicKey;
238 _Flags |= AssemblyNameFlags.PublicKey;
241 // The compressed version of the public key formed from a truncated hash.
242 // Will throw a SecurityException if _PublicKey is invalid
243 [System.Security.SecuritySafeCritical] // auto-generated
244 public byte[] GetPublicKeyToken()
246 if (_PublicKeyToken == null)
247 _PublicKeyToken = nGetPublicKeyToken();
248 return _PublicKeyToken;
251 public void SetPublicKeyToken(byte[] publicKeyToken)
253 _PublicKeyToken = publicKeyToken;
256 // Flags modifying the name. So far the only flag is PublicKey, which
257 // indicates that a full public key and not the compressed version is
259 // Processor Architecture flags are set only through ProcessorArchitecture
260 // property and can't be set or retrieved directly
261 // Content Type flags are set only through ContentType property and can't be
262 // set or retrieved directly
263 public AssemblyNameFlags Flags
265 get { return (AssemblyNameFlags)((uint)_Flags & 0xFFFFF10F); }
267 _Flags &= unchecked((AssemblyNameFlags)0x00000EF0);
268 _Flags |= (value & unchecked((AssemblyNameFlags)0xFFFFF10F));
272 public AssemblyHashAlgorithm HashAlgorithm
274 get { return _HashAlgorithm; }
275 set { _HashAlgorithm = value; }
278 public AssemblyVersionCompatibility VersionCompatibility
280 get { return _VersionCompatibility; }
281 set { _VersionCompatibility = value; }
284 public StrongNameKeyPair KeyPair
286 get { return _StrongNameKeyPair; }
287 set { _StrongNameKeyPair = value; }
290 public String FullName
292 [System.Security.SecuritySafeCritical] // auto-generated
294 String name = nToString();
295 if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8 && string.IsNullOrEmpty(name))
296 return base.ToString();
302 // Returns the stringized version of the assembly name.
303 public override String ToString()
307 return base.ToString();
312 [System.Security.SecurityCritical] // auto-generated_required
313 public void GetObjectData(SerializationInfo info, StreamingContext context)
316 throw new ArgumentNullException("info");
317 Contract.EndContractBlock();
319 //Allocate the serialization info and serialize our static data.
320 info.AddValue("_Name", _Name);
321 info.AddValue("_PublicKey", _PublicKey, typeof(byte[]));
322 info.AddValue("_PublicKeyToken", _PublicKeyToken, typeof(byte[]));
324 info.AddValue("_CultureInfo", (_CultureInfo == null) ? -1 :_CultureInfo.LCID);
326 info.AddValue("_CodeBase", _CodeBase);
327 info.AddValue("_Version", _Version);
328 info.AddValue("_HashAlgorithm", _HashAlgorithm, typeof(AssemblyHashAlgorithm));
329 info.AddValue("_HashAlgorithmForControl", _HashAlgorithmForControl, typeof(AssemblyHashAlgorithm));
330 info.AddValue("_StrongNameKeyPair", _StrongNameKeyPair, typeof(StrongNameKeyPair));
331 info.AddValue("_VersionCompatibility", _VersionCompatibility, typeof(AssemblyVersionCompatibility));
332 info.AddValue("_Flags", _Flags, typeof(AssemblyNameFlags));
333 info.AddValue("_HashForControl",_HashForControl,typeof(byte[]));
336 public void OnDeserialization(Object sender)
338 // Deserialization has already been performed
339 if (m_siInfo == null)
342 _Name = m_siInfo.GetString("_Name");
343 _PublicKey = (byte[]) m_siInfo.GetValue("_PublicKey", typeof(byte[]));
344 _PublicKeyToken = (byte[]) m_siInfo.GetValue("_PublicKeyToken", typeof(byte[]));
346 int lcid = (int)m_siInfo.GetInt32("_CultureInfo");
348 _CultureInfo = new CultureInfo(lcid);
351 _CodeBase = m_siInfo.GetString("_CodeBase");
352 _Version = (Version) m_siInfo.GetValue("_Version", typeof(Version));
353 _HashAlgorithm = (AssemblyHashAlgorithm) m_siInfo.GetValue("_HashAlgorithm", typeof(AssemblyHashAlgorithm));
354 _StrongNameKeyPair = (StrongNameKeyPair) m_siInfo.GetValue("_StrongNameKeyPair", typeof(StrongNameKeyPair));
355 _VersionCompatibility = (AssemblyVersionCompatibility)m_siInfo.GetValue("_VersionCompatibility", typeof(AssemblyVersionCompatibility));
356 _Flags = (AssemblyNameFlags) m_siInfo.GetValue("_Flags", typeof(AssemblyNameFlags));
359 _HashAlgorithmForControl = (AssemblyHashAlgorithm) m_siInfo.GetValue("_HashAlgorithmForControl", typeof(AssemblyHashAlgorithm));
360 _HashForControl = (byte[]) m_siInfo.GetValue("_HashForControl", typeof(byte[]));
362 catch (SerializationException) { // RTM did not have these defined
363 _HashAlgorithmForControl = AssemblyHashAlgorithm.None;
364 _HashForControl = null;
370 [System.Security.SecuritySafeCritical] // auto-generated
371 public AssemblyName(String assemblyName)
373 if (assemblyName == null)
374 throw new ArgumentNullException("assemblyName");
375 Contract.EndContractBlock();
376 if ((assemblyName.Length == 0) ||
377 (assemblyName[0] == '\0'))
378 throw new ArgumentException(Environment.GetResourceString("Format_StringZeroLength"));
380 _Name = assemblyName;
384 [System.Security.SecuritySafeCritical] // auto-generated
385 [ResourceExposure(ResourceScope.None)]
386 static public bool ReferenceMatchesDefinition(AssemblyName reference,
387 AssemblyName definition)
389 // Optimization for common use case
390 if (Object.ReferenceEquals(reference, definition))
394 return ReferenceMatchesDefinitionInternal(reference, definition, true);
398 /// "parse" tells us to parse the simple name of the assembly as if it was the full name
399 /// almost never the right thing to do, but needed for compat
400 [System.Security.SecuritySafeCritical] // auto-generated
401 [ResourceExposure(ResourceScope.None)]
402 [MethodImplAttribute(MethodImplOptions.InternalCall)]
403 static internal extern bool ReferenceMatchesDefinitionInternal(AssemblyName reference,
404 AssemblyName definition,
409 [System.Security.SecurityCritical] // auto-generated
410 [ResourceExposure(ResourceScope.None)]
411 [MethodImplAttribute(MethodImplOptions.InternalCall)]
412 internal extern void nInit(out RuntimeAssembly assembly, bool forIntrospection, bool raiseResolveEvent);
414 [System.Security.SecurityCritical] // auto-generated
415 internal void nInit()
417 RuntimeAssembly dummy = null;
418 nInit(out dummy, false, false);
421 // Constructs a new AssemblyName during deserialization.
422 internal AssemblyName(SerializationInfo info, StreamingContext context)
424 //The graph is not valid until OnDeserialization() has been called.
428 internal void SetProcArchIndex(PortableExecutableKinds pek, ImageFileMachine ifm)
430 ProcessorArchitecture = CalculateProcArchIndex(pek, ifm, _Flags);
433 internal static ProcessorArchitecture CalculateProcArchIndex(PortableExecutableKinds pek, ImageFileMachine ifm, AssemblyNameFlags flags)
435 if (((uint)flags & 0xF0) == 0x70)
436 return ProcessorArchitecture.None;
438 if ((pek & System.Reflection.PortableExecutableKinds.PE32Plus) == System.Reflection.PortableExecutableKinds.PE32Plus)
442 case System.Reflection.ImageFileMachine.IA64:
443 return ProcessorArchitecture.IA64;
444 case System.Reflection.ImageFileMachine.AMD64:
445 return ProcessorArchitecture.Amd64;
446 case System.Reflection.ImageFileMachine.I386:
447 if ((pek & System.Reflection.PortableExecutableKinds.ILOnly) == System.Reflection.PortableExecutableKinds.ILOnly)
448 return ProcessorArchitecture.MSIL;
454 if (ifm == System.Reflection.ImageFileMachine.I386)
456 if ((pek & System.Reflection.PortableExecutableKinds.Required32Bit) == System.Reflection.PortableExecutableKinds.Required32Bit)
457 return ProcessorArchitecture.X86;
459 if ((pek & System.Reflection.PortableExecutableKinds.ILOnly) == System.Reflection.PortableExecutableKinds.ILOnly)
460 return ProcessorArchitecture.MSIL;
462 return ProcessorArchitecture.X86;
464 if (ifm == System.Reflection.ImageFileMachine.ARM)
466 return ProcessorArchitecture.Arm;
469 return ProcessorArchitecture.None;
472 internal void Init(String name,
474 byte[] publicKeyToken,
476 CultureInfo cultureInfo,
477 AssemblyHashAlgorithm hashAlgorithm,
478 AssemblyVersionCompatibility versionCompatibility,
480 AssemblyNameFlags flags,
481 StrongNameKeyPair keyPair) // Null if ref, matching Assembly if def
485 if (publicKey != null) {
486 _PublicKey = new byte[publicKey.Length];
487 Array.Copy(publicKey, _PublicKey, publicKey.Length);
490 if (publicKeyToken != null) {
491 _PublicKeyToken = new byte[publicKeyToken.Length];
492 Array.Copy(publicKeyToken, _PublicKeyToken, publicKeyToken.Length);
496 _Version = (Version) version.Clone();
498 _CultureInfo = cultureInfo;
499 _HashAlgorithm = hashAlgorithm;
500 _VersionCompatibility = versionCompatibility;
501 _CodeBase = codeBase;
503 _StrongNameKeyPair = keyPair;
506 void _AssemblyName.GetTypeInfoCount(out uint pcTInfo)
508 throw new NotImplementedException();
511 void _AssemblyName.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
513 throw new NotImplementedException();
516 void _AssemblyName.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
518 throw new NotImplementedException();
521 void _AssemblyName.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
523 throw new NotImplementedException();
527 internal string GetNameWithPublicKey()
529 byte[] key = GetPublicKey();
531 // The following string should not be localized because it is used in security decisions.
532 return Name + ", PublicKey=" + System.Security.Util.Hex.EncodeHexString(key);
536 // This call opens and closes the file, but does not add the
537 // assembly to the domain.
538 [System.Security.SecurityCritical] // auto-generated
539 [ResourceExposure(ResourceScope.Machine)]
540 [MethodImplAttribute(MethodImplOptions.InternalCall)]
541 static internal extern AssemblyName nGetFileInformation(String s);
543 [System.Security.SecurityCritical] // auto-generated
544 [ResourceExposure(ResourceScope.None)]
545 [MethodImplAttribute(MethodImplOptions.InternalCall)]
546 private extern String nToString();
548 [System.Security.SecurityCritical] // auto-generated
549 [ResourceExposure(ResourceScope.None)]
550 [MethodImplAttribute(MethodImplOptions.InternalCall)]
551 private extern byte[] nGetPublicKeyToken();
553 [System.Security.SecurityCritical] // auto-generated
554 [ResourceExposure(ResourceScope.Machine)]
555 [MethodImplAttribute(MethodImplOptions.InternalCall)]
556 static internal extern String EscapeCodeBase(String codeBase);