/// <inheritdoc/>
        protected override void InitializeInternal()
        {
            var hotHeapVersion = GetHotHeapVersion(peImage.FileName, mdHeader.VersionString);

            IImageStream     imageStream = null, fullStream = null;
            DotNetStream     dns        = null;
            List <HotStream> hotStreams = null;
            HotStream        hotStream  = null;
            var newAllStreams           = new List <DotNetStream>(allStreams);

            try {
                var mdRva = cor20Header.MetaData.VirtualAddress;
                for (int i = mdHeader.StreamHeaders.Count - 1; i >= 0; i--)
                {
                    var sh         = mdHeader.StreamHeaders[i];
                    var rva        = mdRva + sh.Offset;
                    var fileOffset = peImage.ToFileOffset(rva);
                    imageStream = peImage.CreateStream(fileOffset, sh.StreamSize);
                    switch (sh.Name)
                    {
                    case "#Strings":
                        if (stringsStream == null)
                        {
                            stringsStream = new StringsStream(imageStream, sh);
                            imageStream   = null;
                            newAllStreams.Add(stringsStream);
                            continue;
                        }
                        break;

                    case "#US":
                        if (usStream == null)
                        {
                            usStream    = new USStream(imageStream, sh);
                            imageStream = null;
                            newAllStreams.Add(usStream);
                            continue;
                        }
                        break;

                    case "#Blob":
                        if (blobStream == null)
                        {
                            blobStream  = new BlobStream(imageStream, sh);
                            imageStream = null;
                            newAllStreams.Add(blobStream);
                            continue;
                        }
                        break;

                    case "#GUID":
                        if (guidStream == null)
                        {
                            guidStream  = new GuidStream(imageStream, sh);
                            imageStream = null;
                            newAllStreams.Add(guidStream);
                            continue;
                        }
                        break;

                    case "#~":
                        if (tablesStream == null)
                        {
                            tablesStream = new TablesStream(imageStream, sh);
                            imageStream  = null;
                            newAllStreams.Add(tablesStream);
                            continue;
                        }
                        break;

                    case "#!":
                        if (hotStreams == null)
                        {
                            hotStreams = new List <HotStream>();
                        }
                        fullStream = peImage.CreateFullStream();
                        hotStream  = HotStream.Create(hotHeapVersion, imageStream, sh, fullStream, fileOffset);
                        fullStream = null;
                        hotStreams.Add(hotStream);
                        newAllStreams.Add(hotStream);
                        hotStream   = null;
                        imageStream = null;
                        continue;
                    }
                    dns         = new DotNetStream(imageStream, sh);
                    imageStream = null;
                    newAllStreams.Add(dns);
                    dns = null;
                }
            }
            finally {
                if (imageStream != null)
                {
                    imageStream.Dispose();
                }
                if (fullStream != null)
                {
                    fullStream.Dispose();
                }
                if (dns != null)
                {
                    dns.Dispose();
                }
                if (hotStream != null)
                {
                    hotStream.Dispose();
                }
                newAllStreams.Reverse();
                allStreams = ThreadSafeListCreator.MakeThreadSafe(newAllStreams);
            }

            if (tablesStream == null)
            {
                throw new BadImageFormatException("Missing MD stream");
            }

            if (hotStreams != null)
            {
                hotStreams.Reverse();
                InitializeHotStreams(hotStreams);
            }

            tablesStream.Initialize(peImage);
        }
