private int GetPartitionOffset(int index)
        {
            bool found        = false;
            int  entriesSoFar = 0;
            int  position     = 0;

            while (!found && position < _primaryHeader.PartitionEntryCount)
            {
                GptEntry entry = new GptEntry();
                entry.ReadFrom(_entryBuffer, position * _primaryHeader.PartitionEntrySize);
                if (entry.PartitionType != Guid.Empty)
                {
                    if (index == entriesSoFar)
                    {
                        found = true;
                        break;
                    }

                    entriesSoFar++;
                }

                position++;
            }

            if (found)
            {
                return(position * _primaryHeader.PartitionEntrySize);
            }
            throw new IOException(string.Format(CultureInfo.InvariantCulture, "No such partition: {0}", index));
        }
 private IEnumerable <GptEntry> GetAllEntries()
 {
     for (int i = 0; i < _primaryHeader.PartitionEntryCount; ++i)
     {
         GptEntry entry = new GptEntry();
         entry.ReadFrom(_entryBuffer, i * _primaryHeader.PartitionEntrySize);
         if (entry.PartitionType != Guid.Empty)
         {
             yield return(entry);
         }
     }
 }
        private int GetFreeEntryOffset()
        {
            for (int i = 0; i < _primaryHeader.PartitionEntryCount; ++i)
            {
                GptEntry entry = new GptEntry();
                entry.ReadFrom(_entryBuffer, i * _primaryHeader.PartitionEntrySize);

                if (entry.PartitionType == Guid.Empty)
                {
                    return(i * _primaryHeader.PartitionEntrySize);
                }
            }

            throw new IOException("No free partition entries available");
        }
        /// <summary>
        /// Makes a best guess at the geometry of a disk.
        /// </summary>
        /// <param name="disk">String containing the disk image to detect the geometry from.</param>
        /// <returns>The detected geometry.</returns>
        public static Geometry DetectGeometry(Stream disk)
        {
            if (disk.Length >= Sizes.Sector)
            {
                disk.Position = 0;
                byte[] bootSector = StreamUtilities.ReadExact(disk, Sizes.Sector);
                if (bootSector[510] == 0x55 && bootSector[511] == 0xAA)
                {
                    long lastSector = 0;

                    disk.Position = Sizes.Sector;
                    var sector = StreamUtilities.ReadExact(disk, Sizes.Sector);
                    var header = new GptHeader(Sizes.Sector);
                    if (!header.ReadFrom(sector, 0))
                    {
                        throw new InvalidDataException("Failed to read primary GPT header");
                    }

                    disk.Position = header.PartitionEntriesLba * Sizes.Sector;
                    var entryBuffer = StreamUtilities.ReadExact(disk,
                                                                (int)(header.PartitionEntrySize * header.PartitionEntryCount));

                    if (header.EntriesCrc != Crc32LittleEndian.Compute(Crc32Algorithm.Common,
                                                                       entryBuffer, 0, entryBuffer.Length))
                    {
                        throw new InvalidDataException("Invalid GPT header");
                    }

                    for (int i = 0; i < header.PartitionEntryCount; ++i)
                    {
                        GptEntry entry = new GptEntry();
                        entry.ReadFrom(entryBuffer, i * header.PartitionEntrySize);

                        if (entry.PartitionType != Guid.Empty)
                        {
                            lastSector = entry.LastUsedLogicalBlock + 1;
                        }
                    }

                    if (lastSector > 0)
                    {
                        return(Geometry.FromCapacity(lastSector * Sizes.Sector, Sizes.Sector));
                    }
                }
            }

            return(Geometry.FromCapacity(disk.Length));
        }
        private int GetEntryIndex(Guid identity)
        {
            int index = 0;

            for (int i = 0; i < _primaryHeader.PartitionEntryCount; ++i)
            {
                GptEntry entry = new GptEntry();
                entry.ReadFrom(_entryBuffer, i * _primaryHeader.PartitionEntrySize);

                if (entry.Identity == identity)
                {
                    return(index);
                }
                if (entry.PartitionType != Guid.Empty)
                {
                    index++;
                }
            }

            throw new IOException("No such partition");
        }