123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- /* Copyright (C) 2014 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
- *
- * You can redistribute this program and/or modify it under the terms of
- * the GNU Lesser Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- */
- using System;
- using System.Collections.Generic;
- using System.Text;
- using Utilities;
- namespace DiskAccessLibrary.VHD
- {
- public class DynamicDiskHeader
- {
- public const int Length = 1024;
- public const string DynamidDiskHeaderCookie = "cxsparse";
- public string Cookie; // 8 bytes
- public ulong DataOffset; // The documentation says 0xFFFFFFFF, but all programs use 0xFFFFFFFFFFFFFFFF
- public ulong TableOffset;
- public uint HeaderVersion;
- public uint MaxTableEntries;
- public uint BlockSize;
- //public uint Checksum;
- public Guid ParentUniqueID;
- public uint ParentTimeStamp;
- public uint Reserved;
- public string ParentUnicodeName = String.Empty; // 8 bytes
- public ParentLocatorEntry ParentLocatorEntry1;
- public ParentLocatorEntry ParentLocatorEntry2;
- public ParentLocatorEntry ParentLocatorEntry3;
- public ParentLocatorEntry ParentLocatorEntry4;
- public ParentLocatorEntry ParentLocatorEntry5;
- public ParentLocatorEntry ParentLocatorEntry6;
- public ParentLocatorEntry ParentLocatorEntry7;
- public ParentLocatorEntry ParentLocatorEntry8;
- private bool m_isValid = true;
- public DynamicDiskHeader()
- {
- Cookie = DynamidDiskHeaderCookie;
- DataOffset = 0xFFFFFFFFFFFFFFFF;
- HeaderVersion = 0x00010000;
- }
- public DynamicDiskHeader(byte[] buffer)
- {
- Cookie = ByteReader.ReadAnsiString(buffer, 0x00, 8);
- DataOffset = BigEndianConverter.ToUInt64(buffer, 0x08);
- TableOffset = BigEndianConverter.ToUInt64(buffer, 0x10);
- HeaderVersion = BigEndianConverter.ToUInt32(buffer, 0x18);
- MaxTableEntries = BigEndianConverter.ToUInt32(buffer, 0x1C);
- BlockSize = BigEndianConverter.ToUInt32(buffer, 0x20);
- uint checksum = BigEndianConverter.ToUInt32(buffer, 0x24);
- ParentUniqueID = BigEndianConverter.ToGuid(buffer, 0x28);
- ParentTimeStamp = BigEndianConverter.ToUInt32(buffer, 0x38);
- Reserved = BigEndianConverter.ToUInt32(buffer, 0x3C);
- ParentUnicodeName = ByteReader.ReadUTF16String(buffer, 0x40, 256).TrimEnd('\0');
- ParentLocatorEntry1 = new ParentLocatorEntry(buffer, 0x240);
- ParentLocatorEntry2 = new ParentLocatorEntry(buffer, 0x258);
- ParentLocatorEntry3 = new ParentLocatorEntry(buffer, 0x270);
- ParentLocatorEntry4 = new ParentLocatorEntry(buffer, 0x288);
- ParentLocatorEntry5 = new ParentLocatorEntry(buffer, 0x2A0);
- ParentLocatorEntry6 = new ParentLocatorEntry(buffer, 0x2B8);
- ParentLocatorEntry7 = new ParentLocatorEntry(buffer, 0x2D0);
- ParentLocatorEntry8 = new ParentLocatorEntry(buffer, 0x2E8);
- byte[] temp = (byte[])buffer.Clone();
- BigEndianWriter.WriteInt32(temp, 0x24, 0);
- uint expectedChecksum = VHDFooter.CalculateChecksum(temp);
- m_isValid = String.Equals(Cookie, DynamidDiskHeaderCookie) && (checksum == expectedChecksum) && (HeaderVersion == 0x00010000);
- }
- public byte[] GetBytes()
- {
- byte[] buffer = new byte[Length];
- ByteWriter.WriteAnsiString(buffer, 0x00, Cookie, 8);
- BigEndianWriter.WriteUInt64(buffer, 0x08, DataOffset);
- BigEndianWriter.WriteUInt64(buffer, 0x10, TableOffset);
- BigEndianWriter.WriteUInt32(buffer, 0x18, HeaderVersion);
- BigEndianWriter.WriteUInt32(buffer, 0x1C, MaxTableEntries);
- BigEndianWriter.WriteUInt32(buffer, 0x20, BlockSize);
- // We'll write the checksum later
- BigEndianWriter.WriteGuidBytes(buffer, 0x28, ParentUniqueID);
- BigEndianWriter.WriteUInt32(buffer, 0x38, ParentTimeStamp);
- BigEndianWriter.WriteUInt32(buffer, 0x3C, Reserved);
- ByteWriter.WriteUTF16String(buffer, 0x40, ParentUnicodeName, 256);
- ParentLocatorEntry1.WriteBytes(buffer, 0x240);
- ParentLocatorEntry2.WriteBytes(buffer, 0x258);
- ParentLocatorEntry3.WriteBytes(buffer, 0x270);
- ParentLocatorEntry4.WriteBytes(buffer, 0x288);
- ParentLocatorEntry5.WriteBytes(buffer, 0x2A0);
- ParentLocatorEntry6.WriteBytes(buffer, 0x2B8);
- ParentLocatorEntry7.WriteBytes(buffer, 0x2D0);
- ParentLocatorEntry8.WriteBytes(buffer, 0x2E8);
- uint checksum = VHDFooter.CalculateChecksum(buffer);
- BigEndianWriter.WriteUInt32(buffer, 0x24, checksum);
- return buffer;
- }
- }
- }
|