Example #2
0
        /// <inheritdoc/>
        protected override void InitializeInternal(IImageStream mdStream)
        {
            var hotHeapVersion = peImage == null ? HotHeapVersion.CLR20 : GetHotHeapVersion(peImage.FileName, mdHeader.VersionString);

            bool             disposeOfMdStream = false;
            IImageStream     imageStream = null, fullStream = null;
            DotNetStream     dns = null;
            List <HotStream> hotStreams = null;
            HotStream        hotStream  = null;
            var newAllStreams = new List <DotNetStream>(allStreams);

            try {
                if (peImage != null)
                {
                    Debug.Assert(mdStream == null);
                    Debug.Assert(cor20Header != null);
                    var mdOffset = peImage.ToFileOffset(cor20Header.MetaData.VirtualAddress);
                    mdStream          = peImage.CreateStream(mdOffset, cor20Header.MetaData.Size);
                    disposeOfMdStream = true;
                }
                else
                {
                    Debug.Assert(mdStream != null);
                }
                for (int i = mdHeader.StreamHeaders.Count - 1; i >= 0; i--)
                {
                    var sh = mdHeader.StreamHeaders[i];
                    imageStream = mdStream.Create((FileOffset)sh.Offset, sh.StreamSize);
                    switch (sh.Name)
                    {
                    case "#Strings":
                        if (stringsStream == null)
                        {
                            stringsStream = new StringsStream(imageStream, sh);
                            imageStream   = null;
                            newAllStreams.Add(stringsStream);
                            continue;
                        }
                        break;

                    case "#US":
                        if (usStream == null)
                        {
                            usStream    = new USStream(imageStream, sh);
                            imageStream = null;
                            newAllStreams.Add(usStream);
                            continue;
                        }
                        break;

                    case "#Blob":
                        if (blobStream == null)
                        {
                            blobStream  = new BlobStream(imageStream, sh);
                            imageStream = null;
                            newAllStreams.Add(blobStream);
                            continue;
                        }
                        break;

                    case "#GUID":
                        if (guidStream == null)
                        {
                            guidStream  = new GuidStream(imageStream, sh);
                            imageStream = null;
                            newAllStreams.Add(guidStream);
                            continue;
                        }
                        break;

                    case "#~":
                        if (tablesStream == null)
                        {
                            tablesStream = new TablesStream(imageStream, sh);
                            imageStream  = null;
                            newAllStreams.Add(tablesStream);
                            continue;
                        }
                        break;

                    case "#!":
                        if (peImage == null)
                        {
                            break;
                        }
                        if (hotStreams == null)
                        {
                            hotStreams = new List <HotStream>();
                        }
                        fullStream = peImage.CreateFullStream();
                        hotStream  = HotStream.Create(hotHeapVersion, imageStream, sh, fullStream, mdStream.FileOffset + sh.Offset);
                        fullStream = null;
                        hotStreams.Add(hotStream);
                        newAllStreams.Add(hotStream);
                        hotStream   = null;
                        imageStream = null;
                        continue;

                    case "#Pdb":
                        if (isStandalonePortablePdb && pdbStream == null)
                        {
                            pdbStream   = new PdbStream(imageStream, sh);
                            imageStream = null;
                            allStreams.Add(pdbStream);
                            continue;
                        }
                        break;
                    }
                    dns         = new DotNetStream(imageStream, sh);
                    imageStream = null;
                    newAllStreams.Add(dns);
                    dns = null;
                }
            }
            finally {
                if (disposeOfMdStream)
                {
                    mdStream.Dispose();
                }
                if (imageStream != null)
                {
                    imageStream.Dispose();
                }
                if (fullStream != null)
                {
                    fullStream.Dispose();
                }
                if (dns != null)
                {
                    dns.Dispose();
                }
                if (hotStream != null)
                {
                    hotStream.Dispose();
                }
                newAllStreams.Reverse();
                allStreams = ThreadSafeListCreator.MakeThreadSafe(newAllStreams);
            }

            if (tablesStream == null)
            {
                throw new BadImageFormatException("Missing MD stream");
            }

            if (hotStreams != null)
            {
                hotStreams.Reverse();
                InitializeHotStreams(hotStreams);
            }

            if (pdbStream != null)
            {
                tablesStream.Initialize(pdbStream.TypeSystemTableRows);
            }
            else
            {
                tablesStream.Initialize(null);
            }
        }