123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330 |
- using System;
- using System.Collections.Generic;
- using System.Text;
- using DiskAccessLibrary;
- using Utilities;
- namespace DiskAccessLibrary.LogicalDiskManager
- {
- [Flags]
-
- public enum PrivateHeaderFlags : uint
- {
- Shared = 0x01,
- NoAutoImport = 0x02,
- }
- public class PrivateHeader
- {
- public const int Length = 512;
- public const int PrivateHeaderSectorIndex = 6;
- public const string PrivateHeaderSignature = "PRIVHEAD";
- public string Signature = PrivateHeaderSignature;
-
-
-
-
- public ushort MajorVersion;
- public ushort MinorVersion;
- public DateTime LastUpdateDT;
- public ulong UpdateSequenceNumber;
- public ulong PrimaryPrivateHeaderLBA;
- public ulong SecondaryPrivateHeaderLBA;
- public string DiskGuidString;
- public string HostGuidString;
- public string DiskGroupGuidString;
- public string DiskGroupName;
- public uint BytesPerSector;
- public PrivateHeaderFlags Flags;
- public ushort PublicRegionSliceNumber;
- public ushort PrivateRegionSliceNumber;
-
-
-
- public ulong PublicRegionStartLBA;
- public ulong PublicRegionSizeLBA;
- public ulong PrivateRegionStartLBA;
- public ulong PrivateRegionSizeLBA;
-
-
-
-
- public ulong PrimaryTocLBA;
- public ulong SecondaryTocLBA;
- public uint NumberOfConfigs;
- public uint NumberOfLogs;
- public ulong ConfigSizeLBA;
- public ulong LogSizeLBA;
- public uint DiskSignature;
- public Guid DiskSetGuid;
- public Guid DiskSetGuidRepeat;
- private bool m_isChecksumValid;
- public PrivateHeader(byte[] buffer)
- {
- Signature = ByteReader.ReadAnsiString(buffer, 0x00, 8);
- uint checksum = BigEndianConverter.ToUInt32(buffer, 0x08);
- MajorVersion = BigEndianConverter.ToUInt16(buffer, 0x0C);
- MinorVersion = BigEndianConverter.ToUInt16(buffer, 0x0E);
- LastUpdateDT = DateTime.FromFileTimeUtc(BigEndianConverter.ToInt64(buffer, 0x10));
- UpdateSequenceNumber = BigEndianConverter.ToUInt64(buffer, 0x18);
- PrimaryPrivateHeaderLBA = BigEndianConverter.ToUInt64(buffer, 0x20);
- SecondaryPrivateHeaderLBA = BigEndianConverter.ToUInt64(buffer, 0x28);
- DiskGuidString = ByteReader.ReadAnsiString(buffer, 0x30, 0x40).Trim('\0');
- HostGuidString = ByteReader.ReadAnsiString(buffer, 0x70, 0x40).Trim('\0');
- DiskGroupGuidString = ByteReader.ReadAnsiString(buffer, 0xB0, 0x40).Trim('\0');
- DiskGroupName = ByteReader.ReadAnsiString(buffer, 0xF0, 31).Trim('\0');
- BytesPerSector = BigEndianConverter.ToUInt32(buffer, 0x10F);
- Flags = (PrivateHeaderFlags)BigEndianConverter.ToUInt32(buffer, 0x113);
- PublicRegionSliceNumber = BigEndianConverter.ToUInt16(buffer, 0x117);
- PrivateRegionSliceNumber = BigEndianConverter.ToUInt16(buffer, 0x119);
- PublicRegionStartLBA = BigEndianConverter.ToUInt64(buffer, 0x11B);
- PublicRegionSizeLBA = BigEndianConverter.ToUInt64(buffer, 0x123);
- PrivateRegionStartLBA = BigEndianConverter.ToUInt64(buffer, 0x12B);
- PrivateRegionSizeLBA = BigEndianConverter.ToUInt64(buffer, 0x133);
- PrimaryTocLBA = BigEndianConverter.ToUInt64(buffer, 0x13B);
- SecondaryTocLBA = BigEndianConverter.ToUInt64(buffer, 0x143);
- NumberOfConfigs = BigEndianConverter.ToUInt32(buffer, 0x14B);
- NumberOfLogs = BigEndianConverter.ToUInt32(buffer, 0x14F);
- ConfigSizeLBA = BigEndianConverter.ToUInt64(buffer, 0x153);
- LogSizeLBA = BigEndianConverter.ToUInt64(buffer, 0x15B);
- DiskSignature = BigEndianConverter.ToUInt32(buffer, 0x163);
- DiskSetGuid = BigEndianConverter.ToGuid(buffer, 0x167);
- DiskSetGuidRepeat = BigEndianConverter.ToGuid(buffer, 0x177);
- BigEndianWriter.WriteUInt32(buffer, 0x08, (uint)0);
- m_isChecksumValid = (checksum == CalculateChecksum(buffer));
- }
- public byte[] GetBytes()
- {
- byte[] buffer = new byte[Length];
- ByteWriter.WriteAnsiString(buffer, 0x00, Signature, 8);
-
- BigEndianWriter.WriteUInt16(buffer, 0x0C, MajorVersion);
- BigEndianWriter.WriteUInt16(buffer, 0x0E, MinorVersion);
- BigEndianWriter.WriteInt64(buffer, 0x10, LastUpdateDT.ToFileTimeUtc());
- BigEndianWriter.WriteUInt64(buffer, 0x18, UpdateSequenceNumber);
- BigEndianWriter.WriteUInt64(buffer, 0x20, PrimaryPrivateHeaderLBA);
- BigEndianWriter.WriteUInt64(buffer, 0x28, SecondaryPrivateHeaderLBA);
- ByteWriter.WriteAnsiString(buffer, 0x30, DiskGuidString, 0x40);
- ByteWriter.WriteAnsiString(buffer, 0x70, HostGuidString, 0x40);
- ByteWriter.WriteAnsiString(buffer, 0xB0, DiskGroupGuidString, 0x40);
- ByteWriter.WriteAnsiString(buffer, 0xF0, DiskGroupName, 31);
- BigEndianWriter.WriteUInt32(buffer, 0x10F, BytesPerSector);
- BigEndianWriter.WriteUInt32(buffer, 0x113, (uint)Flags);
- BigEndianWriter.WriteUInt16(buffer, 0x117, PublicRegionSliceNumber);
- BigEndianWriter.WriteUInt16(buffer, 0x119, PrivateRegionSliceNumber);
- BigEndianWriter.WriteUInt64(buffer, 0x11B, PublicRegionStartLBA);
- BigEndianWriter.WriteUInt64(buffer, 0x123, PublicRegionSizeLBA);
- BigEndianWriter.WriteUInt64(buffer, 0x12B, PrivateRegionStartLBA);
- BigEndianWriter.WriteUInt64(buffer, 0x133, PrivateRegionSizeLBA);
- BigEndianWriter.WriteUInt64(buffer, 0x13B, PrimaryTocLBA);
- BigEndianWriter.WriteUInt64(buffer, 0x143, SecondaryTocLBA);
- BigEndianWriter.WriteUInt32(buffer, 0x14B, NumberOfConfigs);
- BigEndianWriter.WriteUInt32(buffer, 0x14F, NumberOfLogs);
- BigEndianWriter.WriteUInt64(buffer, 0x153, ConfigSizeLBA);
- BigEndianWriter.WriteUInt64(buffer, 0x15B, LogSizeLBA);
- BigEndianWriter.WriteUInt32(buffer, 0x163, DiskSignature);
- BigEndianWriter.WriteGuidBytes(buffer, 0x167, DiskSetGuid);
- BigEndianWriter.WriteGuidBytes(buffer, 0x177, DiskSetGuidRepeat);
- uint checksum = CalculateChecksum(buffer);
- BigEndianWriter.WriteUInt32(buffer, 0x08, checksum);
- return buffer;
- }
- public static PrivateHeader ReadFromDisk(Disk disk)
- {
- MasterBootRecord mbr = MasterBootRecord.ReadFromDisk(disk);
- if (mbr.IsGPTBasedDisk)
- {
- return ReadFromGPTBasedDisk(disk);
- }
- else
- {
- return ReadFromMBRBasedDisk(disk);
- }
- }
- public static PrivateHeader ReadFromMBRBasedDisk(Disk disk)
- {
-
- PrivateHeader privateHeader = ReadFromDiskEnd(disk, true);
- if (privateHeader != null)
- {
- if (privateHeader.IsChecksumValid)
- {
- return privateHeader;
- }
- else
- {
-
- long sectorIndex = (long)(privateHeader.PrivateRegionStartLBA + privateHeader.SecondaryPrivateHeaderLBA);
- return ReadFromDisk(disk, sectorIndex, false);
- }
- }
- else
- {
-
- return ReadFromDiskStart(disk);
- }
- }
- public static PrivateHeader ReadFromGPTBasedDisk(Disk disk)
- {
- List<GuidPartitionEntry> entries = GuidPartitionTable.ReadEntriesFromDisk(disk);
- int index = GuidPartitionEntryCollection.GetIndexOfPartitionTypeGuid(entries, GPTPartition.PrivateRegionPartitionTypeGuid);
-
- PrivateHeader privateHeader = PrivateHeader.ReadFromDisk(disk, (long)entries[index].LastLBA, true);
- if (privateHeader != null)
- {
- if (privateHeader.IsChecksumValid)
- {
- return privateHeader;
- }
- else
- {
-
- long sectorIndex = (long)(privateHeader.PrivateRegionStartLBA + privateHeader.SecondaryPrivateHeaderLBA);
- return ReadFromDisk(disk, sectorIndex, false);
- }
- }
- return null;
- }
- public static PrivateHeader ReadFromDiskEnd(Disk disk, bool returnPrivateHeaderWithInvalidChecksum)
- {
- long sectorCount = disk.Size / disk.BytesPerSector;
- long sectorIndex = sectorCount - 1;
- return ReadFromDisk(disk, sectorIndex, returnPrivateHeaderWithInvalidChecksum);
- }
- public static PrivateHeader ReadFromDiskStart(Disk disk)
- {
- return ReadFromDisk(disk, PrivateHeaderSectorIndex, false);
- }
- public static PrivateHeader ReadFromDisk(Disk disk, long sectorIndex, bool returnPrivateHeaderWithInvalidChecksum)
- {
- byte[] sector = disk.ReadSector(sectorIndex);
- string signature = ByteReader.ReadAnsiString(sector, 0x00, 8);
- if (signature == PrivateHeaderSignature)
- {
- PrivateHeader privateHeader = new PrivateHeader(sector);
- if (privateHeader.IsChecksumValid || returnPrivateHeaderWithInvalidChecksum)
- {
- return privateHeader;
- }
- }
- return null;
- }
- public static void WriteToDisk(Disk disk, PrivateHeader privateHeader)
- {
- byte[] bytes = privateHeader.GetBytes();
- disk.WriteSectors((long)(privateHeader.PrivateRegionStartLBA + privateHeader.PrimaryPrivateHeaderLBA), bytes);
- disk.WriteSectors((long)(privateHeader.PrivateRegionStartLBA + privateHeader.SecondaryPrivateHeaderLBA), bytes);
-
- byte[] sector = disk.ReadSector(PrivateHeaderSectorIndex);
- string signature = ByteReader.ReadAnsiString(sector, 0x00, 8);
- if (signature == PrivateHeaderSignature)
- {
- disk.WriteSectors(PrivateHeaderSectorIndex, bytes);
- }
- }
- public Guid DiskGuid
- {
- get
- {
- return new Guid(this.DiskGuidString);
- }
- set
- {
- this.DiskGuidString = value.ToString();
- }
- }
- public Guid DiskGroupGuid
- {
- get
- {
- return new Guid(this.DiskGroupGuidString);
- }
- set
- {
- this.DiskGroupGuidString = value.ToString();
- }
- }
-
-
-
-
- public ulong PreviousPrimaryTocLBA
- {
- get
- {
- if (PrimaryTocLBA == 1)
- {
- return PrimaryTocLBA + 1;
- }
- else
- {
- return PrimaryTocLBA - 1;
- }
- }
- }
- public ulong PreviousSecondaryTocLBA
- {
- get
- {
- if (PrimaryTocLBA == 1)
- {
- return SecondaryTocLBA - 1;
- }
- else
- {
- return SecondaryTocLBA + 1;
- }
- }
- }
- public bool IsChecksumValid
- {
- get
- {
- return m_isChecksumValid;
- }
- }
- public static uint CalculateChecksum(byte[] bytes)
- {
- uint result = 0;
- for (int index = 0; index < bytes.Length; index++)
- {
- result += bytes[index];
- }
- return result;
- }
- }
- }
|