~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric

« back to all changes in this revision

Viewing changes to contrib/Mono.Cecil/Mono.Cecil/Mono.Cecil.Binary/ImageReader.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2011-06-27 17:03:13 UTC
  • mto: (1.8.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 54.
  • Revision ID: james.westby@ubuntu.com-20110627170313-6cvz3s19x6e9hqe9
ImportĀ upstreamĀ versionĀ 2.5.92+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//
2
 
// ImageReader.cs
3
 
//
4
 
// Author:
5
 
//   Jb Evain (jbevain@gmail.com)
6
 
//
7
 
// (C) 2005 - 2007 Jb Evain
8
 
//
9
 
// Permission is hereby granted, free of charge, to any person obtaining
10
 
// a copy of this software and associated documentation files (the
11
 
// "Software"), to deal in the Software without restriction, including
12
 
// without limitation the rights to use, copy, modify, merge, publish,
13
 
// distribute, sublicense, and/or sell copies of the Software, and to
14
 
// permit persons to whom the Software is furnished to do so, subject to
15
 
// the following conditions:
16
 
//
17
 
// The above copyright notice and this permission notice shall be
18
 
// included in all copies or substantial portions of the Software.
19
 
//
20
 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
 
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
 
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23
 
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24
 
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25
 
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26
 
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
 
//
28
 
 
29
 
namespace Mono.Cecil.Binary {
30
 
 
31
 
        using System;
32
 
        using System.IO;
33
 
        using System.Text;
34
 
 
35
 
        using Mono.Cecil.Metadata;
36
 
 
37
 
        sealed class ImageReader : BaseImageVisitor {
38
 
 
39
 
                MetadataReader m_mdReader;
40
 
                BinaryReader m_binaryReader;
41
 
                Image m_image;
42
 
 
43
 
                public MetadataReader MetadataReader {
44
 
                        get { return m_mdReader; }
45
 
                }
46
 
 
47
 
                public Image Image {
48
 
                        get { return m_image; }
49
 
                }
50
 
 
51
 
                ImageReader (Image img, BinaryReader reader)
52
 
                {
53
 
                        m_image = img;
54
 
                        m_binaryReader = reader;
55
 
                }
56
 
 
57
 
                static ImageReader Read (Image img, Stream stream)
58
 
                {
59
 
                        ImageReader reader = new ImageReader (img, new BinaryReader (stream));
60
 
                        img.Accept (reader);
61
 
                        return reader;
62
 
                }
63
 
 
64
 
                public static ImageReader Read (string file)
65
 
                {
66
 
                        if (file == null)
67
 
                                throw new ArgumentNullException ("file");
68
 
 
69
 
                        FileInfo fi = new FileInfo (file);
70
 
                        if (!File.Exists (fi.FullName))
71
 
                        #if CF_1_0 || CF_2_0
72
 
                                throw new FileNotFoundException (fi.FullName);
73
 
                        #else
74
 
                                throw new FileNotFoundException (string.Format ("File '{0}' not found.", fi.FullName), fi.FullName);
75
 
                        #endif
76
 
 
77
 
                        FileStream stream = null;
78
 
                        try {
79
 
                                stream = new FileStream (fi.FullName, FileMode.Open, FileAccess.Read, FileShare.Read);
80
 
                                return Read (new Image (fi), stream);
81
 
                        } catch (Exception e) {
82
 
                                if (stream != null)
83
 
                                        stream.Close ();
84
 
#if CF_1_0 || CF_2_0
85
 
                                throw new BadImageFormatException ("Invalid PE file: " + file, e);
86
 
#else
87
 
                                throw new BadImageFormatException ("Invalid PE file", file, e);
88
 
#endif
89
 
                        }
90
 
                }
91
 
 
92
 
                public static ImageReader Read (byte [] image)
93
 
                {
94
 
                        if (image == null)
95
 
                                throw new ArgumentNullException ("image");
96
 
 
97
 
                        if (image.Length == 0)
98
 
                                throw new ArgumentException ("Empty image array");
99
 
 
100
 
                        return Read (new Image (), new MemoryStream (image));
101
 
                }
102
 
 
103
 
                public static ImageReader Read (Stream stream)
104
 
                {
105
 
                        if (stream == null)
106
 
                                throw new ArgumentNullException ("stream");
107
 
 
108
 
                        if (!stream.CanRead)
109
 
                                throw new ArgumentException ("Can not read from stream");
110
 
 
111
 
                        return Read (new Image (), stream);
112
 
                }
113
 
 
114
 
                public BinaryReader GetReader ()
115
 
                {
116
 
                        return m_binaryReader;
117
 
                }
118
 
 
119
 
                public override void VisitImage (Image img)
120
 
                {
121
 
                        m_mdReader = new MetadataReader (this);
122
 
                }
123
 
 
124
 
                void SetPositionToAddress (RVA address)
125
 
                {
126
 
                        m_binaryReader.BaseStream.Position = m_image.ResolveVirtualAddress (address);
127
 
                }
128
 
 
129
 
                public override void VisitDOSHeader (DOSHeader header)
130
 
                {
131
 
                        header.Start = m_binaryReader.ReadBytes (60);
132
 
                        header.Lfanew = m_binaryReader.ReadUInt32 ();
133
 
                        header.End = m_binaryReader.ReadBytes (64);
134
 
 
135
 
                        m_binaryReader.BaseStream.Position = header.Lfanew;
136
 
 
137
 
                        if (m_binaryReader.ReadUInt16 () != 0x4550 ||
138
 
                                m_binaryReader.ReadUInt16 () != 0)
139
 
 
140
 
                                throw new ImageFormatException ("Invalid PE File Signature");
141
 
                }
142
 
 
143
 
                public override void VisitPEFileHeader (PEFileHeader header)
144
 
                {
145
 
                        header.Machine = m_binaryReader.ReadUInt16 ();
146
 
                        header.NumberOfSections = m_binaryReader.ReadUInt16 ();
147
 
                        header.TimeDateStamp = m_binaryReader.ReadUInt32 ();
148
 
                        header.PointerToSymbolTable = m_binaryReader.ReadUInt32 ();
149
 
                        header.NumberOfSymbols = m_binaryReader.ReadUInt32 ();
150
 
                        header.OptionalHeaderSize = m_binaryReader.ReadUInt16 ();
151
 
                        header.Characteristics = (ImageCharacteristics) m_binaryReader.ReadUInt16 ();
152
 
                }
153
 
 
154
 
                ulong ReadIntOrLong ()
155
 
                {
156
 
                        return m_image.PEOptionalHeader.StandardFields.IsPE64 ?
157
 
                                m_binaryReader.ReadUInt64 () :
158
 
                                m_binaryReader.ReadUInt32 ();
159
 
                }
160
 
 
161
 
                RVA ReadRVA ()
162
 
                {
163
 
                        return m_binaryReader.ReadUInt32 ();
164
 
                }
165
 
 
166
 
                DataDirectory ReadDataDirectory ()
167
 
                {
168
 
                        return new DataDirectory (ReadRVA (), m_binaryReader.ReadUInt32 ());
169
 
                }
170
 
 
171
 
                public override void VisitNTSpecificFieldsHeader (PEOptionalHeader.NTSpecificFieldsHeader header)
172
 
                {
173
 
                        header.ImageBase = ReadIntOrLong ();
174
 
                        header.SectionAlignment = m_binaryReader.ReadUInt32 ();
175
 
                        header.FileAlignment = m_binaryReader.ReadUInt32 ();
176
 
                        header.OSMajor = m_binaryReader.ReadUInt16 ();
177
 
                        header.OSMinor = m_binaryReader.ReadUInt16 ();
178
 
                        header.UserMajor = m_binaryReader.ReadUInt16 ();
179
 
                        header.UserMinor = m_binaryReader.ReadUInt16 ();
180
 
                        header.SubSysMajor = m_binaryReader.ReadUInt16 ();
181
 
                        header.SubSysMinor = m_binaryReader.ReadUInt16 ();
182
 
                        header.Reserved = m_binaryReader.ReadUInt32 ();
183
 
                        header.ImageSize = m_binaryReader.ReadUInt32 ();
184
 
                        header.HeaderSize = m_binaryReader.ReadUInt32 ();
185
 
                        header.FileChecksum = m_binaryReader.ReadUInt32 ();
186
 
                        header.SubSystem = (SubSystem) m_binaryReader.ReadUInt16 ();
187
 
                        header.DLLFlags = m_binaryReader.ReadUInt16 ();
188
 
                        header.StackReserveSize = ReadIntOrLong ();
189
 
                        header.StackCommitSize = ReadIntOrLong ();
190
 
                        header.HeapReserveSize = ReadIntOrLong ();
191
 
                        header.HeapCommitSize = ReadIntOrLong ();
192
 
                        header.LoaderFlags = m_binaryReader.ReadUInt32 ();
193
 
                        header.NumberOfDataDir = m_binaryReader.ReadUInt32 ();
194
 
                }
195
 
 
196
 
                public override void VisitStandardFieldsHeader (PEOptionalHeader.StandardFieldsHeader header)
197
 
                {
198
 
                        header.Magic = m_binaryReader.ReadUInt16 ();
199
 
                        header.LMajor = m_binaryReader.ReadByte ();
200
 
                        header.LMinor = m_binaryReader.ReadByte ();
201
 
                        header.CodeSize = m_binaryReader.ReadUInt32 ();
202
 
                        header.InitializedDataSize = m_binaryReader.ReadUInt32 ();
203
 
                        header.UninitializedDataSize = m_binaryReader.ReadUInt32 ();
204
 
                        header.EntryPointRVA = ReadRVA ();
205
 
                        header.BaseOfCode = ReadRVA ();
206
 
                        if (!header.IsPE64)
207
 
                                header.BaseOfData = ReadRVA ();
208
 
                }
209
 
 
210
 
                public override void VisitDataDirectoriesHeader (PEOptionalHeader.DataDirectoriesHeader header)
211
 
                {
212
 
                        header.ExportTable = ReadDataDirectory ();
213
 
                        header.ImportTable = ReadDataDirectory ();
214
 
                        header.ResourceTable = ReadDataDirectory ();
215
 
                        header.ExceptionTable = ReadDataDirectory ();
216
 
                        header.CertificateTable = ReadDataDirectory ();
217
 
                        header.BaseRelocationTable = ReadDataDirectory ();
218
 
                        header.Debug = ReadDataDirectory ();
219
 
                        header.Copyright = ReadDataDirectory ();
220
 
                        header.GlobalPtr = ReadDataDirectory ();
221
 
                        header.TLSTable = ReadDataDirectory ();
222
 
                        header.LoadConfigTable = ReadDataDirectory ();
223
 
                        header.BoundImport = ReadDataDirectory ();
224
 
                        header.IAT = ReadDataDirectory ();
225
 
                        header.DelayImportDescriptor = ReadDataDirectory ();
226
 
                        header.CLIHeader = ReadDataDirectory ();
227
 
                        header.Reserved = ReadDataDirectory ();
228
 
 
229
 
                        if (header.CLIHeader != DataDirectory.Zero)
230
 
                                m_image.CLIHeader = new CLIHeader ();
231
 
                        if (header.ExportTable != DataDirectory.Zero)
232
 
                                m_image.ExportTable = new ExportTable ();
233
 
                }
234
 
 
235
 
                public override void VisitSectionCollection (SectionCollection coll)
236
 
                {
237
 
                        for (int i = 0; i < m_image.PEFileHeader.NumberOfSections; i++)
238
 
                                coll.Add (new Section ());
239
 
                }
240
 
 
241
 
                public override void VisitSection (Section sect)
242
 
                {
243
 
                        char [] buffer = new char [8];
244
 
                        int read = 0;
245
 
                        while (read < 8) {
246
 
                                char cur = (char) m_binaryReader.ReadSByte ();
247
 
                                if (cur == '\0') {
248
 
                                        m_binaryReader.BaseStream.Position += 8 - read - 1;
249
 
                                        break;
250
 
                                }
251
 
                                buffer [read++] = cur;
252
 
                        }
253
 
                        sect.Name = read == 0 ? string.Empty : new string (buffer, 0, read);
254
 
                        if (sect.Name == Section.Text)
255
 
                                m_image.TextSection = sect;
256
 
 
257
 
                        sect.VirtualSize = m_binaryReader.ReadUInt32 ();
258
 
                        sect.VirtualAddress = ReadRVA ();
259
 
                        sect.SizeOfRawData = m_binaryReader.ReadUInt32 ();
260
 
                        sect.PointerToRawData = ReadRVA ();
261
 
                        sect.PointerToRelocations = ReadRVA ();
262
 
                        sect.PointerToLineNumbers = ReadRVA ();
263
 
                        sect.NumberOfRelocations = m_binaryReader.ReadUInt16 ();
264
 
                        sect.NumberOfLineNumbers = m_binaryReader.ReadUInt16 ();
265
 
                        sect.Characteristics = (SectionCharacteristics) m_binaryReader.ReadUInt32 ();
266
 
 
267
 
                        long pos = m_binaryReader.BaseStream.Position;
268
 
                        m_binaryReader.BaseStream.Position = sect.PointerToRawData;
269
 
                        sect.Data = m_binaryReader.ReadBytes ((int) sect.SizeOfRawData);
270
 
                        m_binaryReader.BaseStream.Position = pos;
271
 
                }
272
 
 
273
 
                public override void VisitImportAddressTable (ImportAddressTable iat)
274
 
                {
275
 
                        if (m_image.PEOptionalHeader.DataDirectories.IAT.VirtualAddress == RVA.Zero)
276
 
                                return;
277
 
 
278
 
                        SetPositionToAddress (m_image.PEOptionalHeader.DataDirectories.IAT.VirtualAddress);
279
 
 
280
 
                        iat.HintNameTableRVA = ReadRVA ();
281
 
                }
282
 
 
283
 
                public override void VisitCLIHeader (CLIHeader header)
284
 
                {
285
 
                        if (m_image.PEOptionalHeader.DataDirectories.Debug != DataDirectory.Zero) {
286
 
                                m_image.DebugHeader = new DebugHeader ();
287
 
                                VisitDebugHeader (m_image.DebugHeader);
288
 
                        }
289
 
 
290
 
                        SetPositionToAddress (m_image.PEOptionalHeader.DataDirectories.CLIHeader.VirtualAddress);
291
 
                        header.Cb = m_binaryReader.ReadUInt32 ();
292
 
                        header.MajorRuntimeVersion = m_binaryReader.ReadUInt16 ();
293
 
                        header.MinorRuntimeVersion = m_binaryReader.ReadUInt16 ();
294
 
                        header.Metadata = ReadDataDirectory ();
295
 
                        header.Flags = (RuntimeImage) m_binaryReader.ReadUInt32 ();
296
 
                        header.EntryPointToken = m_binaryReader.ReadUInt32 ();
297
 
                        header.Resources = ReadDataDirectory ();
298
 
                        header.StrongNameSignature = ReadDataDirectory ();
299
 
                        header.CodeManagerTable = ReadDataDirectory ();
300
 
                        header.VTableFixups = ReadDataDirectory ();
301
 
                        header.ExportAddressTableJumps = ReadDataDirectory ();
302
 
                        header.ManagedNativeHeader = ReadDataDirectory ();
303
 
 
304
 
                        if (header.StrongNameSignature != DataDirectory.Zero) {
305
 
                                SetPositionToAddress (header.StrongNameSignature.VirtualAddress);
306
 
                                header.ImageHash = m_binaryReader.ReadBytes ((int) header.StrongNameSignature.Size);
307
 
                        } else
308
 
                                header.ImageHash = new byte [0];
309
 
 
310
 
                        SetPositionToAddress (m_image.CLIHeader.Metadata.VirtualAddress);
311
 
                        m_image.MetadataRoot.Accept (m_mdReader);
312
 
                }
313
 
 
314
 
                public override void VisitDebugHeader (DebugHeader header)
315
 
                {
316
 
                        if (m_image.PEOptionalHeader.DataDirectories.Debug == DataDirectory.Zero)
317
 
                                return;
318
 
 
319
 
                        long pos = m_binaryReader.BaseStream.Position;
320
 
 
321
 
                        SetPositionToAddress (m_image.PEOptionalHeader.DataDirectories.Debug.VirtualAddress);
322
 
                        header.Characteristics = m_binaryReader.ReadUInt32 ();
323
 
                        header.TimeDateStamp = m_binaryReader.ReadUInt32 ();
324
 
                        header.MajorVersion = m_binaryReader.ReadUInt16 ();
325
 
                        header.MinorVersion = m_binaryReader.ReadUInt16 ();
326
 
                        header.Type = (DebugStoreType) m_binaryReader.ReadUInt32 ();
327
 
                        header.SizeOfData = m_binaryReader.ReadUInt32 ();
328
 
                        header.AddressOfRawData = ReadRVA ();
329
 
                        header.PointerToRawData = m_binaryReader.ReadUInt32 ();
330
 
 
331
 
                        m_binaryReader.BaseStream.Position = header.PointerToRawData;
332
 
 
333
 
                        header.Magic = m_binaryReader.ReadUInt32 ();
334
 
                        header.Signature = new Guid (m_binaryReader.ReadBytes (16));
335
 
                        header.Age = m_binaryReader.ReadUInt32 ();
336
 
                        header.FileName = ReadZeroTerminatedString ();
337
 
 
338
 
                        m_binaryReader.BaseStream.Position = pos;
339
 
                }
340
 
 
341
 
                string ReadZeroTerminatedString ()
342
 
                {
343
 
                        StringBuilder sb = new StringBuilder ();
344
 
                        while (true) {
345
 
                                byte chr = m_binaryReader.ReadByte ();
346
 
                                if (chr == 0)
347
 
                                        break;
348
 
                                sb.Append ((char) chr);
349
 
                        }
350
 
                        return sb.ToString ();
351
 
                }
352
 
 
353
 
                public override void VisitImportTable (ImportTable it)
354
 
                {
355
 
                        if (m_image.PEOptionalHeader.DataDirectories.ImportTable.VirtualAddress == RVA.Zero)
356
 
                                return;
357
 
 
358
 
                        SetPositionToAddress (m_image.PEOptionalHeader.DataDirectories.ImportTable.VirtualAddress);
359
 
 
360
 
                        it.ImportLookupTable = ReadRVA ();
361
 
                        it.DateTimeStamp = m_binaryReader.ReadUInt32 ();
362
 
                        it.ForwardChain = m_binaryReader.ReadUInt32 ();
363
 
                        it.Name = ReadRVA ();
364
 
                        it.ImportAddressTable = ReadRVA ();
365
 
                }
366
 
 
367
 
                public override void VisitImportLookupTable (ImportLookupTable ilt)
368
 
                {
369
 
                        if (m_image.ImportTable.ImportLookupTable == RVA.Zero)
370
 
                                return;
371
 
 
372
 
                        SetPositionToAddress (m_image.ImportTable.ImportLookupTable);
373
 
 
374
 
                        ilt.HintNameRVA = ReadRVA ();
375
 
                }
376
 
 
377
 
                public override void VisitHintNameTable (HintNameTable hnt)
378
 
                {
379
 
                        if (m_image.ImportAddressTable.HintNameTableRVA == RVA.Zero)
380
 
                                return;
381
 
 
382
 
                        if ((m_image.ImportAddressTable.HintNameTableRVA & 0x80000000) != 0)
383
 
                                return;
384
 
 
385
 
                        SetPositionToAddress (m_image.ImportAddressTable.HintNameTableRVA);
386
 
 
387
 
                        hnt.Hint = m_binaryReader.ReadUInt16 ();
388
 
 
389
 
                        byte [] bytes = m_binaryReader.ReadBytes (11);
390
 
                        hnt.RuntimeMain = Encoding.ASCII.GetString (bytes, 0, bytes.Length);
391
 
 
392
 
                        SetPositionToAddress (m_image.ImportTable.Name);
393
 
 
394
 
                        bytes = m_binaryReader.ReadBytes (11);
395
 
                        hnt.RuntimeLibrary = Encoding.ASCII.GetString (bytes, 0, bytes.Length);
396
 
 
397
 
                        SetPositionToAddress (m_image.PEOptionalHeader.StandardFields.EntryPointRVA);
398
 
                        hnt.EntryPoint = m_binaryReader.ReadUInt16 ();
399
 
                        hnt.RVA = ReadRVA ();
400
 
                }
401
 
 
402
 
                public override void VisitExportTable (ExportTable et)
403
 
                {
404
 
                        SetPositionToAddress (m_image.PEOptionalHeader.DataDirectories.ExportTable.VirtualAddress);
405
 
 
406
 
                        et.Characteristics = m_binaryReader.ReadUInt32 ();
407
 
                        et.TimeDateStamp = m_binaryReader.ReadUInt32 ();
408
 
                        et.MajorVersion = m_binaryReader.ReadUInt16 ();
409
 
                        et.MinorVersion = m_binaryReader.ReadUInt16 ();
410
 
 
411
 
                        //et.Name =
412
 
                        m_binaryReader.ReadUInt32 ();
413
 
 
414
 
                        et.Base = m_binaryReader.ReadUInt32 ();
415
 
                        et.NumberOfFunctions = m_binaryReader.ReadUInt32 ();
416
 
                        et.NumberOfNames = m_binaryReader.ReadUInt32 ();
417
 
                        et.AddressOfFunctions = m_binaryReader.ReadUInt32 ();
418
 
                        et.AddressOfNames = m_binaryReader.ReadUInt32 ();
419
 
                        et.AddressOfNameOrdinals = m_binaryReader.ReadUInt32 ();
420
 
 
421
 
                        et.AddressesOfFunctions = ReadArrayOfRVA (et.AddressOfFunctions, et.NumberOfFunctions);
422
 
                        et.AddressesOfNames = ReadArrayOfRVA (et.AddressOfNames, et.NumberOfNames);
423
 
                        et.NameOrdinals = ReadArrayOfUInt16 (et.AddressOfNameOrdinals, et.NumberOfNames);
424
 
                        et.Names = new string [et.NumberOfFunctions];
425
 
 
426
 
                        for (int i = 0; i < et.NumberOfFunctions; i++) {
427
 
                                if (et.AddressesOfFunctions [i] == 0)
428
 
                                        continue;
429
 
 
430
 
                                et.Names [i] = ReadFunctionName (et, i);
431
 
                        }
432
 
                }
433
 
 
434
 
                string ReadFunctionName (ExportTable et, int index)
435
 
                {
436
 
                        for (int i = 0; i < et.NumberOfNames; i++) {
437
 
                                if (et.NameOrdinals [i] != index)
438
 
                                        continue;
439
 
 
440
 
                                SetPositionToAddress (et.AddressesOfNames [i]);
441
 
                                return ReadZeroTerminatedString ();
442
 
                        }
443
 
 
444
 
                        return string.Empty;
445
 
                }
446
 
 
447
 
                ushort [] ReadArrayOfUInt16 (RVA position, uint length)
448
 
                {
449
 
                        if (position == RVA.Zero)
450
 
                                return new ushort [0];
451
 
 
452
 
                        SetPositionToAddress (position);
453
 
                        ushort [] array = new ushort [length];
454
 
                        for (int i = 0; i < length; i++)
455
 
                                array [i] = m_binaryReader.ReadUInt16 ();
456
 
 
457
 
                        return array;
458
 
                }
459
 
 
460
 
                RVA [] ReadArrayOfRVA (RVA position, uint length)
461
 
                {
462
 
                        if (position == RVA.Zero)
463
 
                                return new RVA [0];
464
 
 
465
 
                        SetPositionToAddress (position);
466
 
                        RVA [] addresses = new RVA [length];
467
 
                        for (int i = 0; i < length; i++)
468
 
                                addresses [i] = m_binaryReader.ReadUInt32 ();
469
 
 
470
 
                        return addresses;
471
 
                }
472
 
 
473
 
                public override void TerminateImage(Image img)
474
 
                {
475
 
                        m_binaryReader.Close ();
476
 
 
477
 
                        try {
478
 
                                ResourceReader resReader = new ResourceReader (img);
479
 
                                img.ResourceDirectoryRoot = resReader.Read ();
480
 
                        } catch {
481
 
                                img.ResourceDirectoryRoot = null;
482
 
                        }
483
 
                }
484
 
        }
485
 
}