~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to external/ikvm/reflect/Emit/AssemblyBuilder.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  Copyright (C) 2008-2012 Jeroen Frijters
 
3
 
 
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.
 
7
 
 
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:
 
11
 
 
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.
 
19
 
 
20
  Jeroen Frijters
 
21
  jeroen@frijters.net
 
22
  
 
23
*/
 
24
using System;
 
25
using System.Collections.Generic;
 
26
using System.Configuration.Assemblies;
 
27
using System.IO;
 
28
using System.Diagnostics;
 
29
using System.Globalization;
 
30
using System.Resources;
 
31
using System.Security.Cryptography;
 
32
using System.Security;
 
33
using IKVM.Reflection.Metadata;
 
34
using IKVM.Reflection.Impl;
 
35
using IKVM.Reflection.Writer;
 
36
 
 
37
namespace IKVM.Reflection.Emit
 
38
{
 
39
        public sealed class AssemblyBuilder : Assembly
 
40
        {
 
41
                private readonly string name;
 
42
                private ushort majorVersion;
 
43
                private ushort minorVersion;
 
44
                private ushort buildVersion;
 
45
                private ushort revisionVersion;
 
46
                private string culture;
 
47
                private AssemblyNameFlags flags;
 
48
                private AssemblyHashAlgorithm hashAlgorithm;
 
49
                private StrongNameKeyPair keyPair;
 
50
                private byte[] publicKey;
 
51
                internal readonly string dir;
 
52
                private readonly PermissionSet requiredPermissions;
 
53
                private readonly PermissionSet optionalPermissions;
 
54
                private readonly PermissionSet refusedPermissions;
 
55
                private PEFileKinds fileKind = PEFileKinds.Dll;
 
56
                private MethodInfo entryPoint;
 
57
                private VersionInfo versionInfo;
 
58
                private byte[] win32icon;
 
59
                private byte[] win32manifest;
 
60
                private byte[] win32resources;
 
61
                private string imageRuntimeVersion;
 
62
                internal int mdStreamVersion = 0x20000;
 
63
                private Module pseudoManifestModule;
 
64
                private readonly List<ResourceFile> resourceFiles = new List<ResourceFile>();
 
65
                private readonly List<ModuleBuilder> modules = new List<ModuleBuilder>();
 
66
                private readonly List<Module> addedModules = new List<Module>();
 
67
                private readonly List<CustomAttributeBuilder> customAttributes = new List<CustomAttributeBuilder>();
 
68
                private readonly List<CustomAttributeBuilder> declarativeSecurity = new List<CustomAttributeBuilder>();
 
69
                private readonly List<Type> typeForwarders = new List<Type>();
 
70
 
 
71
                private struct ResourceFile
 
72
                {
 
73
                        internal string Name;
 
74
                        internal string FileName;
 
75
                        internal ResourceAttributes Attributes;
 
76
                        internal ResourceWriter Writer;
 
77
                }
 
78
 
 
79
                internal AssemblyBuilder(Universe universe, AssemblyName name, string dir, PermissionSet requiredPermissions, PermissionSet optionalPermissions, PermissionSet refusedPermissions)
 
80
                        : base(universe)
 
81
                {
 
82
                        this.name = name.Name;
 
83
                        SetVersionHelper(name.Version);
 
84
                        if (!string.IsNullOrEmpty(name.Culture))
 
85
                        {
 
86
                                this.culture = name.Culture;
 
87
                        }
 
88
                        this.flags = name.RawFlags;
 
89
                        this.hashAlgorithm = name.HashAlgorithm;
 
90
                        if (this.hashAlgorithm == AssemblyHashAlgorithm.None)
 
91
                        {
 
92
                                this.hashAlgorithm = AssemblyHashAlgorithm.SHA1;
 
93
                        }
 
94
                        this.keyPair = name.KeyPair;
 
95
                        if (this.keyPair != null)
 
96
                        {
 
97
                                this.publicKey = this.keyPair.PublicKey;
 
98
                        }
 
99
                        else
 
100
                        {
 
101
                                byte[] publicKey = name.GetPublicKey();
 
102
                                if (publicKey != null && publicKey.Length != 0)
 
103
                                {
 
104
                                        this.publicKey = (byte[])publicKey.Clone();
 
105
                                }
 
106
                        }
 
107
                        this.dir = dir ?? ".";
 
108
                        this.requiredPermissions = requiredPermissions;
 
109
                        this.optionalPermissions = optionalPermissions;
 
110
                        this.refusedPermissions = refusedPermissions;
 
111
                        if (universe.HasMscorlib && !universe.Mscorlib.__IsMissing && universe.Mscorlib.ImageRuntimeVersion != null)
 
112
                        {
 
113
                                this.imageRuntimeVersion = universe.Mscorlib.ImageRuntimeVersion;
 
114
                        }
 
115
                        else
 
116
                        {
 
117
                                this.imageRuntimeVersion = typeof(object).Assembly.ImageRuntimeVersion;
 
118
                        }
 
119
                }
 
120
 
 
121
                private void SetVersionHelper(Version version)
 
122
                {
 
123
                        if (version == null)
 
124
                        {
 
125
                                majorVersion = 0;
 
126
                                minorVersion = 0;
 
127
                                buildVersion = 0;
 
128
                                revisionVersion = 0;
 
129
                        }
 
130
                        else
 
131
                        {
 
132
                                majorVersion = (ushort)version.Major;
 
133
                                minorVersion = (ushort)version.Minor;
 
134
                                buildVersion = version.Build == -1 ? (ushort)0 : (ushort)version.Build;
 
135
                                revisionVersion = version.Revision == -1 ? (ushort)0 : (ushort)version.Revision;
 
136
                        }
 
137
                }
 
138
 
 
139
                private void Rename(AssemblyName oldName)
 
140
                {
 
141
                        this.fullName = null;
 
142
                        universe.RenameAssembly(this, oldName);
 
143
                }
 
144
 
 
145
                public void __SetAssemblyVersion(Version version)
 
146
                {
 
147
                        AssemblyName oldName = GetName();
 
148
                        SetVersionHelper(version);
 
149
                        Rename(oldName);
 
150
                }
 
151
 
 
152
                public void __SetAssemblyCulture(string cultureName)
 
153
                {
 
154
                        AssemblyName oldName = GetName();
 
155
                        this.culture = cultureName;
 
156
                        Rename(oldName);
 
157
                }
 
158
 
 
159
                public void __SetAssemblyKeyPair(StrongNameKeyPair keyPair)
 
160
                {
 
161
                        AssemblyName oldName = GetName();
 
162
                        this.keyPair = keyPair;
 
163
                        if (keyPair != null)
 
164
                        {
 
165
                                this.publicKey = keyPair.PublicKey;
 
166
                        }
 
167
                        Rename(oldName);
 
168
                }
 
169
 
 
170
                // this is used in combination with delay signing
 
171
                public void __SetAssemblyPublicKey(byte[] publicKey)
 
172
                {
 
173
                        AssemblyName oldName = GetName();
 
174
                        this.publicKey = publicKey == null ? null : (byte[])publicKey.Clone();
 
175
                        Rename(oldName);
 
176
                }
 
177
 
 
178
                public void __SetAssemblyAlgorithmId(AssemblyHashAlgorithm hashAlgorithm)
 
179
                {
 
180
                        this.hashAlgorithm = hashAlgorithm;
 
181
                }
 
182
 
 
183
                [Obsolete("Use __AssemblyFlags property instead.")]
 
184
                public void __SetAssemblyFlags(AssemblyNameFlags flags)
 
185
                {
 
186
                        this.__AssemblyFlags = flags;
 
187
                }
 
188
 
 
189
                protected override AssemblyNameFlags GetAssemblyFlags()
 
190
                {
 
191
                        return flags;
 
192
                }
 
193
 
 
194
                public new AssemblyNameFlags __AssemblyFlags
 
195
                {
 
196
                        get { return flags; }
 
197
                        set
 
198
                        {
 
199
                                AssemblyName oldName = GetName();
 
200
                                this.flags = value;
 
201
                                Rename(oldName);
 
202
                        }
 
203
                }
 
204
 
 
205
                internal string Name
 
206
                {
 
207
                        get { return name; }
 
208
                }
 
209
 
 
210
                public override AssemblyName GetName()
 
211
                {
 
212
                        AssemblyName n = new AssemblyName();
 
213
                        n.Name = name;
 
214
                        n.Version = new Version(majorVersion, minorVersion, buildVersion, revisionVersion);
 
215
                        n.Culture = culture ?? "";
 
216
                        n.HashAlgorithm = hashAlgorithm;
 
217
                        n.RawFlags = flags;
 
218
                        n.SetPublicKey(publicKey != null ? (byte[])publicKey.Clone() : Empty<byte>.Array);
 
219
                        n.KeyPair = keyPair;
 
220
                        return n;
 
221
                }
 
222
 
 
223
                public override string Location
 
224
                {
 
225
                        get { throw new NotSupportedException(); }
 
226
                }
 
227
 
 
228
                public ModuleBuilder DefineDynamicModule(string name, string fileName)
 
229
                {
 
230
                        return DefineDynamicModule(name, fileName, false);
 
231
                }
 
232
 
 
233
                public ModuleBuilder DefineDynamicModule(string name, string fileName, bool emitSymbolInfo)
 
234
                {
 
235
                        ModuleBuilder module = new ModuleBuilder(this, name, fileName, emitSymbolInfo);
 
236
                        modules.Add(module);
 
237
                        return module;
 
238
                }
 
239
 
 
240
                public ModuleBuilder GetDynamicModule(string name)
 
241
                {
 
242
                        foreach (ModuleBuilder module in modules)
 
243
                        {
 
244
                                if (module.Name == name)
 
245
                                {
 
246
                                        return module;
 
247
                                }
 
248
                        }
 
249
                        return null;
 
250
                }
 
251
 
 
252
                public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
 
253
                {
 
254
                        SetCustomAttribute(new CustomAttributeBuilder(con, binaryAttribute));
 
255
                }
 
256
 
 
257
                public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
 
258
                {
 
259
                        customAttributes.Add(customBuilder);
 
260
                }
 
261
 
 
262
                public void __AddDeclarativeSecurity(CustomAttributeBuilder customBuilder)
 
263
                {
 
264
                        declarativeSecurity.Add(customBuilder);
 
265
                }
 
266
 
 
267
                public void __AddTypeForwarder(Type type)
 
268
                {
 
269
                        typeForwarders.Add(type);
 
270
                }
 
271
 
 
272
                public void SetEntryPoint(MethodInfo entryMethod)
 
273
                {
 
274
                        SetEntryPoint(entryMethod, PEFileKinds.ConsoleApplication);
 
275
                }
 
276
 
 
277
                public void SetEntryPoint(MethodInfo entryMethod, PEFileKinds fileKind)
 
278
                {
 
279
                        this.entryPoint = entryMethod;
 
280
                        this.fileKind = fileKind;
 
281
                }
 
282
 
 
283
                public void __Save(Stream stream, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
 
284
                {
 
285
                        if (!stream.CanRead || !stream.CanWrite || !stream.CanSeek || stream.Position != 0)
 
286
                        {
 
287
                                throw new ArgumentException("Stream must support read/write/seek and current position must be zero.", "stream");
 
288
                        }
 
289
                        if (modules.Count != 1)
 
290
                        {
 
291
                                throw new NotSupportedException("Saving to a stream is only supported for single module assemblies.");
 
292
                        }
 
293
                        SaveImpl(modules[0].fileName, stream, portableExecutableKind, imageFileMachine);
 
294
                }
 
295
 
 
296
                public void Save(string assemblyFileName)
 
297
                {
 
298
                        Save(assemblyFileName, PortableExecutableKinds.ILOnly, ImageFileMachine.I386);
 
299
                }
 
300
 
 
301
                public void Save(string assemblyFileName, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
 
302
                {
 
303
                        SaveImpl(assemblyFileName, null, portableExecutableKind, imageFileMachine);
 
304
                }
 
305
 
 
306
                private void SaveImpl(string assemblyFileName, Stream streamOrNull, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
 
307
                {
 
308
                        ModuleBuilder manifestModule = null;
 
309
 
 
310
                        foreach (ModuleBuilder moduleBuilder in modules)
 
311
                        {
 
312
                                moduleBuilder.SetIsSaved();
 
313
                                moduleBuilder.PopulatePropertyAndEventTables();
 
314
 
 
315
                                if (manifestModule == null
 
316
                                        && string.Compare(moduleBuilder.fileName, assemblyFileName, StringComparison.OrdinalIgnoreCase) == 0)
 
317
                                {
 
318
                                        manifestModule = moduleBuilder;
 
319
                                }
 
320
                        }
 
321
 
 
322
                        if (manifestModule == null)
 
323
                        {
 
324
                                manifestModule = DefineDynamicModule("RefEmit_OnDiskManifestModule", assemblyFileName, false);
 
325
                        }
 
326
 
 
327
                        AssemblyTable.Record assemblyRecord = new AssemblyTable.Record();
 
328
                        assemblyRecord.HashAlgId = (int)hashAlgorithm;
 
329
                        assemblyRecord.Name = manifestModule.Strings.Add(name);
 
330
                        assemblyRecord.MajorVersion = majorVersion;
 
331
                        assemblyRecord.MinorVersion = minorVersion;
 
332
                        assemblyRecord.BuildNumber = buildVersion;
 
333
                        assemblyRecord.RevisionNumber = revisionVersion;
 
334
                        if (publicKey != null)
 
335
                        {
 
336
                                assemblyRecord.PublicKey = manifestModule.Blobs.Add(ByteBuffer.Wrap(publicKey));
 
337
                                assemblyRecord.Flags = (int)(flags | AssemblyNameFlags.PublicKey);
 
338
                        }
 
339
                        else
 
340
                        {
 
341
                                assemblyRecord.Flags = (int)(flags & ~AssemblyNameFlags.PublicKey);
 
342
                        }
 
343
                        if (culture != null)
 
344
                        {
 
345
                                assemblyRecord.Culture = manifestModule.Strings.Add(culture);
 
346
                        }
 
347
                        int token = 0x20000000 + manifestModule.AssemblyTable.AddRecord(assemblyRecord);
 
348
 
 
349
#pragma warning disable 618
 
350
                        // this values are obsolete, but we already know that so we disable the warning
 
351
                        System.Security.Permissions.SecurityAction requestMinimum = System.Security.Permissions.SecurityAction.RequestMinimum;
 
352
                        System.Security.Permissions.SecurityAction requestOptional = System.Security.Permissions.SecurityAction.RequestOptional;
 
353
                        System.Security.Permissions.SecurityAction requestRefuse = System.Security.Permissions.SecurityAction.RequestRefuse;
 
354
#pragma warning restore 618
 
355
                        if (requiredPermissions != null)
 
356
                        {
 
357
                                manifestModule.AddDeclarativeSecurity(token, requestMinimum, requiredPermissions);
 
358
                        }
 
359
                        if (optionalPermissions != null)
 
360
                        {
 
361
                                manifestModule.AddDeclarativeSecurity(token, requestOptional, optionalPermissions);
 
362
                        }
 
363
                        if (refusedPermissions != null)
 
364
                        {
 
365
                                manifestModule.AddDeclarativeSecurity(token, requestRefuse, refusedPermissions);
 
366
                        }
 
367
 
 
368
                        ResourceSection unmanagedResources = versionInfo != null || win32icon != null || win32manifest != null || win32resources != null
 
369
                                ? new ResourceSection()
 
370
                                : null;
 
371
 
 
372
                        if (versionInfo != null)
 
373
                        {
 
374
                                versionInfo.SetName(GetName());
 
375
                                versionInfo.SetFileName(assemblyFileName);
 
376
                                foreach (CustomAttributeBuilder cab in customAttributes)
 
377
                                {
 
378
                                        // .NET doesn't support copying blob custom attributes into the version info
 
379
                                        if (!cab.HasBlob)
 
380
                                        {
 
381
                                                versionInfo.SetAttribute(cab);
 
382
                                        }
 
383
                                }
 
384
                                ByteBuffer versionInfoData = new ByteBuffer(512);
 
385
                                versionInfo.Write(versionInfoData);
 
386
                                unmanagedResources.AddVersionInfo(versionInfoData);
 
387
                        }
 
388
 
 
389
                        if (win32icon != null)
 
390
                        {
 
391
                                unmanagedResources.AddIcon(win32icon);
 
392
                        }
 
393
 
 
394
                        if (win32manifest != null)
 
395
                        {
 
396
                                unmanagedResources.AddManifest(win32manifest, fileKind == PEFileKinds.Dll ? (ushort)2 : (ushort)1);
 
397
                        }
 
398
 
 
399
                        if (win32resources != null)
 
400
                        {
 
401
                                unmanagedResources.ExtractResources(win32resources);
 
402
                        }
 
403
 
 
404
                        foreach (CustomAttributeBuilder cab in customAttributes)
 
405
                        {
 
406
                                // we intentionally don't filter out the version info (pseudo) custom attributes (to be compatible with .NET)
 
407
                                manifestModule.SetCustomAttribute(0x20000001, cab);
 
408
                        }
 
409
 
 
410
                        manifestModule.AddDeclarativeSecurity(0x20000001, declarativeSecurity);
 
411
 
 
412
                        foreach (Type type in typeForwarders)
 
413
                        {
 
414
                                manifestModule.AddTypeForwarder(type);
 
415
                        }
 
416
 
 
417
                        foreach (ResourceFile resfile in resourceFiles)
 
418
                        {
 
419
                                if (resfile.Writer != null)
 
420
                                {
 
421
                                        resfile.Writer.Generate();
 
422
                                        resfile.Writer.Close();
 
423
                                }
 
424
                                int fileToken = AddFile(manifestModule, resfile.FileName, 1 /*ContainsNoMetaData*/);
 
425
                                ManifestResourceTable.Record rec = new ManifestResourceTable.Record();
 
426
                                rec.Offset = 0;
 
427
                                rec.Flags = (int)resfile.Attributes;
 
428
                                rec.Name = manifestModule.Strings.Add(resfile.Name);
 
429
                                rec.Implementation = fileToken;
 
430
                                manifestModule.ManifestResource.AddRecord(rec);
 
431
                        }
 
432
 
 
433
                        int entryPointToken = 0;
 
434
 
 
435
                        foreach (ModuleBuilder moduleBuilder in modules)
 
436
                        {
 
437
                                moduleBuilder.FillAssemblyRefTable();
 
438
                                moduleBuilder.EmitResources();
 
439
                                if (moduleBuilder != manifestModule)
 
440
                                {
 
441
                                        int fileToken;
 
442
                                        if (entryPoint != null && entryPoint.Module == moduleBuilder)
 
443
                                        {
 
444
                                                ModuleWriter.WriteModule(null, null, moduleBuilder, fileKind, portableExecutableKind, imageFileMachine, moduleBuilder.unmanagedResources, entryPoint.MetadataToken);
 
445
                                                entryPointToken = fileToken = AddFile(manifestModule, moduleBuilder.fileName, 0 /*ContainsMetaData*/);
 
446
                                        }
 
447
                                        else
 
448
                                        {
 
449
                                                ModuleWriter.WriteModule(null, null, moduleBuilder, fileKind, portableExecutableKind, imageFileMachine, moduleBuilder.unmanagedResources, 0);
 
450
                                                fileToken = AddFile(manifestModule, moduleBuilder.fileName, 0 /*ContainsMetaData*/);
 
451
                                        }
 
452
                                        moduleBuilder.ExportTypes(fileToken, manifestModule);
 
453
                                }
 
454
                        }
 
455
 
 
456
                        foreach (Module module in addedModules)
 
457
                        {
 
458
                                int fileToken = AddFile(manifestModule, module.FullyQualifiedName, 0 /*ContainsMetaData*/);
 
459
                                module.ExportTypes(fileToken, manifestModule);
 
460
                        }
 
461
 
 
462
                        if (entryPointToken == 0 && entryPoint != null)
 
463
                        {
 
464
                                entryPointToken = entryPoint.MetadataToken;
 
465
                        }
 
466
 
 
467
                        // finally, write the manifest module
 
468
                        ModuleWriter.WriteModule(keyPair, publicKey, manifestModule, fileKind, portableExecutableKind, imageFileMachine, unmanagedResources ?? manifestModule.unmanagedResources, entryPointToken, streamOrNull);
 
469
                }
 
470
 
 
471
                private int AddFile(ModuleBuilder manifestModule, string fileName, int flags)
 
472
                {
 
473
                        SHA1Managed hash = new SHA1Managed();
 
474
                        string fullPath = fileName;
 
475
                        if (dir != null)
 
476
                        {
 
477
                                fullPath = Path.Combine(dir, fileName);
 
478
                        }
 
479
                        using (FileStream fs = new FileStream(fullPath, FileMode.Open, FileAccess.Read))
 
480
                        {
 
481
                                using (CryptoStream cs = new CryptoStream(Stream.Null, hash, CryptoStreamMode.Write))
 
482
                                {
 
483
                                        byte[] buf = new byte[8192];
 
484
                                        ModuleWriter.HashChunk(fs, cs, buf, (int)fs.Length);
 
485
                                }
 
486
                        }
 
487
                        return manifestModule.__AddModule(flags, Path.GetFileName(fileName), hash.Hash);
 
488
                }
 
489
 
 
490
                public void AddResourceFile(string name, string fileName)
 
491
                {
 
492
                        AddResourceFile(name, fileName, ResourceAttributes.Public);
 
493
                }
 
494
 
 
495
                public void AddResourceFile(string name, string fileName, ResourceAttributes attribs)
 
496
                {
 
497
                        ResourceFile resfile = new ResourceFile();
 
498
                        resfile.Name = name;
 
499
                        resfile.FileName = fileName;
 
500
                        resfile.Attributes = attribs;
 
501
                        resourceFiles.Add(resfile);
 
502
                }
 
503
 
 
504
                public IResourceWriter DefineResource(string name, string description, string fileName)
 
505
                {
 
506
                        return DefineResource(name, description, fileName, ResourceAttributes.Public);
 
507
                }
 
508
 
 
509
                public IResourceWriter DefineResource(string name, string description, string fileName, ResourceAttributes attribute)
 
510
                {
 
511
                        // FXBUG we ignore the description, because there is no such thing
 
512
 
 
513
                        string fullPath = fileName;
 
514
                        if (dir != null)
 
515
                        {
 
516
                                fullPath = Path.Combine(dir, fileName);
 
517
                        }
 
518
                        ResourceWriter rw = new ResourceWriter(fullPath);
 
519
                        ResourceFile resfile;
 
520
                        resfile.Name = name;
 
521
                        resfile.FileName = fileName;
 
522
                        resfile.Attributes = attribute;
 
523
                        resfile.Writer = rw;
 
524
                        resourceFiles.Add(resfile);
 
525
                        return rw;
 
526
                }
 
527
 
 
528
                public void DefineVersionInfoResource()
 
529
                {
 
530
                        if (versionInfo != null || win32resources != null)
 
531
                        {
 
532
                                throw new ArgumentException("Native resource has already been defined.");
 
533
                        }
 
534
                        versionInfo = new VersionInfo();
 
535
                }
 
536
 
 
537
                public void DefineVersionInfoResource(string product, string productVersion, string company, string copyright, string trademark)
 
538
                {
 
539
                        if (versionInfo != null || win32resources != null)
 
540
                        {
 
541
                                throw new ArgumentException("Native resource has already been defined.");
 
542
                        }
 
543
                        versionInfo = new VersionInfo();
 
544
                        versionInfo.product = product;
 
545
                        versionInfo.informationalVersion = productVersion;
 
546
                        versionInfo.company = company;
 
547
                        versionInfo.copyright = copyright;
 
548
                        versionInfo.trademark = trademark;
 
549
                }
 
550
 
 
551
                public void __DefineIconResource(byte[] iconFile)
 
552
                {
 
553
                        if (win32icon != null || win32resources != null)
 
554
                        {
 
555
                                throw new ArgumentException("Native resource has already been defined.");
 
556
                        }
 
557
                        win32icon = (byte[])iconFile.Clone();
 
558
                }
 
559
 
 
560
                public void __DefineManifestResource(byte[] manifest)
 
561
                {
 
562
                        if (win32manifest != null || win32resources != null)
 
563
                        {
 
564
                                throw new ArgumentException("Native resource has already been defined.");
 
565
                        }
 
566
                        win32manifest = (byte[])manifest.Clone();
 
567
                }
 
568
 
 
569
                public void __DefineUnmanagedResource(byte[] resource)
 
570
                {
 
571
                        if (versionInfo != null || win32icon != null || win32manifest != null || win32resources != null)
 
572
                        {
 
573
                                throw new ArgumentException("Native resource has already been defined.");
 
574
                        }
 
575
                        // The standard .NET DefineUnmanagedResource(byte[]) is useless, because it embeds "resource" (as-is) as the .rsrc section,
 
576
                        // but it doesn't set the PE file Resource Directory entry to point to it. That's why we have a renamed version, which behaves
 
577
                        // like DefineUnmanagedResource(string).
 
578
                        win32resources = (byte[])resource.Clone();
 
579
                }
 
580
 
 
581
                public void DefineUnmanagedResource(string resourceFileName)
 
582
                {
 
583
                        // This method reads the specified resource file (Win32 .res file) and converts it into the appropriate format and embeds it in the .rsrc section,
 
584
                        // also setting the Resource Directory entry.
 
585
                        __DefineUnmanagedResource(File.ReadAllBytes(resourceFileName));
 
586
                }
 
587
 
 
588
                public override Type[] GetTypes()
 
589
                {
 
590
                        List<Type> list = new List<Type>();
 
591
                        foreach (ModuleBuilder module in modules)
 
592
                        {
 
593
                                module.GetTypesImpl(list);
 
594
                        }
 
595
                        foreach (Module module in addedModules)
 
596
                        {
 
597
                                module.GetTypesImpl(list);
 
598
                        }
 
599
                        return list.ToArray();
 
600
                }
 
601
 
 
602
                internal override Type FindType(TypeName typeName)
 
603
                {
 
604
                        foreach (ModuleBuilder mb in modules)
 
605
                        {
 
606
                                Type type = mb.FindType(typeName);
 
607
                                if (type != null)
 
608
                                {
 
609
                                        return type;
 
610
                                }
 
611
                        }
 
612
                        foreach (Module module in addedModules)
 
613
                        {
 
614
                                Type type = module.FindType(typeName);
 
615
                                if (type != null)
 
616
                                {
 
617
                                        return type;
 
618
                                }
 
619
                        }
 
620
                        return null;
 
621
                }
 
622
 
 
623
                internal override Type FindTypeIgnoreCase(TypeName lowerCaseName)
 
624
                {
 
625
                        foreach (ModuleBuilder mb in modules)
 
626
                        {
 
627
                                Type type = mb.FindTypeIgnoreCase(lowerCaseName);
 
628
                                if (type != null)
 
629
                                {
 
630
                                        return type;
 
631
                                }
 
632
                        }
 
633
                        foreach (Module module in addedModules)
 
634
                        {
 
635
                                Type type = module.FindTypeIgnoreCase(lowerCaseName);
 
636
                                if (type != null)
 
637
                                {
 
638
                                        return type;
 
639
                                }
 
640
                        }
 
641
                        return null;
 
642
                }
 
643
 
 
644
                public override string ImageRuntimeVersion
 
645
                {
 
646
                        get { return imageRuntimeVersion; }
 
647
                }
 
648
 
 
649
                public void __SetImageRuntimeVersion(string imageRuntimeVersion, int mdStreamVersion)
 
650
                {
 
651
                        this.imageRuntimeVersion = imageRuntimeVersion;
 
652
                        this.mdStreamVersion = mdStreamVersion;
 
653
                }
 
654
 
 
655
                public override Module ManifestModule
 
656
                {
 
657
                        get
 
658
                        {
 
659
                                if (pseudoManifestModule == null)
 
660
                                {
 
661
                                        pseudoManifestModule = new ManifestModule(this);
 
662
                                }
 
663
                                return pseudoManifestModule;
 
664
                        }
 
665
                }
 
666
 
 
667
                public override MethodInfo EntryPoint
 
668
                {
 
669
                        get { return entryPoint; }
 
670
                }
 
671
 
 
672
                public override AssemblyName[] GetReferencedAssemblies()
 
673
                {
 
674
                        return Empty<AssemblyName>.Array;
 
675
                }
 
676
 
 
677
                public override Module[] GetLoadedModules(bool getResourceModules)
 
678
                {
 
679
                        return GetModules(getResourceModules);
 
680
                }
 
681
 
 
682
                public override Module[] GetModules(bool getResourceModules)
 
683
                {
 
684
                        List<Module> list = new List<Module>();
 
685
                        foreach (ModuleBuilder module in modules)
 
686
                        {
 
687
                                if (getResourceModules || !module.IsResource())
 
688
                                {
 
689
                                        list.Add(module);
 
690
                                }
 
691
                        }
 
692
                        foreach (Module module in addedModules)
 
693
                        {
 
694
                                if (getResourceModules || !module.IsResource())
 
695
                                {
 
696
                                        list.Add(module);
 
697
                                }
 
698
                        }
 
699
                        return list.ToArray();
 
700
                }
 
701
 
 
702
                public override Module GetModule(string name)
 
703
                {
 
704
                        foreach (ModuleBuilder module in modules)
 
705
                        {
 
706
                                if (module.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase))
 
707
                                {
 
708
                                        return module;
 
709
                                }
 
710
                        }
 
711
                        foreach (Module module in addedModules)
 
712
                        {
 
713
                                if (module.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase))
 
714
                                {
 
715
                                        return module;
 
716
                                }
 
717
                        }
 
718
                        return null;
 
719
                }
 
720
 
 
721
                public Module __AddModule(RawModule module)
 
722
                {
 
723
                        Module mod = module.ToModule(this);
 
724
                        addedModules.Add(mod);
 
725
                        return mod;
 
726
                }
 
727
 
 
728
                public override ManifestResourceInfo GetManifestResourceInfo(string resourceName)
 
729
                {
 
730
                        throw new NotSupportedException();
 
731
                }
 
732
 
 
733
                public override string[] GetManifestResourceNames()
 
734
                {
 
735
                        throw new NotSupportedException();
 
736
                }
 
737
 
 
738
                public override Stream GetManifestResourceStream(string resourceName)
 
739
                {
 
740
                        throw new NotSupportedException();
 
741
                }
 
742
 
 
743
                public override bool IsDynamic
 
744
                {
 
745
                        get { return true; }
 
746
                }
 
747
 
 
748
                internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
 
749
                {
 
750
                        List<CustomAttributeData> list = new List<CustomAttributeData>();
 
751
                        foreach (CustomAttributeBuilder cab in customAttributes)
 
752
                        {
 
753
                                if (attributeType == null || attributeType.IsAssignableFrom(cab.Constructor.DeclaringType))
 
754
                                {
 
755
                                        list.Add(cab.ToData(this));
 
756
                                }
 
757
                        }
 
758
                        return list;
 
759
                }
 
760
 
 
761
                internal bool IsWindowsRuntime
 
762
                {
 
763
                        get { return (flags & (AssemblyNameFlags)0x200) != 0; }
 
764
                }
 
765
        }
 
766
 
 
767
        sealed class ManifestModule : NonPEModule
 
768
        {
 
769
                private readonly AssemblyBuilder assembly;
 
770
                private readonly Guid guid = Guid.NewGuid();
 
771
 
 
772
                internal ManifestModule(AssemblyBuilder assembly)
 
773
                        : base(assembly.universe)
 
774
                {
 
775
                        this.assembly = assembly;
 
776
                }
 
777
 
 
778
                public override int MDStreamVersion
 
779
                {
 
780
                        get { return assembly.mdStreamVersion; }
 
781
                }
 
782
 
 
783
                public override Assembly Assembly
 
784
                {
 
785
                        get { return assembly; }
 
786
                }
 
787
 
 
788
                internal override Type FindType(TypeName typeName)
 
789
                {
 
790
                        return null;
 
791
                }
 
792
 
 
793
                internal override Type FindTypeIgnoreCase(TypeName lowerCaseName)
 
794
                {
 
795
                        return null;
 
796
                }
 
797
 
 
798
                internal override void  GetTypesImpl(List<Type> list)
 
799
                {
 
800
                }
 
801
 
 
802
                public override string FullyQualifiedName
 
803
                {
 
804
                        get { return Path.Combine(assembly.dir, "RefEmit_InMemoryManifestModule"); }
 
805
                }
 
806
 
 
807
                public override string Name
 
808
                {
 
809
                        get { return "<In Memory Module>"; }
 
810
                }
 
811
 
 
812
                public override Guid ModuleVersionId
 
813
                {
 
814
                        get { return guid; }
 
815
                }
 
816
 
 
817
                public override string ScopeName
 
818
                {
 
819
                        get { return "RefEmit_InMemoryManifestModule"; }
 
820
                }
 
821
 
 
822
                protected override Exception NotSupportedException()
 
823
                {
 
824
                        return new InvalidOperationException();
 
825
                }
 
826
        }
 
827
}