/// <summary>
        ///
        /// </summary>
        /// <param name="table"></param>
        /// <param name="foreignKeyMetadata"></param>
        /// <returns></returns>
        private ForeignKeyInfo GetForeignKey(MetadataTableInfo table, ForeignKeyMetadata foreignKeyMetadata)
        {
            var foreignKey = new ForeignKeyInfo();

            foreignKey.Name   = foreignKeyMetadata.Name;
            foreignKey.Column = table.GetColumn(foreignKeyMetadata.Column.Name);
            foreignKey.Table  = table;

            foreignKey.ReferenceTable  = GetReferenceTable(foreignKeyMetadata);
            foreignKey.ReferenceColumn = GetReferenceColumn(foreignKey, foreignKeyMetadata);

            MigrateManager.CorrectName(foreignKey);
            return(foreignKey);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="tableMetadata"></param>
        /// <returns></returns>
        private MetadataTableInfo GetTableInfo(TableMetadata tableMetadata)
        {
            var databaseTablesManager = MigrateManager.ServicesContainer.GetService <IDatabaseTablesManager>();
            var tableInfo             = new MetadataTableInfo();

            tableInfo.TableMetadata = tableMetadata;
            tableInfo.Name          = tableMetadata.Name;
            tableInfo.Description   = tableMetadata.Decription;
            tableInfo.Schema        = tableMetadata.Schema ?? databaseTablesManager?.DefaultSchema;
            MigrateManager.CorrectName(tableInfo);

            tableInfo.Columns     = GetColumns(tableInfo, tableMetadata);
            tableInfo.PrimaryKey  = GetPrimaryKey(tableInfo, tableMetadata);
            tableInfo.TableValues = GetTableValues(tableInfo, tableMetadata);

            return(tableInfo);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="tableInfo"></param>
        /// <param name="tableMetadata"></param>
        /// <returns></returns>
        private PrimaryKeyInfo GetPrimaryKey(MetadataTableInfo tableInfo, TableMetadata tableMetadata)
        {
            var primaryKeyMetadata = tableMetadata.PrimaryKey;

            if (primaryKeyMetadata == null)
            {
                return(null);
            }

            var primaryKey = new PrimaryKeyInfo();

            primaryKey.Table         = tableInfo;
            primaryKey.Name          = primaryKeyMetadata.Name;
            primaryKey.PrimaryColumn = tableInfo.GetColumn(primaryKeyMetadata.PrimaryColumn?.Name);

            MigrateManager.CorrectName(primaryKey);
            return(primaryKey);
        }
Beispiel #4
0
        /// <summary>
        /// Modifies a CLI assembly produced by <see cref="AssemblyBuilder"/>
        /// to make it a portable class library (huge hack!).
        /// </summary>
        /// <param name="stream">A read-write stream to the CLI assembly to be modified.</param>
        public static void PatchReflectionEmitAssembly(Stream stream)
        {
            Contract.Requires(stream != null);
            Contract.Requires(stream.CanRead && stream.CanWrite && stream.CanSeek);

            // Read the DOS header
            var dosHeader = stream.ReadStruct <IMAGE_DOS_HEADER>();

            if (dosHeader.e_magic != IMAGE_DOS_HEADER.IMAGE_DOS_SIGNATURE)
            {
                throw new InvalidDataException("Invalid DOS header.");
            }

            // Read the NT header
            stream.Position = dosHeader.e_lfanew;
            var ntHeadersSignature = stream.ReadStruct <uint>();

            if (ntHeadersSignature != IMAGE_NT_HEADERS.IMAGE_NT_SIGNATURE)
            {
                throw new InvalidDataException("Invalid NT header.");
            }

            // Read the file header
            var fileHeader = stream.ReadStruct <IMAGE_FILE_HEADER>();

            // Read the optional header
            long optionalHeaderPosition = stream.Position;
            var  optionalHeaderMagic    = stream.ReadStruct <ushort>();

            if (optionalHeaderMagic != IMAGE_OPTIONAL_HEADER32.IMAGE_NT_OPTIONAL_HDR_MAGIC)
            {
                throw new InvalidDataException("Unsupported non-32 bit NT optional header.");
            }

            stream.Position = optionalHeaderPosition;
            var optionalHeader = stream.ReadStruct <IMAGE_OPTIONAL_HEADER32>();

            Contract.Assert(optionalHeader.MajorOperatingSystemVersion == 4);
            Contract.Assert(optionalHeader.NumberOfRvaAndSizes == IMAGE_OPTIONAL_HEADER.IMAGE_NUMBEROF_DIRECTORY_ENTRIES);
            Contract.Assert(optionalHeader.Subsystem == 3);

            // Read the section headers
            var sectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections];

            for (int i = 0; i < sectionHeaders.Length; ++i)
            {
                sectionHeaders[i] = stream.ReadStruct <IMAGE_SECTION_HEADER>();
            }

            // Read the CLR header
            var comDescriptorVirtualAddress = optionalHeader.DataDirectory[IMAGE_DATA_DIRECTORY.IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress;

            stream.Position = VirtualAddressToFilePosition(comDescriptorVirtualAddress, sectionHeaders);
            var cor20Header = stream.ReadStruct <IMAGE_COR20_HEADER>();

            // Read the metadata header
            var metadataHeaderVirtualAddress = cor20Header.MetaData.VirtualAddress;
            var metadataHeaderPosition       = VirtualAddressToFilePosition(metadataHeaderVirtualAddress, sectionHeaders);

            stream.Position = metadataHeaderPosition;
            var metadataRootPart1 = stream.ReadStruct <MetadataRoot_BeforeVersion>();

            if (metadataRootPart1.Signature != MetadataRoot_BeforeVersion.StandardSignature)
            {
                throw new InvalidDataException("Invalid metadata root signature.");
            }

            string metadataVersionString = stream.ReadNullPaddedString((metadataRootPart1.Length + 3U) & ~3U);
            var    metadataRootPart2     = stream.ReadStruct <MetadataRoot_AfterVersion>();

            // Read the stream headers
            var metadataStreamHeaders = new Dictionary <string, StreamHeader>(StringComparer.Ordinal);

            for (int i = 0; i < metadataRootPart2.Streams; ++i)
            {
                var metadataStreamHeader = stream.ReadStruct <StreamHeader>();
                var metadataStreamName   = stream.ReadPaddedNullTerminatedString(4);
                metadataStreamHeaders.Add(metadataStreamName, metadataStreamHeader);
            }

            // Read the metadata table stream header
            stream.Position = metadataHeaderPosition + metadataStreamHeaders["#~"].Offset;
            var metadataTablesStreamHeader = stream.ReadStruct <MetadataTablesStreamHeader>();

            if (metadataTablesStreamHeader.MajorVersion != 2 || metadataTablesStreamHeader.MinorVersion != 0)
            {
                throw new InvalidDataException("Unsupported metadata tables stream version.");
            }

            var metadataTableInfos = new MetadataTableInfo[64];

            for (int i = 0; i < metadataTableInfos.Length; ++i)
            {
                if ((metadataTablesStreamHeader.Valid & (1UL << i)) != 0)
                {
                    metadataTableInfos[i].RowCount = stream.ReadStruct <uint>();
                }
            }

            var metadataTablesStartPosition = stream.Position;

            // Compute the size of the metadata rows and their offset
            uint stringIndexSize = (metadataTablesStreamHeader.HeapSizes & 0x01) == 0 ? 2U : 4U;
            uint blobIndexSize   = (metadataTablesStreamHeader.HeapSizes & 0x04) == 0 ? 2U : 4U;

            FillMetadataTableInfos(ref metadataTablesStreamHeader, metadataTableInfos);

            // Read the assembly reference tables
            var assemblyReferenceTableInfo = metadataTableInfos[(int)Table.AssemblyReference];

            stream.Position = metadataTablesStartPosition + assemblyReferenceTableInfo.Offset;
            for (uint i = 0; i < assemblyReferenceTableInfo.RowCount; ++i)
            {
                var    rowPosition           = stream.Position;
                ushort majorVersion          = stream.ReadStruct <ushort>();
                ushort minorVersion          = stream.ReadStruct <ushort>();
                ushort buildNumber           = stream.ReadStruct <ushort>();
                ushort revisionNumber        = stream.ReadStruct <ushort>();
                var    version               = new Version(majorVersion, minorVersion, buildNumber, revisionNumber);
                uint   flags                 = stream.ReadStruct <uint>();
                uint   publicKeyOrTokenIndex = blobIndexSize == 2 ? stream.ReadStruct <ushort>() : stream.ReadStruct <uint>();
                uint   nameIndex             = stringIndexSize == 2 ? stream.ReadStruct <ushort>() : stream.ReadStruct <uint>();
                uint   cultureIndex          = stringIndexSize == 2 ? stream.ReadStruct <ushort>() : stream.ReadStruct <uint>();
                uint   hashValueIndex        = stringIndexSize == 2 ? stream.ReadStruct <ushort>() : stream.ReadStruct <uint>();

                var nextRowPosition = stream.Position;
                if (version == nonportableMscorlibVersion && flags == nonportableMscorlibFlags)
                {
                    // Looks like mscorlib, let's make sure
                    long nameStringPosition    = metadataHeaderPosition + metadataStreamHeaders["#Strings"].Offset + nameIndex;
                    long publicKeyBlobPosition = metadataHeaderPosition + metadataStreamHeaders["#Blob"].Offset + publicKeyOrTokenIndex;

                    stream.Position = nameStringPosition;
                    var name = stream.ReadPaddedNullTerminatedString(1);
                    stream.Position = publicKeyBlobPosition;
                    var publicKeyBlob = stream.ReadBytes(nonportableMscorlibPublicKeyBlob.Length);
                    if (name == "mscorlib" && Equals(publicKeyBlob, nonportableMscorlibPublicKeyBlob))
                    {
                        // It is indeed the mscorlib we want to patch!
                        // Patch the version number and assembly flags
                        stream.Position = rowPosition;
                        stream.WriteStruct((ushort)portableMscorlibVersion.Major);
                        stream.WriteStruct((ushort)portableMscorlibVersion.Minor);
                        stream.WriteStruct((ushort)portableMscorlibVersion.Build);
                        stream.WriteStruct((ushort)portableMscorlibVersion.Revision);
                        stream.WriteStruct <uint>(portableMscorlibFlags);

                        // Update the public key token
                        stream.Position = publicKeyBlobPosition;
                        stream.Write(portableMscorlibPublicKeyBlob, 0, portableMscorlibPublicKeyBlob.Length);

                        // Done!
                        return;
                    }
                    else
                    {
                        stream.Position = nextRowPosition;
                    }
                }
            }

            throw new InvalidDataException("mscorlib assembly reference not found.");
        }
Beispiel #5
0
        protected override void DoRun()
        {
            using (DiskImageFile vhdxFile = new DiskImageFile(_vhdxFile.Value, FileAccess.Read))
            {
                DiskImageFileInfo info = vhdxFile.Information;

                FileInfo fileInfo = new FileInfo(_vhdxFile.Value);

                Console.WriteLine("File Info");
                Console.WriteLine("---------");
                Console.WriteLine("           File Name: {0}", fileInfo.FullName);
                Console.WriteLine("           File Size: {0} ({1} bytes)", Utilities.ApproximateDiskSize(fileInfo.Length), fileInfo.Length);
                Console.WriteLine("  File Creation Time: {0} (UTC)", fileInfo.CreationTimeUtc);
                Console.WriteLine("     File Write Time: {0} (UTC)", fileInfo.LastWriteTimeUtc);
                Console.WriteLine();

                Console.WriteLine("VHDX File Info");
                Console.WriteLine("--------------");
                Console.WriteLine("           Signature: {0:x8}", info.Signature);
                Console.WriteLine("             Creator: {0:x8}", info.Creator);
                Console.WriteLine("          Block Size: {0} (0x{0:X8})", info.BlockSize);
                Console.WriteLine("Leave Blocks Alloced: {0}", info.LeaveBlocksAllocated);
                Console.WriteLine("          Has Parent: {0}", info.HasParent);
                Console.WriteLine("           Disk Size: {0} ({1} (0x{1:X8}))", Utilities.ApproximateDiskSize(info.DiskSize), info.DiskSize);
                Console.WriteLine(" Logical Sector Size: {0} (0x{0:X8})", info.LogicalSectorSize);
                Console.WriteLine("Physical Sector Size: {0} (0x{0:X8})", info.PhysicalSectorSize);
                Console.WriteLine(" Parent Locator Type: {0}", info.ParentLocatorType);
                WriteParentLocations(info);
                Console.WriteLine();

                WriteHeaderInfo(info.FirstHeader);
                WriteHeaderInfo(info.SecondHeader);

                if (info.ActiveHeader.LogGuid != Guid.Empty)
                {
                    Console.WriteLine("Log Info (Active Sequence)");
                    Console.WriteLine("--------------------------");

                    foreach (var entry in info.ActiveLogSequence)
                    {
                        Console.WriteLine("   Log Entry");
                        Console.WriteLine("   ---------");
                        Console.WriteLine("         Sequence Number: {0}", entry.SequenceNumber);
                        Console.WriteLine("                    Tail: {0}", entry.Tail);
                        Console.WriteLine("     Flushed File Offset: {0} (0x{0:X8})", entry.FlushedFileOffset);
                        Console.WriteLine("        Last File Offset: {0} (0x{0:X8})", entry.LastFileOffset);
                        Console.WriteLine("            File Extents: {0}", entry.IsEmpty ? "<none>" : "");
                        foreach (var extent in entry.ModifiedExtents)
                        {
                            Console.WriteLine("                          {0} +{1}  (0x{0:X8} +0x{1:X8})", extent.Offset, extent.Count);
                        }
                        Console.WriteLine();
                    }
                }

                RegionTableInfo regionTable = info.RegionTable;
                Console.WriteLine("Region Table Info");
                Console.WriteLine("-----------------");
                Console.WriteLine("           Signature: {0}", regionTable.Signature);
                Console.WriteLine("            Checksum: {0:x8}", regionTable.Checksum);
                Console.WriteLine("         Entry Count: {0}", regionTable.Count);
                Console.WriteLine();

                foreach (var entry in regionTable)
                {
                    Console.WriteLine("Region Table Entry Info");
                    Console.WriteLine("-----------------------");
                    Console.WriteLine("                Guid: {0}", entry.Guid);
                    Console.WriteLine("     Well-Known Name: {0}", entry.WellKnownName);
                    Console.WriteLine("         File Offset: {0} (0x{0:X8})", entry.FileOffset);
                    Console.WriteLine("              Length: {0} (0x{0:X8})", entry.Length);
                    Console.WriteLine("         Is Required: {0}", entry.IsRequired);
                    Console.WriteLine();
                }

                MetadataTableInfo metadataTable = info.MetadataTable;
                Console.WriteLine("Metadata Table Info");
                Console.WriteLine("-------------------");
                Console.WriteLine("           Signature: {0}", metadataTable.Signature);
                Console.WriteLine("         Entry Count: {0}", metadataTable.Count);
                Console.WriteLine();

                foreach (var entry in metadataTable)
                {
                    Console.WriteLine("Metadata Table Entry Info");
                    Console.WriteLine("-------------------------");
                    Console.WriteLine("             Item Id: {0}", entry.ItemId);
                    Console.WriteLine("     Well-Known Name: {0}", entry.WellKnownName);
                    Console.WriteLine("              Offset: {0} (0x{0:X8})", entry.Offset);
                    Console.WriteLine("              Length: {0} (0x{0:X8})", entry.Length);
                    Console.WriteLine("             Is User: {0}", entry.IsUser);
                    Console.WriteLine("         Is Required: {0}", entry.IsRequired);
                    Console.WriteLine("     Is Virtual Disk: {0}", entry.IsVirtualDisk);
                    Console.WriteLine();
                }
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="table"></param>
        /// <returns></returns>
        private List <ForeignKeyInfo> GetForeignKeys(MetadataTableInfo table)
        {
            var forignKeys = table.TableMetadata.ForeignKeys;

            return(forignKeys.Select(s => GetForeignKey(table, s)).ToList(w => w != null));
        }