/// <summary>
 /// Creates empty heap objects if they're not present in the metadata
 /// </summary>
 protected void InitializeNonExistentHeaps()
 {
     if (stringsStream is null)
     {
         stringsStream = new StringsStream();
     }
     if (usStream is null)
     {
         usStream = new USStream();
     }
     if (blobStream is null)
     {
         blobStream = new BlobStream();
     }
     if (guidStream is null)
     {
         guidStream = new GuidStream();
     }
 }
        /// <summary>
        /// Dispose method
        /// </summary>
        /// <param name="disposing"><c>true</c> if called by <see cref="Dispose()"/></param>
        protected virtual void Dispose(bool disposing)
        {
            if (!disposing)
            {
                return;
            }
            peImage?.Dispose();
            stringsStream?.Dispose();
            usStream?.Dispose();
            blobStream?.Dispose();
            guidStream?.Dispose();
            tablesStream?.Dispose();
            var as2 = allStreams;

            if (as2 is not null)
            {
                foreach (var stream in as2)
                {
                    stream?.Dispose();
                }
            }
            mdReaderFactoryToDisposeLater?.Dispose();
            peImage                       = null;
            cor20Header                   = null;
            mdHeader                      = null;
            stringsStream                 = null;
            usStream                      = null;
            blobStream                    = null;
            guidStream                    = null;
            tablesStream                  = null;
            allStreams                    = null;
            fieldRidToTypeDefRid          = null;
            methodRidToTypeDefRid         = null;
            typeDefRidToNestedClasses     = null;
            mdReaderFactoryToDisposeLater = null;
        }
        /// <inheritdoc/>
        protected override void InitializeInternal(DataReaderFactory mdReaderFactory, uint metadataBaseOffset)
        {
            DotNetStream dns           = null;
            var          newAllStreams = new List <DotNetStream>(allStreams);
            bool         forceAllBig   = false;

            try {
                for (int i = mdHeader.StreamHeaders.Count - 1; i >= 0; i--)
                {
                    var sh = mdHeader.StreamHeaders[i];
                    switch (sh.Name)
                    {
                    case "#Strings":
                        if (stringsStream is null)
                        {
                            stringsStream = new StringsStream(mdReaderFactory, metadataBaseOffset, sh);
                            newAllStreams.Add(stringsStream);
                            continue;
                        }
                        break;

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

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

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

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

                    case "#Pdb":
                        if (isStandalonePortablePdb && pdbStream is null)
                        {
                            pdbStream = new PdbStream(mdReaderFactory, metadataBaseOffset, sh);
                            newAllStreams.Add(pdbStream);
                            continue;
                        }
                        break;

                    case "#JTD":
                        if (runtime == CLRRuntimeReaderKind.Mono)
                        {
                            forceAllBig = true;
                            continue;
                        }
                        break;
                    }
                    dns = new CustomDotNetStream(mdReaderFactory, metadataBaseOffset, sh);
                    newAllStreams.Add(dns);
                    dns = null;
                }
            }
            finally {
                dns?.Dispose();
                newAllStreams.Reverse();
                allStreams = newAllStreams;
            }

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

            if (pdbStream is not null)
            {
                tablesStream.Initialize(pdbStream.TypeSystemTableRows, forceAllBig);
            }
            else
            {
                tablesStream.Initialize(null, forceAllBig);
            }
        }
