Represents a metadata storage stream header in a .NET assembly image.
Inheritance: FileSegment
示例#1
0
        internal static MetadataHeader FromReadingContext(ReadingContext context)
        {
            var reader = context.Reader;

            var header = new MetadataHeader
            {
                StartOffset = reader.Position,

                Signature     = reader.ReadUInt32(),
                MajorVersion  = reader.ReadUInt16(),
                MinorVersion  = reader.ReadUInt16(),
                Reserved      = reader.ReadUInt32(),
                VersionLength = reader.ReadUInt32(),
            };

            header.VersionString = Encoding.ASCII.GetString(reader.ReadBytes((int)header.VersionLength));
            header.Flags         = reader.ReadUInt16();
            var streamCount = reader.ReadUInt16();

            for (int i = 0; i < streamCount; i++)
            {
                var streamHeader = MetadataStreamHeader.FromReadingContext(context);
                header.StreamHeaders.Add(streamHeader);
            }

            return(header);
        }
示例#2
0
        public IDictionary <IMetadataMember, MetadataToken> UnlockMetadata()
        {
            if (!IsLocked)
            {
                throw new InvalidOperationException("Cannot unlock the metadata if it has not already been locked.");
            }

            var image  = Image;
            var buffer = new MetadataBuffer(image);

            // Add assembly to buffer.
            buffer.TableStreamBuffer.AddAssembly(image.Assembly);

            // Create resources.
            NetDirectory.ResourcesManifest = buffer.ResourcesBuffer.CreateDirectory();

            // Unlock metadata.
            Image = null;

            // Replace old streams with new buffers.
            var buffers = new MetadataStreamBuffer[]
            {
                buffer.TableStreamBuffer,
                buffer.BlobStreamBuffer,
                buffer.GuidStreamBuffer,
                buffer.StringStreamBuffer,
                buffer.UserStringStreamBuffer
            };

            foreach (var streamBuffer in buffers)
            {
                var header = StreamHeaders.FirstOrDefault(x => x.Name == streamBuffer.Name);

                if (header == null)
                {
                    header = new MetadataStreamHeader(streamBuffer.Name);
                    StreamHeaders.Add(header);
                }

                header.Stream = streamBuffer.CreateStream();
            }

            // Update managed entrypoint.
            var newTokenMapping = buffer.TableStreamBuffer.GetNewTokenMapping();

            NetDirectory.EntryPointToken = image.ManagedEntrypoint != null
                ? newTokenMapping[image.ManagedEntrypoint].ToUInt32()
                : 0u;

            return(newTokenMapping);
        }
示例#3
0
        internal static MetadataStreamHeader FromReadingContext(ReadingContext context)
        {
            var reader = context.Reader;

            var header = new MetadataStreamHeader
            {
                _readingContext = context,

                StartOffset = reader.Position,

                Offset = reader.ReadUInt32(),
                Size   = reader.ReadUInt32(),
                Name   = reader.ReadAlignedAsciiString(4),
            };

            return(header);
        }
示例#4
0
        internal static MetadataStreamHeader FromReadingContext(ReadingContext context)
        {
            var reader = context.Reader;

            var header = new MetadataStreamHeader
            {
                StartOffset = reader.Position,

                Offset = reader.ReadUInt32(),
                Size   = reader.ReadUInt32(),
                Name   = reader.ReadAlignedAsciiString(4),
            };

            header._stream = new LazyValue <MetadataStream>(() =>
            {
                var mdHeader = context.Assembly.NetDirectory.MetadataHeader;
                var stream   = mdHeader.StreamParser.ReadStream(header.Name,
                                                                context.CreateSubContext(mdHeader.StartOffset + header.Offset, (int)header.Size));
                stream.StreamHeader = header;
                return(stream);
            });

            return(header);
        }
示例#5
0
        public IDictionary <IMetadataMember, MetadataToken> UnlockMetadata(IMetadataBuilder builder)
        {
            if (!IsLocked)
            {
                throw new InvalidOperationException("Cannot unlock the metadata if it has not already been locked.");
            }

            var image = Image;

            // Construct new metadata streams.
            var buffer = builder.Rebuild(image);

            // Create resources.
            NetDirectory.ResourcesManifest = buffer.ResourcesBuffer.CreateDirectory();

            // Serialize new streams.
            var newStreams = new MetadataStreamBuffer[]
            {
                buffer.TableStreamBuffer,
                buffer.BlobStreamBuffer,
                buffer.GuidStreamBuffer,
                buffer.StringStreamBuffer,
                buffer.UserStringStreamBuffer
            }.ToDictionary(x => x, x => x.CreateStream());

            // Determine new entrypoint token.
            var  newTokenMapping = buffer.TableStreamBuffer.GetNewTokenMapping();
            uint entrypointToken;

            if (image.ManagedEntrypoint == null)
            {
                entrypointToken = 0u;
            }
            else
            {
                if (newTokenMapping.TryGetValue(image.ManagedEntrypoint, out var token))
                {
                    entrypointToken = token.ToUInt32();
                }
                else
                {
                    throw new MemberNotImportedException(image.ManagedEntrypoint);
                }
            }

            // Unlock metadata, commit changes to streams.
            Image = null;
            foreach (var entry in newStreams)
            {
                var header = StreamHeaders.FirstOrDefault(x => x.Name == entry.Key.Name);

                if (header == null)
                {
                    header = new MetadataStreamHeader(entry.Key.Name);
                    StreamHeaders.Add(header);
                }

                header.Stream = entry.Value;
            }

            // Update managed entrypoint.
            NetDirectory.EntryPointToken = entrypointToken;
            return(newTokenMapping);
        }
        internal static MetadataStreamHeader FromReadingContext(ReadingContext context)
        {
            var reader = context.Reader;

            var header = new MetadataStreamHeader
            {
                _readingContext = context,

                StartOffset = reader.Position,

                Offset = reader.ReadUInt32(),
                Size = reader.ReadUInt32(),
                Name = reader.ReadAlignedAsciiString(4),

            };

            return header;
        }