private void ReadHeaders() { _freeSpace.Reserve(0, Sizes.OneMiB); _activeHeader = 0; _fileStream.Position = 64 * Sizes.OneKiB; VhdxHeader vhdxHeader1 = StreamUtilities.ReadStruct <VhdxHeader>(_fileStream); if (vhdxHeader1.IsValid) { _header = vhdxHeader1; _activeHeader = 1; } _fileStream.Position = 128 * Sizes.OneKiB; VhdxHeader vhdxHeader2 = StreamUtilities.ReadStruct <VhdxHeader>(_fileStream); if (vhdxHeader2.IsValid && (_activeHeader == 0 || _header.SequenceNumber < vhdxHeader2.SequenceNumber)) { _header = vhdxHeader2; _activeHeader = 2; } if (_activeHeader == 0) { throw new IOException("Invalid VHDX file - no valid VHDX headers found"); } }
private void Initialize() { _fileStream.Position = 0; FileHeader fileHeader = StreamUtilities.ReadStruct <FileHeader>(_fileStream); if (!fileHeader.IsValid) { throw new IOException("Invalid VHDX file - file signature mismatch"); } _freeSpace = new FreeSpaceTable(_fileStream.Length); ReadHeaders(); ReplayLog(); ReadRegionTable(); ReadMetadata(); _batStream = OpenRegion(RegionTable.BatGuid); _freeSpace.Reserve(BatControlledFileExtents()); // Indicate the file is open for modification if (_fileStream.CanWrite) { _header.FileWriteGuid = Guid.NewGuid(); WriteHeader(); } }
private T ReadStruct <T>(Guid itemId, bool isUser) where T : IByteArraySerializable, new() { MetadataEntryKey key = new MetadataEntryKey(itemId, isUser); MetadataEntry entry; if (Table.Entries.TryGetValue(key, out entry)) { _regionStream.Position = entry.Offset; return(StreamUtilities.ReadStruct <T>(_regionStream, (int)entry.Length)); } return(default(T)); }
public Metadata(Stream regionStream) { _regionStream = regionStream; _regionStream.Position = 0; Table = StreamUtilities.ReadStruct <MetadataTable>(_regionStream); FileParameters = ReadStruct <FileParameters>(MetadataTable.FileParametersGuid, false); DiskSize = ReadValue(MetadataTable.VirtualDiskSizeGuid, false, EndianUtilities.ToUInt64LittleEndian); _page83Data = ReadValue(MetadataTable.Page83DataGuid, false, EndianUtilities.ToGuidLittleEndian); LogicalSectorSize = ReadValue(MetadataTable.LogicalSectorSizeGuid, false, EndianUtilities.ToUInt32LittleEndian); PhysicalSectorSize = ReadValue(MetadataTable.PhysicalSectorSizeGuid, false, EndianUtilities.ToUInt32LittleEndian); ParentLocator = ReadStruct <ParentLocator>(MetadataTable.ParentLocatorGuid, false); }
private void ReadRegionTable() { _fileStream.Position = 192 * Sizes.OneKiB; _regionTable = StreamUtilities.ReadStruct <RegionTable>(_fileStream); foreach (RegionEntry entry in _regionTable.Regions.Values) { if ((entry.Flags & RegionFlags.Required) != 0) { if (entry.Guid != RegionTable.BatGuid && entry.Guid != RegionTable.MetadataRegionGuid) { throw new IOException("Invalid VHDX file - unrecognised required region"); } } _freeSpace.Reserve(entry.FileOffset, entry.Length); } }