MasterBootRecord.cs 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /* Copyright (C) 2014 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
  2. *
  3. * You can redistribute this program and/or modify it under the terms of
  4. * the GNU Lesser Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. */
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Text;
  10. using Utilities;
  11. namespace DiskAccessLibrary
  12. {
  13. public class MasterBootRecord
  14. {
  15. public const ushort ValidMBRSignature = 0xAA55;
  16. public const int NumberOfPartitionEntries = 4;
  17. public byte[] Code = new byte[440];
  18. public uint DiskSignature;
  19. public PartitionTableEntry[] PartitionTable = new PartitionTableEntry[4];
  20. public ushort MBRSignature;
  21. public MasterBootRecord()
  22. {
  23. for (int index = 0; index < NumberOfPartitionEntries; index++)
  24. {
  25. PartitionTable[index] = new PartitionTableEntry();
  26. }
  27. }
  28. public MasterBootRecord(byte[] buffer)
  29. {
  30. Array.Copy(buffer, Code, 440);
  31. DiskSignature = LittleEndianConverter.ToUInt32(buffer, 440);
  32. int offset = 446;
  33. for (int index = 0; index < NumberOfPartitionEntries; index++)
  34. {
  35. PartitionTable[index] = new PartitionTableEntry(buffer, offset);
  36. offset += 16;
  37. }
  38. MBRSignature = LittleEndianConverter.ToUInt16(buffer, 510);
  39. }
  40. public byte[] GetBytes(int sectorSize)
  41. {
  42. byte[] buffer = new byte[sectorSize];
  43. ByteWriter.WriteBytes(buffer, 0, Code, Math.Min(Code.Length, 440));
  44. LittleEndianWriter.WriteUInt32(buffer, 440, DiskSignature);
  45. int offset = 446;
  46. for (int index = 0; index < NumberOfPartitionEntries; index++)
  47. {
  48. PartitionTable[index].WriteBytes(buffer, offset);
  49. offset += PartitionTableEntry.Length;
  50. }
  51. LittleEndianWriter.WriteUInt16(buffer, 510, MBRSignature);
  52. return buffer;
  53. }
  54. public bool IsGPTBasedDisk
  55. {
  56. get
  57. {
  58. return (PartitionTable[0].PartitionTypeName == PartitionTypeName.EFIGPT);
  59. }
  60. }
  61. public static MasterBootRecord ReadFromDisk(Disk disk)
  62. {
  63. byte[] buffer = disk.ReadSector(0);
  64. ushort signature = LittleEndianConverter.ToUInt16(buffer, 510);
  65. if (signature == ValidMBRSignature)
  66. {
  67. return new MasterBootRecord(buffer);
  68. }
  69. else
  70. {
  71. return null;
  72. }
  73. }
  74. public static void WriteToDisk(Disk disk, MasterBootRecord mbr)
  75. {
  76. byte[] buffer = mbr.GetBytes(disk.BytesPerSector);
  77. disk.WriteSectors(0, buffer);
  78. }
  79. }
  80. }