/// <summary> /// Creates a new partition table on a disk. /// </summary> /// <param name="disk">The stream containing the disk data.</param> /// <param name="diskGeometry">The geometry of the disk.</param> /// <returns>An object to access the newly created partition table.</returns> public static GuidPartitionTable Initialize(Stream disk, Geometry diskGeometry) { // Create the protective MBR partition record. BiosPartitionTable pt = BiosPartitionTable.Initialize(disk, diskGeometry); pt.CreatePrimaryByCylinder(0, diskGeometry.Cylinders - 1, BiosPartitionTypes.GptProtective, false); // Create the GPT headers, and blank-out the entry areas const int EntryCount = 128; const int EntrySize = 128; int entrySectors = (EntryCount * EntrySize + diskGeometry.BytesPerSector - 1) / diskGeometry.BytesPerSector; byte[] entriesBuffer = new byte[EntryCount * EntrySize]; // Prepare primary header GptHeader header = new GptHeader(diskGeometry.BytesPerSector); header.HeaderLba = 1; header.AlternateHeaderLba = disk.Length / diskGeometry.BytesPerSector - 1; header.FirstUsable = header.HeaderLba + entrySectors + 1; header.LastUsable = header.AlternateHeaderLba - entrySectors - 1; header.DiskGuid = Guid.NewGuid(); header.PartitionEntriesLba = 2; header.PartitionEntryCount = EntryCount; header.PartitionEntrySize = EntrySize; header.EntriesCrc = CalcEntriesCrc(entriesBuffer); // Write the primary header byte[] headerBuffer = new byte[diskGeometry.BytesPerSector]; header.WriteTo(headerBuffer, 0); disk.Position = header.HeaderLba * diskGeometry.BytesPerSector; disk.Write(headerBuffer, 0, headerBuffer.Length); // Write the primary partition table disk.Position = header.PartitionEntriesLba * diskGeometry.BytesPerSector; disk.Write(entriesBuffer, 0, entriesBuffer.Length); // Calc alternate header header.HeaderLba = header.AlternateHeaderLba; header.AlternateHeaderLba = 1; header.PartitionEntriesLba = header.HeaderLba - entrySectors; // Write the alternate header header.WriteTo(headerBuffer, 0); disk.Position = header.HeaderLba * diskGeometry.BytesPerSector; disk.Write(headerBuffer, 0, headerBuffer.Length); // Write the alternate partition table disk.Position = header.PartitionEntriesLba * diskGeometry.BytesPerSector; disk.Write(entriesBuffer, 0, entriesBuffer.Length); return(new GuidPartitionTable(disk, diskGeometry)); }
private void WriteSecondaryHeader() { byte[] buffer = new byte[_diskGeometry.BytesPerSector]; _secondaryHeader.EntriesCrc = CalcEntriesCrc(); _secondaryHeader.WriteTo(buffer, 0); _diskData.Position = _diskData.Length - _diskGeometry.BytesPerSector; _diskData.Write(buffer, 0, buffer.Length); _diskData.Position = _secondaryHeader.PartitionEntriesLba * _diskGeometry.BytesPerSector; _diskData.Write(_entryBuffer, 0, _entryBuffer.Length); }
private void WritePrimaryHeader() { byte[] buffer = new byte[_diskGeometry.BytesPerSector]; _primaryHeader.EntriesCrc = CalcEntriesCrc(); _primaryHeader.WriteTo(buffer, 0); _diskData.Position = _diskGeometry.BytesPerSector; _diskData.Write(buffer, 0, buffer.Length); _diskData.Position = 2 * _diskGeometry.BytesPerSector; _diskData.Write(_entryBuffer, 0, _entryBuffer.Length); }