internal GuidPartitionInfo(GuidPartitionTable table, GptEntry entry)
 {
     _table = table;
     _entry = entry;
 }
Esempio n. 2
0
        public bool GetInformation(IMediaImage imagePlugin, out List <Partition> partitions, ulong sectorOffset)
        {
            partitions = new List <Partition>();

            if (sectorOffset + 2 >= imagePlugin.Info.Sectors)
            {
                return(false);
            }

            byte[]    hdrBytes = imagePlugin.ReadSector(1 + sectorOffset);
            GptHeader hdr;

            ulong signature  = BitConverter.ToUInt64(hdrBytes, 0);
            bool  misaligned = false;

            DicConsole.DebugWriteLine("GPT Plugin", "hdr.signature = 0x{0:X16}", signature);

            if (signature != GPT_MAGIC)
            {
                if (imagePlugin.Info.XmlMediaType == XmlMediaType.OpticalDisc)
                {
                    hdrBytes  = imagePlugin.ReadSector(sectorOffset);
                    signature = BitConverter.ToUInt64(hdrBytes, 512);
                    DicConsole.DebugWriteLine("GPT Plugin", "hdr.signature @ 0x200 = 0x{0:X16}", signature);
                    if (signature == GPT_MAGIC)
                    {
                        DicConsole.DebugWriteLine("GPT Plugin", "Found unaligned signature", signature);
                        byte[] real = new byte[512];
                        Array.Copy(hdrBytes, 512, real, 0, 512);
                        hdrBytes   = real;
                        misaligned = true;
                    }
                    else
                    {
                        return(false);
                    }
                }
                else
                {
                    return(false);
                }
            }

            try
            {
                GCHandle handle = GCHandle.Alloc(hdrBytes, GCHandleType.Pinned);
                hdr = (GptHeader)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(GptHeader));
                handle.Free();
            }
            catch { return(false); }

            DicConsole.DebugWriteLine("GPT Plugin", "hdr.revision = 0x{0:X8}", hdr.revision);
            DicConsole.DebugWriteLine("GPT Plugin", "hdr.headerSize = {0}", hdr.headerSize);
            DicConsole.DebugWriteLine("GPT Plugin", "hdr.headerCrc = 0x{0:X8}", hdr.headerCrc);
            DicConsole.DebugWriteLine("GPT Plugin", "hdr.reserved = 0x{0:X8}", hdr.reserved);
            DicConsole.DebugWriteLine("GPT Plugin", "hdr.myLBA = {0}", hdr.myLBA);
            DicConsole.DebugWriteLine("GPT Plugin", "hdr.alternateLBA = {0}", hdr.alternateLBA);
            DicConsole.DebugWriteLine("GPT Plugin", "hdr.firstUsableLBA = {0}", hdr.firstUsableLBA);
            DicConsole.DebugWriteLine("GPT Plugin", "hdr.lastUsableLBA = {0}", hdr.lastUsableLBA);
            DicConsole.DebugWriteLine("GPT Plugin", "hdr.diskGuid = {0}", hdr.diskGuid);
            DicConsole.DebugWriteLine("GPT Plugin", "hdr.entryLBA = {0}", hdr.entryLBA);
            DicConsole.DebugWriteLine("GPT Plugin", "hdr.entries = {0}", hdr.entries);
            DicConsole.DebugWriteLine("GPT Plugin", "hdr.entriesSize = {0}", hdr.entriesSize);
            DicConsole.DebugWriteLine("GPT Plugin", "hdr.entriesCrc = 0x{0:X8}", hdr.entriesCrc);

            if (hdr.signature != GPT_MAGIC)
            {
                return(false);
            }

            if (hdr.myLBA != 1 + sectorOffset)
            {
                return(false);
            }

            uint divisor, modulo, sectorSize;

            if (misaligned)
            {
                divisor    = 4;
                modulo     = (uint)(hdr.entryLBA % divisor);
                sectorSize = 512;
            }
            else
            {
                divisor    = 1;
                modulo     = 0;
                sectorSize = imagePlugin.Info.SectorSize;
            }

            uint totalEntriesSectors = hdr.entries * hdr.entriesSize / imagePlugin.Info.SectorSize;

            if (hdr.entries * hdr.entriesSize % imagePlugin.Info.SectorSize > 0)
            {
                totalEntriesSectors++;
            }

            byte[] temp         = imagePlugin.ReadSectors(hdr.entryLBA / divisor, totalEntriesSectors + modulo);
            byte[] entriesBytes = new byte[temp.Length - modulo * 512];
            Array.Copy(temp, modulo * 512, entriesBytes, 0, entriesBytes.Length);
            List <GptEntry> entries = new List <GptEntry>();

            for (int i = 0; i < hdr.entries; i++)
            {
                try
                {
                    byte[] entryBytes = new byte[hdr.entriesSize];
                    Array.Copy(entriesBytes, hdr.entriesSize * i, entryBytes, 0, hdr.entriesSize);
                    GCHandle handle = GCHandle.Alloc(entryBytes, GCHandleType.Pinned);
                    GptEntry entry  = (GptEntry)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(GptEntry));
                    handle.Free();
                    entries.Add(entry);
                }
                #pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body
                catch
                {
                    // ignored
                }
                #pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body
            }

            if (entries.Count == 0)
            {
                return(false);
            }

            ulong pseq = 0;

            foreach (GptEntry entry in entries.Where(entry => entry.partitionType != Guid.Empty &&
                                                     entry.partitionId != Guid.Empty))
            {
                DicConsole.DebugWriteLine("GPT Plugin", "entry.partitionType = {0}", entry.partitionType);
                DicConsole.DebugWriteLine("GPT Plugin", "entry.partitionId = {0}", entry.partitionId);
                DicConsole.DebugWriteLine("GPT Plugin", "entry.startLBA = {0}", entry.startLBA);
                DicConsole.DebugWriteLine("GPT Plugin", "entry.endLBA = {0}", entry.endLBA);
                DicConsole.DebugWriteLine("GPT Plugin", "entry.attributes = 0x{0:X16}", entry.attributes);
                DicConsole.DebugWriteLine("GPT Plugin", "entry.name = {0}", entry.name);

                if (entry.startLBA / divisor > imagePlugin.Info.Sectors ||
                    entry.endLBA / divisor > imagePlugin.Info.Sectors)
                {
                    return(false);
                }

                Partition part = new Partition
                {
                    Description = $"ID: {entry.partitionId}",
                    Size        = (entry.endLBA - entry.startLBA + 1) * sectorSize,
                    Name        = entry.name,
                    Length      = (entry.endLBA - entry.startLBA + 1) / divisor,
                    Sequence    = pseq++,
                    Offset      = entry.startLBA * sectorSize,
                    Start       = entry.startLBA / divisor,
                    Type        = GetGuidTypeName(entry.partitionType),
                    Scheme      = Name
                };
                DicConsole.DebugWriteLine("GPT Plugin", "part.PartitionType = {0}", part.Type);
                partitions.Add(part);
            }

            return(true);
        }