internal Table(byte[] gptBuffer, uint bytesPerSector) { this.gptBuffer = gptBuffer; var tempHeaderOffset = ByteOperations.FindAscii(gptBuffer, "EFI PART"); if (tempHeaderOffset == null) { throw new Exception("Bad GPT"); } headerOffset = (uint)tempHeaderOffset; headerSize = ByteOperations.ReadUInt32(gptBuffer, headerOffset + 0x0C); tableOffset = headerOffset + 0x200; FirstUsableSector = ByteOperations.ReadUInt64(gptBuffer, headerOffset + 0x28); LastUsableSector = ByteOperations.ReadUInt64(gptBuffer, headerOffset + 0x30); var maxPartitions = ByteOperations.ReadUInt32(gptBuffer, headerOffset + 0x50); partitionEntrySize = ByteOperations.ReadUInt32(gptBuffer, headerOffset + 0x54); tableSize = maxPartitions * partitionEntrySize; if (tableOffset + tableSize > gptBuffer.Length) { throw new Exception("Bad GPT"); } var partitionOffset = tableOffset; uint number = 1; while (partitionOffset < tableOffset + tableSize) { var name = ByteOperations.ReadUnicodeString(gptBuffer, partitionOffset + 0x38, 0x48) .TrimEnd((char)0, ' '); if (name.Length == 0) { break; } var partitionTypeGuid = ByteOperations.ReadGuid(gptBuffer, partitionOffset + 0x00); var partitionType = GptType.FromGuid(partitionTypeGuid); var currentPartition = new Partition(name, partitionType, bytesPerSector) { FirstSector = ByteOperations.ReadUInt64(gptBuffer, partitionOffset + 0x20), LastSector = ByteOperations.ReadUInt64(gptBuffer, partitionOffset + 0x28), Guid = ByteOperations.ReadGuid(gptBuffer, partitionOffset + 0x10), Attributes = ByteOperations.ReadUInt64(gptBuffer, partitionOffset + 0x30) }; Partitions.Add(currentPartition); partitionOffset += partitionEntrySize; number++; } }
internal byte[] Rebuild() { Log.Debug("Rebuilding GPT..."); if (gptBuffer == null) { tableSize = 0x4200; tableOffset = 0; gptBuffer = new byte[tableSize]; } else { Array.Clear(gptBuffer, (int)tableOffset, (int)tableSize); } var partitionOffset = tableOffset; foreach (var currentPartition in Partitions) { ByteOperations.WriteGuid(gptBuffer, partitionOffset + 0x00, currentPartition.GptType.Guid); ByteOperations.WriteGuid(gptBuffer, partitionOffset + 0x10, currentPartition.Guid); ByteOperations.WriteUInt64(gptBuffer, partitionOffset + 0x20, currentPartition.FirstSector); ByteOperations.WriteUInt64(gptBuffer, partitionOffset + 0x28, currentPartition.LastSector); ByteOperations.WriteUInt64(gptBuffer, partitionOffset + 0x30, currentPartition.Attributes); ByteOperations.WriteUnicodeString(gptBuffer, partitionOffset + 0x38, currentPartition.Name, 0x48); partitionOffset += partitionEntrySize; } ByteOperations.WriteUInt32(gptBuffer, headerOffset + 0x58, ByteOperations.Crc32(gptBuffer, tableOffset, tableSize)); ByteOperations.WriteUInt32(gptBuffer, headerOffset + 0x10, 0); ByteOperations.WriteUInt32(gptBuffer, headerOffset + 0x10, ByteOperations.Crc32(gptBuffer, headerOffset, headerSize)); Log.Debug("GPT rebuilt"); return(gptBuffer); }