/// <summary> /// Tries to resolve given assembly name as if given module would reference it. /// </summary> /// <param name="thisModule">The <see cref="CILModule"/> loaded by this <see cref="CILAssemblyLoader"/>.</param> /// <param name="name">The <see cref="CILAssemblyName"/> of reference.</param> /// <param name="resolvedAssembly">This will hold the resolved assembly, if successful.</param> /// <returns><c>true</c> if successfully resolved reference; <c>false</c> otherwise.</returns> public Boolean TryResolveReference(CILModule thisModule, CILAssemblyName name, out CILAssembly resolvedAssembly) { String modPath = null; String libAssemblyPath = null; var retVal = thisModule != null && this._moduleResources.TryGetValue(thisModule, out modPath); if (retVal) { if (!this._callbacks.TryResolveAssemblyFilePath(modPath, name, out libAssemblyPath)) { // Have to deduce ourselves - most likely client assembly referencing system assembly var fwInfo = this.GetMonikerInfoFor(modPath, this._loadingArgs[thisModule]); if (!this._callbacks.TryGetFrameworkAssemblyPath(modPath, name, fwInfo.FrameworkName, fwInfo.FrameworkVersion, fwInfo.ProfileName, out libAssemblyPath)) { // TODO event libAssemblyPath = null; } } } retVal = libAssemblyPath != null; resolvedAssembly = retVal ? this.LoadModuleFrom(libAssemblyPath).Assembly : null; return(retVal); }
private static CILAssemblyName ParseAssemblyNameFromTypeString(ref String str) { var typeStrMax = 0; var curIdx = -1; while (typeStrMax < str.Length && (curIdx = str.IndexOf(TYPE_ASSEMBLY_SEPARATOR, typeStrMax)) > 0 && str[curIdx - 1] == ESCAPE_CHAR) { typeStrMax = curIdx + TYPE_ASSEMBLY_SEPARATOR.Length; } CILAssemblyName an; if (curIdx < 0 || typeStrMax >= str.Length) { // No assembly name present an = null; } else { // Parse assembly name and set type string to hold actual type string an = CILAssemblyName.Parse(str.Substring(curIdx + TYPE_ASSEMBLY_SEPARATOR.Length)); str = str.Substring(0, curIdx); } return(an); }
private static Boolean TryParseVersion(CILAssemblyName assemblyName, String fullAssemblyName, ref Int32 nameIdx) { var aux = NextSeparatorIdx(fullAssemblyName, VERSION_SEPARATOR, nameIdx); UInt16 tmp = 0; var success = aux > 0 && UInt16.TryParse(fullAssemblyName.Substring(nameIdx, aux), out tmp); if (success) { assemblyName._majorVersion = tmp; nameIdx += aux + 1; aux = NextSeparatorIdx(fullAssemblyName, VERSION_SEPARATOR, nameIdx); success = aux > 0 && UInt16.TryParse(fullAssemblyName.Substring(nameIdx, aux), out tmp); if (success) { assemblyName._minorVersion = tmp; nameIdx += aux + 1; aux = NextSeparatorIdx(fullAssemblyName, VERSION_SEPARATOR, nameIdx); success = aux > 0 && UInt16.TryParse(fullAssemblyName.Substring(nameIdx, aux), out tmp); if (success) { assemblyName._buildNumber = tmp; nameIdx += aux + 1; aux = NextSeparatorIdx(fullAssemblyName, ASSEMBLY_NAME_ELEMENTS_SEPARATOR, nameIdx); success = aux > 0 && UInt16.TryParse(fullAssemblyName.Substring(nameIdx, aux), out tmp); if (success) { nameIdx += aux; assemblyName._revision = tmp; } } } } return(success); }
internal TypeParseResult(CILAssemblyName an, String ns, String tn, IList <String> gArgs, IList <Tuple <ElementKind, GeneralArrayInfo> > elInfo, IList <String> nt) { this.assemblyName = an; this.nameSpace = ns; this.typeName = tn; this.genericArguments = gArgs; this.elementInfo = elInfo; this.nestedTypes = nt; }
private CILAssembly LoadLibAssembly(CILModule thisModule, CILAssemblyName name) { CILAssembly retVal; if (!this.TryResolveReference(thisModule, name, out retVal)) { throw new Exception("Failed to deduce path for " + name + " referenced from " + thisModule.Name + "."); } return(retVal); }
/// <inheritdoc /> public Boolean TryResolveAssemblyFilePath(String thisModulePath, CILAssemblyManipulator.API.CILAssemblyName referencedAssembly, out String referencedAssemblyPath) { var dirName = Path.GetDirectoryName(thisModulePath); // Check if .dll or .exe exists in same directory var dllName = Path.Combine(dirName, referencedAssembly.Name + ".dll"); var exeName = Path.Combine(dirName, referencedAssembly.Name + ".exe"); var winmdName = Path.Combine(dirName, referencedAssembly.Name + ".winmd"); // TODO other extensions? referencedAssemblyPath = new[] { dllName, exeName, winmdName }.FirstOrDefault(fn => File.Exists(fn)); return(referencedAssemblyPath != null); }
private static Boolean TryParsePublicKeyFullOrToken(CILAssemblyName assemblyName, String fullAssemblyName, ref Int32 nameIdx) { var aux = NextSeparatorIdx(fullAssemblyName, ASSEMBLY_NAME_ELEMENTS_SEPARATOR, nameIdx); var success = aux > 0; if (success && !String.Equals("null", fullAssemblyName.Substring(nameIdx, aux), StringComparison.OrdinalIgnoreCase)) { assemblyName._publicKey = StringConversions.HexStr2ByteArray(fullAssemblyName, nameIdx, 0, 0); } nameIdx += aux; return(success); }
/// <summary> /// Creates a new instance of <see cref="CILAssemblyName"/> with all fields set to have same values as <paramref name="otherName"/>. /// </summary> /// <param name="otherName">The <see cref="CILAssemblyName"/> to copy values from.</param> public CILAssemblyName(CILAssemblyName otherName) : this(otherName == null ? null : otherName.Name, otherName == null ? 0 : otherName.MajorVersion, otherName == null ? 0 : otherName.MinorVersion, otherName == null ? 0 : otherName.BuildNumber, otherName == null ? 0 : otherName.Revision, otherName == null ? AssemblyHashAlgorithm.SHA1 : otherName.HashAlgorithm, otherName == null ? AssemblyFlags.None : otherName.Flags, null, otherName == null ? null : otherName.Culture) { if (otherName != null) { var pk = otherName.PublicKey; if (!pk.IsNullOrEmpty()) { var thisPK = new Byte[pk.Length]; Array.Copy(pk, thisPK, pk.Length); this._publicKey = thisPK; } } }
private static Boolean TryParseCulture(CILAssemblyName assemblyName, String fullAssemblyName, ref Int32 nameIdx) { var aux = NextSeparatorIdx(fullAssemblyName, ASSEMBLY_NAME_ELEMENTS_SEPARATOR, nameIdx); var success = aux > 0; if (success) { assemblyName._culture = fullAssemblyName.Substring(nameIdx, aux); nameIdx += aux; if (String.Equals("\"\"", assemblyName._culture) || String.Compare(assemblyName._culture, NEUTRAL_CULTURE, StringComparison.OrdinalIgnoreCase) == 0) { assemblyName._culture = NEUTRAL_CULTURE_NAME; } } return(success); }
/// <summary> /// Creates <see cref="TypeForwardingInfo"/> with specified information. /// </summary> /// <param name="typeAttributes">The <see cref="TypeAttributes"/> of the target type.</param> /// <param name="name">The type name.</param> /// <param name="namespace">The type namespace.</param> /// <param name="declTypeName">The declaring type name. May be <c>null</c>.</param> /// <param name="declTypeNamespace">The declaring type namespace. May be <c>null</c>.</param> /// <param name="assemblyName">The name of the assembly containing the type.</param> /// <exception cref="ArgumentNullException">If <paramref name="name"/> or <paramref name="assemblyName"/> is <c>null</c>.</exception> /// <exception cref="ArgumentException">If <paramref name="declTypeNamespace"/> is not <c>null</c> or empty, but <paramref name="declTypeName"/> is.</exception> /// <remarks> /// A copy of <paramref name="assemblyName"/> is created so that modifications done to the assembly name would not reflect to the assembly name given as parameter. /// </remarks> public TypeForwardingInfo(TypeAttributes typeAttributes, String name, String @namespace, String declTypeName, String declTypeNamespace, CILAssemblyName assemblyName) { ArgumentValidator.ValidateNotNull("Type name", name); ArgumentValidator.ValidateNotNull("Assembly name", assemblyName); if (!String.IsNullOrEmpty(declTypeNamespace) && String.IsNullOrEmpty(declTypeName)) { throw new ArgumentException("The declaring type namespace was specified but the declaring type name was not."); } this._typeAttrs = typeAttributes; this._name = name; this._namespace = @namespace; this._declTypeName = declTypeName; this._declTypeNamespace = declTypeNamespace; this._assemblyName = new CILAssemblyName(assemblyName); }
/// <inheritdoc /> public Boolean TryGetFrameworkAssemblyPath(String thisModulePath, CILAssemblyManipulator.API.CILAssemblyName referencedAssembly, String fwName, String fwVersion, String fwProfile, out String fwAssemblyPath) { // TODO Additional checks fwAssemblyPath = Path.Combine(this.GetDirectory(fwName, fwVersion, fwProfile), referencedAssembly.Name + ".dll"); return(true); }
/// <summary> /// Tries to parse textual name of the assembly into a <see cref="CILAssemblyName"/>. /// </summary> /// <param name="textualAssemblyName">The textual assembly name.</param> /// <param name="assemblyName">If <paramref name="textualAssemblyName"/> is <c>null</c>, this will be <c>null</c>. Otherwise, this will hold a new instance of <see cref="CILAssemblyName"/> with any successfully parsed components.</param> /// <returns><c>true</c> if <paramref name="textualAssemblyName"/> was successfully parsed till the end; <c>false</c> otherwise.</returns> /// <remarks> /// The <see cref="System.Reflection.AssemblyName(String)"/> constructor apparently requires that the assembly of the referenced name actually exists and will try to load it. /// Because of this, this method implements pure parsing of assembly name, without caring whether it actually exists or not. /// The <see href="http://msdn.microsoft.com/en-us/library/yfsftwz6%28v=vs.110%29.aspx">Specifying Fully Qualified Type Names</see> resource at MSDN provides information about textual assembly names. /// </remarks> public static Boolean TryParse(String textualAssemblyName, out CILAssemblyName assemblyName) { var success = !String.IsNullOrEmpty(textualAssemblyName); if (success) { assemblyName = new CILAssemblyName(); // First, name var nameIdx = TryParseName(textualAssemblyName); // Name may contain escape characters assemblyName._name = Utils.UnescapeSomeString(textualAssemblyName, 0, nameIdx); success = !String.IsNullOrEmpty(assemblyName._name); if (success) { // Then, other components. Other components shouldn't contain escaped characters. while (success && nameIdx < textualAssemblyName.Length) { success = textualAssemblyName[nameIdx] == ASSEMBLY_NAME_ELEMENTS_SEPARATOR; if (success) { // Skip following whitespaces while (++nameIdx < textualAssemblyName.Length && Char.IsWhiteSpace(textualAssemblyName[nameIdx])) { ; } success = nameIdx < textualAssemblyName.Length; if (success) { // Find next separator var aux = NextSeparatorIdx(textualAssemblyName, ASSEMBLY_NAME_ELEMENT_VALUE_SEPARATOR, nameIdx); success = aux > 0 && aux < textualAssemblyName.Length - 1 - nameIdx; if (success) { var el = GetElement(textualAssemblyName, nameIdx, aux); nameIdx += aux + 1; switch (el) { case Elements.Version: success = TryParseVersion(assemblyName, textualAssemblyName, ref nameIdx); break; case Elements.Culture: success = TryParseCulture(assemblyName, textualAssemblyName, ref nameIdx); break; case Elements.PublicKeyToken: success = TryParsePublicKeyFullOrToken(assemblyName, textualAssemblyName, ref nameIdx); break; case Elements.PublicKey: success = TryParsePublicKeyFullOrToken(assemblyName, textualAssemblyName, ref nameIdx); if (!assemblyName._publicKey.IsNullOrEmpty()) { assemblyName._flags |= (Int32)AssemblyFlags.PublicKey; } break; default: success = false; break; } } } } } // Return true only if successfully parsed whole string till the end. success = success && nameIdx == textualAssemblyName.Length; } } else { assemblyName = null; } return(success); }
/// <summary> /// Creates <see cref="TypeForwardingInfo"/> with specified information. /// </summary> /// <param name="typeAttributes">The <see cref="TypeAttributes"/> of the target type.</param> /// <param name="name">The type name.</param> /// <param name="namespace">The type namespace.</param> /// <param name="assemblyName">The name of the assembly containing the type.</param> /// <exception cref="ArgumentNullException">If <paramref name="name"/> or <paramref name="assemblyName"/> is <c>null</c>.</exception> /// <remarks> /// A copy of <paramref name="assemblyName"/> is created so that modifications done to the assembly name would not reflect to the assembly name given as parameter. /// </remarks> public TypeForwardingInfo(TypeAttributes typeAttributes, String name, String @namespace, CILAssemblyName assemblyName) : this(typeAttributes, name, @namespace, null, null, assemblyName) { }