Example #4
0
        /// <inheritdoc/>
        protected override void InitializeInternal(DataReaderFactory mdReaderFactory, uint metadataBaseOffset)
        {
            DotNetStream dns         = null;
            bool         forceAllBig = false;

            try {
                if (runtime == CLRRuntimeReaderKind.Mono)
                {
                    var newAllStreams = new List <DotNetStream>(allStreams);
                    for (int i = mdHeader.StreamHeaders.Count - 1; i >= 0; i--)
                    {
                        var sh = mdHeader.StreamHeaders[i];
                        switch (sh.Name)
                        {
                        case "#Strings":
                            if (stringsStream is null)
                            {
                                stringsStream = new StringsStream(mdReaderFactory, metadataBaseOffset, sh);
                                newAllStreams.Add(stringsStream);
                                continue;
                            }
                            break;

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

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

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

                        case "#~":
                        case "#-":
                            if (tablesStream is null)
                            {
                                tablesStream = new TablesStream(mdReaderFactory, metadataBaseOffset, sh, runtime);
                                newAllStreams.Add(tablesStream);
                                continue;
                            }
                            break;

                        case "#Pdb":
                            if (isStandalonePortablePdb && pdbStream is null)
                            {
                                pdbStream = new PdbStream(mdReaderFactory, metadataBaseOffset, sh);
                                newAllStreams.Add(pdbStream);
                                continue;
                            }
                            break;

                        case "#JTD":
                            forceAllBig = true;
                            continue;
                        }
                        dns = new CustomDotNetStream(mdReaderFactory, metadataBaseOffset, sh);
                        newAllStreams.Add(dns);
                        dns = null;
                    }
                    newAllStreams.Reverse();
                    allStreams = newAllStreams;
                }
                else
                {
                    Debug.Assert(runtime == CLRRuntimeReaderKind.CLR);
                    foreach (var sh in mdHeader.StreamHeaders)
                    {
                        switch (sh.Name.ToUpperInvariant())
                        {
                        case "#STRINGS":
                            if (stringsStream is null)
                            {
                                stringsStream = new StringsStream(mdReaderFactory, metadataBaseOffset, sh);
                                allStreams.Add(stringsStream);
                                continue;
                            }
                            break;

                        case "#US":
                            if (usStream is null)
                            {
                                usStream = new USStream(mdReaderFactory, metadataBaseOffset, sh);
                                allStreams.Add(usStream);
                                continue;
                            }
                            break;

                        case "#BLOB":
                            if (blobStream is null)
                            {
                                blobStream = new BlobStream(mdReaderFactory, metadataBaseOffset, sh);
                                allStreams.Add(blobStream);
                                continue;
                            }
                            break;

                        case "#GUID":
                            if (guidStream is null)
                            {
                                guidStream = new GuidStream(mdReaderFactory, metadataBaseOffset, sh);
                                allStreams.Add(guidStream);
                                continue;
                            }
                            break;

                        case "#~":                          // Only if #Schema is used
                        case "#-":
                            if (tablesStream is null)
                            {
                                tablesStream = new TablesStream(mdReaderFactory, metadataBaseOffset, sh, runtime);
                                allStreams.Add(tablesStream);
                                continue;
                            }
                            break;

                        case "#PDB":
                            // Case sensitive comparison since it's a stream that's not read by the CLR,
                            // only by other libraries eg. System.Reflection.Metadata.
                            if (isStandalonePortablePdb && pdbStream is null && sh.Name == "#Pdb")
                            {
                                pdbStream = new PdbStream(mdReaderFactory, metadataBaseOffset, sh);
                                allStreams.Add(pdbStream);
                                continue;
                            }
                            break;

                        case "#JTD":
                            forceAllBig = true;
                            continue;
                        }
                        dns = new CustomDotNetStream(mdReaderFactory, metadataBaseOffset, sh);
                        allStreams.Add(dns);
                        dns = null;
                    }
                }
            }
            finally {
                dns?.Dispose();
            }

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

            if (pdbStream is not null)
            {
                tablesStream.Initialize(pdbStream.TypeSystemTableRows, forceAllBig);
            }
            else
            {
                tablesStream.Initialize(null, forceAllBig);
            }

            // The pointer tables are used iff row count != 0
            hasFieldPtr    = !tablesStream.FieldPtrTable.IsEmpty;
            hasMethodPtr   = !tablesStream.MethodPtrTable.IsEmpty;
            hasParamPtr    = !tablesStream.ParamPtrTable.IsEmpty;
            hasEventPtr    = !tablesStream.EventPtrTable.IsEmpty;
            hasPropertyPtr = !tablesStream.PropertyPtrTable.IsEmpty;

            switch (runtime)
            {
            case CLRRuntimeReaderKind.CLR:
                hasDeletedFields    = tablesStream.HasDelete;
                hasDeletedNonFields = tablesStream.HasDelete;
                break;

            case CLRRuntimeReaderKind.Mono:
                hasDeletedFields    = true;
                hasDeletedNonFields = false;
                break;

            default:
                throw new InvalidOperationException();
            }
        }