2
Copyright (C) 2009 Jeroen Frijters
4
This software is provided 'as-is', without any express or implied
5
warranty. In no event will the authors be held liable for any damages
6
arising from the use of this software.
8
Permission is granted to anyone to use this software for any purpose,
9
including commercial applications, and to alter it and redistribute it
10
freely, subject to the following restrictions:
12
1. The origin of this software must not be misrepresented; you must not
13
claim that you wrote the original software. If you use this software
14
in a product, an acknowledgment in the product documentation would be
15
appreciated but is not required.
16
2. Altered source versions must be plainly marked as such, and must not be
17
misrepresented as being the original software.
18
3. This notice may not be removed or altered from any source distribution.
25
using System.Collections.Generic;
26
using System.Configuration.Assemblies;
28
using IKVM.Reflection.Metadata;
30
namespace IKVM.Reflection.Reader
32
sealed class AssemblyReader : Assembly
34
private const int ContainsNoMetaData = 0x0001;
35
private readonly string location;
36
private readonly ModuleReader manifestModule;
37
private readonly Module[] externalModules;
39
internal AssemblyReader(string location, ModuleReader manifestModule)
40
: base(manifestModule.universe)
42
this.location = location;
43
this.manifestModule = manifestModule;
44
externalModules = new Module[manifestModule.File.records.Length];
47
public override string Location
49
get { return location; }
52
public override AssemblyName GetName()
54
return GetNameImpl(ref manifestModule.AssemblyTable.records[0]);
57
private AssemblyName GetNameImpl(ref AssemblyTable.Record rec)
59
AssemblyName name = new AssemblyName();
60
name.Name = manifestModule.GetString(rec.Name);
61
name.Version = new Version(rec.MajorVersion, rec.MinorVersion, rec.BuildNumber, rec.RevisionNumber);
62
if (rec.PublicKey != 0)
64
name.SetPublicKey(manifestModule.GetBlobCopy(rec.PublicKey));
68
name.SetPublicKey(Empty<byte>.Array);
72
name.Culture = manifestModule.GetString(rec.Culture);
78
name.HashAlgorithm = (AssemblyHashAlgorithm)rec.HashAlgId;
79
name.CodeBase = this.CodeBase;
80
PortableExecutableKinds peKind;
81
ImageFileMachine machine;
82
manifestModule.GetPEKind(out peKind, out machine);
85
case ImageFileMachine.I386:
86
// FXBUG we copy the .NET bug that Preferred32Bit implies x86
87
if ((peKind & (PortableExecutableKinds.Required32Bit | PortableExecutableKinds.Preferred32Bit)) != 0)
89
name.ProcessorArchitecture = ProcessorArchitecture.X86;
91
else if ((rec.Flags & 0x70) == 0x70)
93
// it's a reference assembly
94
name.ProcessorArchitecture = ProcessorArchitecture.None;
98
name.ProcessorArchitecture = ProcessorArchitecture.MSIL;
101
case ImageFileMachine.IA64:
102
name.ProcessorArchitecture = ProcessorArchitecture.IA64;
104
case ImageFileMachine.AMD64:
105
name.ProcessorArchitecture = ProcessorArchitecture.Amd64;
107
case ImageFileMachine.ARM:
108
name.ProcessorArchitecture = ProcessorArchitecture.Arm;
111
name.RawFlags = (AssemblyNameFlags)rec.Flags;
115
public override Type[] GetTypes()
117
if (externalModules.Length == 0)
119
return manifestModule.GetTypes();
122
List<Type> list = new List<Type>();
123
foreach (Module module in GetModules(false))
125
list.AddRange(module.GetTypes());
127
return list.ToArray();
130
internal override Type FindType(TypeName typeName)
132
Type type = manifestModule.FindType(typeName);
133
for (int i = 0; type == null && i < externalModules.Length; i++)
135
if ((manifestModule.File.records[i].Flags & ContainsNoMetaData) == 0)
137
type = GetModule(i).FindType(typeName);
143
internal override Type FindTypeIgnoreCase(TypeName lowerCaseName)
145
Type type = manifestModule.FindTypeIgnoreCase(lowerCaseName);
146
for (int i = 0; type == null && i < externalModules.Length; i++)
148
if ((manifestModule.File.records[i].Flags & ContainsNoMetaData) == 0)
150
type = GetModule(i).FindTypeIgnoreCase(lowerCaseName);
156
public override string ImageRuntimeVersion
158
get { return manifestModule.__ImageRuntimeVersion; }
161
public override Module ManifestModule
163
get { return manifestModule; }
166
public override Module[] GetLoadedModules(bool getResourceModules)
168
List<Module> list = new List<Module>();
169
list.Add(manifestModule);
170
foreach (Module m in externalModules)
177
return list.ToArray();
180
public override Module[] GetModules(bool getResourceModules)
182
if (externalModules.Length == 0)
184
return new Module[] { manifestModule };
188
List<Module> list = new List<Module>();
189
list.Add(manifestModule);
190
for (int i = 0; i < manifestModule.File.records.Length; i++)
192
if (getResourceModules || (manifestModule.File.records[i].Flags & ContainsNoMetaData) == 0)
194
list.Add(GetModule(i));
197
return list.ToArray();
201
public override Module GetModule(string name)
203
if (name.Equals(manifestModule.ScopeName, StringComparison.InvariantCultureIgnoreCase))
205
return manifestModule;
207
int index = GetModuleIndex(name);
210
return GetModule(index);
215
private int GetModuleIndex(string name)
217
for (int i = 0; i < manifestModule.File.records.Length; i++)
219
if (name.Equals(manifestModule.GetString(manifestModule.File.records[i].Name), StringComparison.InvariantCultureIgnoreCase))
227
private Module GetModule(int index)
229
if (externalModules[index] != null)
231
return externalModules[index];
233
return LoadModule(index, null, manifestModule.GetString(manifestModule.File.records[index].Name));
236
private Module LoadModule(int index, byte[] rawModule, string name)
238
string location = name == null ? null : Path.Combine(Path.GetDirectoryName(this.location), name);
239
if ((manifestModule.File.records[index].Flags & ContainsNoMetaData) != 0)
241
return externalModules[index] = new ResourceModule(manifestModule, index, location);
245
if (rawModule == null)
249
rawModule = File.ReadAllBytes(location);
251
catch (FileNotFoundException)
253
if (resolvers != null)
255
ResolveEventArgs arg = new ResolveEventArgs(name, this);
256
foreach (ModuleResolveEventHandler resolver in resolvers)
258
Module module = resolver(this, arg);
265
if (universe.MissingMemberResolution)
267
return externalModules[index] = new MissingModule(this);
272
return externalModules[index] = new ModuleReader(this, manifestModule.universe, new MemoryStream(rawModule), location);
276
public override Module LoadModule(string moduleName, byte[] rawModule)
278
int index = GetModuleIndex(moduleName);
281
throw new ArgumentException();
283
if (externalModules[index] != null)
285
return externalModules[index];
287
return LoadModule(index, rawModule, null);
290
public override MethodInfo EntryPoint
292
get { return manifestModule.GetEntryPoint(); }
295
public override string[] GetManifestResourceNames()
297
return manifestModule.GetManifestResourceNames();
300
public override ManifestResourceInfo GetManifestResourceInfo(string resourceName)
302
return manifestModule.GetManifestResourceInfo(resourceName);
305
public override Stream GetManifestResourceStream(string resourceName)
307
return manifestModule.GetManifestResourceStream(resourceName);
310
public override AssemblyName[] GetReferencedAssemblies()
312
return manifestModule.__GetReferencedAssemblies();
315
protected override AssemblyNameFlags GetAssemblyFlags()
317
return (AssemblyNameFlags)manifestModule.AssemblyTable.records[0].Flags;
322
get { return manifestModule.GetString(manifestModule.AssemblyTable.records[0].Name); }
325
internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
327
return CustomAttributeData.GetCustomAttributesImpl(null, manifestModule, 0x20000001, attributeType) ?? CustomAttributeData.EmptyList;