private void ReadHeaders() { long pos = _footer.DataOffset; while (pos != -1) { _fileStream.Position = pos; Header hdr = Header.FromStream(_fileStream); if (hdr.Cookie == DynamicHeader.HeaderCookie) { _fileStream.Position = pos; _dynamicHeader = DynamicHeader.FromStream(_fileStream); if (!_dynamicHeader.IsValid()) { throw new IOException("Invalid Dynamic Disc Header"); } } pos = hdr.DataOffset; } }
private void CheckDynamicHeader() { long lastHeaderEnd = _footer.DataOffset + 512; long pos = _footer.DataOffset; while (pos != -1) { if ((pos % 512) != 0) { ReportError("DynHeader: Unaligned header @{0}", pos); } _fileStream.Position = pos; Header hdr = Header.FromStream(_fileStream); if (hdr.Cookie == DynamicHeader.HeaderCookie) { if (_dynamicHeader != null) { ReportError("DynHeader: Duplicate dynamic header found"); } _fileStream.Position = pos; _dynamicHeader = DynamicHeader.FromStream(_fileStream); if (pos + 1024 > lastHeaderEnd) { lastHeaderEnd = pos + 1024; } } else { ReportWarning("DynHeader: Undocumented header found, with cookie '" + hdr.Cookie + "'"); if (pos + 512 > lastHeaderEnd) { lastHeaderEnd = pos + 1024; } } pos = hdr.DataOffset; } if (_dynamicHeader == null) { ReportError("DynHeader: No dynamic header found"); return; } if (_dynamicHeader.TableOffset < lastHeaderEnd) { ReportError("DynHeader: BAT offset is before last header"); } if ((_dynamicHeader.TableOffset % 512) != 0) { ReportError("DynHeader: BAT offset is not sector aligned"); } if (_dynamicHeader.HeaderVersion != 0x00010000) { ReportError("DynHeader: Unrecognized header version"); } if (_dynamicHeader.MaxTableEntries != Utilities.Ceil(_footer.CurrentSize, _dynamicHeader.BlockSize)) { ReportError("DynHeader: Max table entries is invalid"); } if ((_dynamicHeader.BlockSize != Sizes.OneMiB * 2) && (_dynamicHeader.BlockSize != Sizes.OneKiB * 512)) { ReportWarning("DynHeader: Using non-standard block size '" + _dynamicHeader.BlockSize + "'"); } if (!Utilities.IsPowerOfTwo(_dynamicHeader.BlockSize)) { ReportError("DynHeader: Block size is not a power of 2"); } if (!_dynamicHeader.IsChecksumValid()) { ReportError("DynHeader: Invalid checksum"); } if (_footer.DiskType == FileType.Dynamic && _dynamicHeader.ParentUniqueId != Guid.Empty) { ReportWarning("DynHeader: Parent Id is not null for dynamic disk"); } else if (_footer.DiskType == FileType.Differencing && _dynamicHeader.ParentUniqueId == Guid.Empty) { ReportError("DynHeader: Parent Id is null for differencing disk"); } if (_footer.DiskType == FileType.Differencing && _dynamicHeader.ParentTimestamp > DateTime.UtcNow) { ReportWarning("DynHeader: Parent timestamp is greater than current time"); } }