Documentation
¶
Overview ¶
VHD Dynamic Disk Header Parser
Package reader provides high-level APIs for reading VHD/VHDX virtual disk files.
Package reader provides high-level APIs for reading VHD/VHDX virtual disk files.
VHDX File Information and Image Header Parser
Index ¶
- Constants
- Variables
- type ChainEntry
- type Extent
- type ExtentKind
- type LogReplayStats
- type Options
- type ParentRequest
- type ParentResolver
- type ParentResolverFunc
- type ParentSource
- type VHDDynamicDiskHeaderParser
- type VHDFooterParser
- type VHDXFileInfoParser
- type VHDXImageHeaderParser
- type VHDXRegionTableParser
- type VirtualDisk
- func Open(r io.ReaderAt, opts *Options) (*VirtualDisk, error)
- func OpenFile(path string) (*VirtualDisk, error)
- func OpenFileWith(name string, opts *Options) (*VirtualDisk, error)
- func OpenVHD(r io.ReaderAt, fileSize int64) (*VirtualDisk, error)
- func OpenVHDX(r io.ReaderAt, fileSize int64) (*VirtualDisk, error)
- func (d *VirtualDisk) AllExtents() ([]Extent, error)
- func (d *VirtualDisk) BlockSize() uint32
- func (d *VirtualDisk) Chain() []ChainEntry
- func (d *VirtualDisk) ChainComplete() bool
- func (d *VirtualDisk) ChainDepth() int
- func (d *VirtualDisk) Close() error
- func (d *VirtualDisk) DiskType() types.DiskType
- func (d *VirtualDisk) Extents(virtualOffset, length int64) ([]Extent, error)
- func (d *VirtualDisk) Format() types.FileFormat
- func (d *VirtualDisk) GUIDString() string
- func (d *VirtualDisk) HasLog() bool
- func (d *VirtualDisk) Identifier() [16]byte
- func (d *VirtualDisk) IsDifferencing() bool
- func (d *VirtualDisk) IsDirty() bool
- func (d *VirtualDisk) LogReplayStats() (LogReplayStats, bool)
- func (d *VirtualDisk) LogReplayed() bool
- func (d *VirtualDisk) MappedBytes() (int64, error)
- func (d *VirtualDisk) NeedsParent() bool
- func (d *VirtualDisk) Parent() *VirtualDisk
- func (d *VirtualDisk) ParentFilename() string
- func (d *VirtualDisk) ParentIdentifier() [16]byte
- func (d *VirtualDisk) ParentLocators() []types.ParentLocatorEntry
- func (d *VirtualDisk) ParentResolveError() error
- func (d *VirtualDisk) Path() string
- func (d *VirtualDisk) ReadAt(p []byte, offset int64) (int, error)
- func (d *VirtualDisk) SectorSize() uint32
- func (d *VirtualDisk) SetParent(parent *VirtualDisk) error
- func (d *VirtualDisk) Size() uint64
- func (d *VirtualDisk) VirtualToFileOffset(virtualOffset int64) (fileOffset int64, mapped bool, err error)
Constants ¶
const DefaultMaxChainDepth = 32
DefaultMaxChainDepth bounds how many disks a differencing chain may contain, counting the child itself.
Variables ¶
var ErrChainCycle = errors.New("libvhdi: parent chain contains a cycle")
ErrChainCycle is returned when a parent chain refers back to a disk already in the chain.
var ErrChainTooDeep = errors.New("libvhdi: parent chain exceeds maximum depth")
ErrChainTooDeep is returned when a parent chain exceeds Options.MaxChainDepth.
var ErrCorruptImage = errors.New("libvhdi: corrupt or malformed image")
ErrCorruptImage is returned when an image's headers are internally inconsistent or describe structures that do not fit the file.
var ErrDirtyImage = errors.New("libvhdi: image has an unreplayed log and may be stale")
ErrDirtyImage is returned when a VHDX image carries an unreplayed log. Its block allocation table and metadata may be stale, so decoded contents cannot be trusted. Set Options.AllowDirtyImage to read it anyway.
var ErrParentMismatch = errors.New("libvhdi: parent image does not match child metadata")
ErrParentMismatch is returned when a located parent does not match the identity recorded in the child.
var ErrParentNotFound = errors.New("libvhdi: parent image not found")
ErrParentNotFound is returned by a ParentResolver that exhausted its search without locating the requested parent image.
var ErrParentRequired = diff.ErrParentRequired
ErrParentRequired is returned when a read on a differencing disk resolves to a parent that has not been attached. Differencing disks fail closed: silently returning zeroes would be indistinguishable from genuine disk contents.
var ErrSizeUnknown = errors.New("libvhdi: cannot determine file size; set Options.Size")
ErrSizeUnknown is returned when a disk's total file size can neither be derived from the supplied reader nor was given explicitly.
Functions ¶
This section is empty.
Types ¶
type ChainEntry ¶
type ChainEntry struct {
// Index is the disk's position: 0 is the disk Chain was called on, 1 its
// parent, and so on.
Index int
// Path is the file the disk was opened from, or "" when it came from a bare
// io.ReaderAt.
Path string
// Identifier is the disk's own GUID.
Identifier [16]byte
// ParentIdentifier is the GUID this disk records for its parent, zero for a
// disk that has none.
ParentIdentifier [16]byte
// ParentFilename is the parent path recorded in this disk's metadata.
ParentFilename string
Format types.FileFormat
DiskType types.DiskType
// VirtualSize is the disk's virtual size. Every link in a valid chain
// reports the same value.
VirtualSize uint64
// IsDifferencing reports whether this disk depends on a parent.
IsDifferencing bool
// HasLog and LogReplayed describe the disk's VHDX log state.
HasLog bool
LogReplayed bool
}
ChainEntry describes one disk in a differencing chain.
func (ChainEntry) GUIDString ¶
func (e ChainEntry) GUIDString() string
GUIDString returns the disk's identifier as a formatted GUID.
type Extent ¶
type Extent struct {
// VirtualOffset and Length bound the run in the virtual disk's address
// space.
VirtualOffset int64
Length int64
// Kind says what backs the run.
Kind ExtentKind
// FileOffset is the byte offset of the run within the backing file. Valid
// only when Kind is ExtentMapped.
FileOffset int64
// ChainIndex identifies the backing disk: 0 is the disk Extents was called
// on, 1 its parent, and so on. Meaningful when Kind is ExtentMapped.
ChainIndex int
// Path is the backing disk's file path when known, for provenance.
Path string
}
Extent describes a contiguous run of the virtual disk address space and what backs it.
type ExtentKind ¶
type ExtentKind int
ExtentKind describes what backs a range of the virtual disk.
const ( // ExtentZero: the range has no backing bytes anywhere in the chain and reads // as zeroes. An acquisition tool can skip it rather than write zeroes. ExtentZero ExtentKind = iota // ExtentMapped: the range is backed by a contiguous run of bytes in one of // the files in the chain, at FileOffset. ExtentMapped // ExtentUnresolved: the range resolves to a parent that is not attached, so // its contents are unknown. Reading it returns ErrParentRequired. ExtentUnresolved )
type LogReplayStats ¶
type LogReplayStats struct {
// Entries is the number of log entries replayed.
Entries int
// Descriptors is the number of descriptors applied across those entries.
Descriptors int
// Sectors is the number of distinct 4 KB file sectors the replay overrides.
Sectors int
// FirstSequence and LastSequence bound the replayed sequence numbers.
FirstSequence, LastSequence uint64
}
LogReplayStats describes what a log replay applied.
type Options ¶
type Options struct {
// ParentResolver locates parents for differencing disks. When nil, no
// automatic resolution is attempted and the caller must use SetParent.
ParentResolver ParentResolver
// Size is the total size of the image in bytes. When zero, Open derives it
// from the reader. Required for VHD images whose reader exposes neither a
// size nor a seek nor a stat method.
Size int64
// MaxChainDepth bounds the length of a differencing chain, counting the
// child. Zero means DefaultMaxChainDepth.
MaxChainDepth int
// AllowParentGUIDMismatch skips verification that a resolved parent's
// identifier matches the one recorded in the child. Leaving this false
// prevents an unrelated image of the right size from being read as the
// parent.
AllowParentGUIDMismatch bool
// RequireParentChain makes Open fail when a differencing disk's parent
// cannot be resolved. By default resolution is best-effort: the disk opens
// with NeedsParent reporting true and reads that need the parent failing
// with ErrParentRequired.
RequireParentChain bool
// AllowDirtyImage opens a VHDX image whose log has not been replayed. Such
// an image's block allocation table and metadata may be stale, so its
// contents may not reflect the last committed state. Log replay is not
// implemented, so this trades a hard failure for a documented risk; check
// IsDirty on the result. Leaving this false refuses the image with
// ErrDirtyImage.
AllowDirtyImage bool
}
Options controls how a disk is opened.
The zero value is safe: parent GUIDs are verified, dirty images are refused, and differencing disks with no parent fail closed on read. Every field that relaxes a check is named so that false — the zero value — is the strict setting.
type ParentRequest ¶
type ParentRequest struct {
// ChildPath is the filesystem path of the child, when it was opened from
// one. Empty for disks opened from a bare io.ReaderAt.
ChildPath string
// ChildDir is the directory containing the child, when known. Parents are
// conventionally stored alongside or near their children, so this is the
// first place to look.
ChildDir string
// ParentFilename is the path recorded in the child's metadata. It is
// typically a Windows path and may be relative or absolute.
ParentFilename string
// ParentIdentifier is the GUID the parent must carry. Callers should not
// need to check this themselves; the chain builder verifies it.
ParentIdentifier [16]byte
// Locators carries the child's parent locator entries, which may hold
// additional candidate paths.
Locators []types.ParentLocatorEntry
// Format is the child's format. A parent is normally the same format.
Format types.FileFormat
// Depth is 0 for the immediate parent of the disk the caller opened, 1 for
// its grandparent, and so on.
Depth int
}
ParentRequest describes the parent image a differencing disk is looking for.
type ParentResolver ¶
type ParentResolver interface {
ResolveParent(req ParentRequest) (ParentSource, error)
}
ParentResolver locates the parent image of a differencing disk.
Implementations should return ErrParentNotFound (possibly wrapped) when the parent cannot be located, so callers can distinguish a missing parent from an I/O failure.
func DirParentResolver ¶
func DirParentResolver(dirs ...string) ParentResolver
DirParentResolver returns a ParentResolver that searches the child's own directory first, then each of the supplied directories, for the parent named in the child's metadata.
For each directory it tries the recorded relative path and then the bare filename, so a chain that has been moved as a unit still resolves.
func FSParentResolver ¶
func FSParentResolver(fsys fs.FS) ParentResolver
FSParentResolver returns a ParentResolver that searches an fs.FS. Paths are interpreted as slash-separated and relative to the root of fsys, matching io/fs conventions, which makes it usable with embedded, archived or test filesystems.
type ParentResolverFunc ¶
type ParentResolverFunc func(req ParentRequest) (ParentSource, error)
ParentResolverFunc adapts a function to the ParentResolver interface.
func (ParentResolverFunc) ResolveParent ¶
func (f ParentResolverFunc) ResolveParent(req ParentRequest) (ParentSource, error)
ResolveParent implements ParentResolver.
type ParentSource ¶
type ParentSource struct {
// ReaderAt is the parent's backing reader. Required.
ReaderAt io.ReaderAt
// Size is the parent file's total size in bytes. Required for VHD, whose
// footer is located from the end of the file.
Size int64
// Closer, if non-nil, is closed when the child disk is closed. Resolvers
// that open files should set this so the chain owns the handle.
Closer io.Closer
// Name is a human-readable identifier used in diagnostics.
Name string
}
ParentSource is an opened parent image returned by a ParentResolver.
type VHDDynamicDiskHeaderParser ¶
type VHDDynamicDiskHeaderParser struct {
// contains filtered or unexported fields
}
VHDDynamicDiskHeaderParser provides functionality to parse VHD dynamic disk headers.
func NewVHDDynamicDiskHeaderParser ¶
func NewVHDDynamicDiskHeaderParser(r io.ReaderAt) *VHDDynamicDiskHeaderParser
NewVHDDynamicDiskHeaderParser creates a new VHD dynamic disk header parser.
func (*VHDDynamicDiskHeaderParser) ReadHeaderAt ¶
func (p *VHDDynamicDiskHeaderParser) ReadHeaderAt(offset int64) (*types.ParsedDynamicDiskHeader, error)
ReadHeaderAt reads a VHD dynamic disk header from a specific offset.
func (*VHDDynamicDiskHeaderParser) VerifyHeaderChecksum ¶
func (p *VHDDynamicDiskHeaderParser) VerifyHeaderChecksum(header *types.DynamicDiskHeader) bool
VerifyHeaderChecksum verifies the dynamic disk header's checksum.
Per the VHD specification this is a one's complement of the sum of all header bytes with the checksum field zeroed — not a CRC. CRC-32C applies only to VHDX structures.
type VHDFooterParser ¶
type VHDFooterParser struct {
// contains filtered or unexported fields
}
VHDFooterParser provides functionality to parse VHD file footers.
func NewVHDFooterParser ¶
func NewVHDFooterParser(r io.ReaderAt) *VHDFooterParser
NewVHDFooterParser creates a new VHD footer parser.
func (*VHDFooterParser) ReadFooterAt ¶
func (p *VHDFooterParser) ReadFooterAt(offset int64) (*types.ParsedFileFooter, error)
ReadFooterAt reads the VHD footer from a specific offset.
func (*VHDFooterParser) ReadFooterFromEnd ¶
func (p *VHDFooterParser) ReadFooterFromEnd(fileSize int64) (*types.ParsedFileFooter, error)
ReadFooterFromEnd reads the VHD footer from the end of the file (at offset -512).
func (*VHDFooterParser) VerifyFooterChecksum ¶
func (p *VHDFooterParser) VerifyFooterChecksum(footer *types.FileFooter) bool
VerifyFooterChecksum verifies the footer's checksum.
Per the VHD specification this is a one's complement of the sum of all footer bytes with the checksum field zeroed — not a CRC. CRC-32C applies only to VHDX structures.
type VHDXFileInfoParser ¶
type VHDXFileInfoParser struct {
// contains filtered or unexported fields
}
VHDXFileInfoParser provides functionality to parse VHDX file information.
func NewVHDXFileInfoParser ¶
func NewVHDXFileInfoParser(r io.ReaderAt) *VHDXFileInfoParser
NewVHDXFileInfoParser creates a new VHDX file info parser.
func (*VHDXFileInfoParser) ReadFileInfo ¶
func (p *VHDXFileInfoParser) ReadFileInfo() (*types.ParsedFileInformation, error)
ReadFileInfo reads VHDX file information from offset 0.
type VHDXImageHeaderParser ¶
type VHDXImageHeaderParser struct {
// contains filtered or unexported fields
}
VHDXImageHeaderParser provides functionality to parse VHDX image headers.
func NewVHDXImageHeaderParser ¶
func NewVHDXImageHeaderParser(r io.ReaderAt) *VHDXImageHeaderParser
NewVHDXImageHeaderParser creates a new VHDX image header parser.
func (*VHDXImageHeaderParser) ReadImageHeader ¶
func (p *VHDXImageHeaderParser) ReadImageHeader() (*types.ParsedImageHeader, error)
ReadImageHeader reads and validates both image headers, returning the valid one with the higher sequence number (per the VHDX spec).
func (*VHDXImageHeaderParser) ReadImageHeaderAt ¶
func (p *VHDXImageHeaderParser) ReadImageHeaderAt(offset int64) (*types.ParsedImageHeader, error)
ReadImageHeaderAt reads and validates a single VHDX image header at the given offset. CRC-32 is computed over all 4096 bytes with the checksum field (bytes 4-7) zeroed.
func (*VHDXImageHeaderParser) VerifyImageHeaderChecksum ¶
func (p *VHDXImageHeaderParser) VerifyImageHeaderChecksum(header *types.ImageHeader) bool
VerifyImageHeaderChecksum verifies the image header's CRC-32 checksum.
type VHDXRegionTableParser ¶
type VHDXRegionTableParser struct {
// contains filtered or unexported fields
}
VHDXRegionTableParser provides functionality to parse VHDX region tables.
func NewVHDXRegionTableParser ¶
func NewVHDXRegionTableParser(r io.ReaderAt) *VHDXRegionTableParser
NewVHDXRegionTableParser creates a new VHDX region table parser.
func (*VHDXRegionTableParser) ReadRegionTableAt ¶
func (p *VHDXRegionTableParser) ReadRegionTableAt(offset int64) ([]types.ParsedRegionTableEntry, error)
ReadRegionTableAt reads a VHDX region table from a specific offset. The region table is 64KB; CRC-32 is verified over the full 64KB with the checksum field (bytes 4-7) zeroed before calculation.
type VirtualDisk ¶
type VirtualDisk struct {
// contains filtered or unexported fields
}
VirtualDisk provides a unified read interface for VHD and VHDX virtual disks.
func Open ¶
func Open(r io.ReaderAt, opts *Options) (*VirtualDisk, error)
Open opens a VHD or VHDX image from r, detecting the format automatically.
The image size is taken from opts.Size when set, and otherwise derived from r: readers exposing Size, Stat or Seek are all handled, which covers *os.File, *bytes.Reader, *strings.Reader, io.SectionReader and fs.File. A bare io.ReaderAt with none of those must supply opts.Size for VHD images.
When opts.ParentResolver is set, differencing parent chains are resolved automatically so the returned disk presents a correct contiguous device with no manual SetParent wiring.
opts may be nil, which selects the documented defaults.
func OpenFile ¶
func OpenFile(path string) (*VirtualDisk, error)
OpenFile opens a VHD or VHDX file by path, auto-detecting the format.
For a differencing disk, parents are resolved automatically from the image's own directory, so the returned disk presents a correct contiguous device without manual SetParent wiring. Resolution is best-effort: if the chain cannot be completed the disk still opens, ParentResolveError explains why, and reads that need the missing parent return ErrParentRequired rather than zeroes.
Use OpenFileWith for control over parent resolution and the other options.
func OpenFileWith ¶
func OpenFileWith(name string, opts *Options) (*VirtualDisk, error)
OpenFileWith opens a VHD or VHDX file by path with explicit options.
When opts.ParentResolver is nil, a resolver searching the image's own directory is used, since that is where a differencing chain's parents conventionally live.
func OpenVHD ¶
func OpenVHD(r io.ReaderAt, fileSize int64) (*VirtualDisk, error)
OpenVHD opens a VHD file (fixed, dynamic, or differencing). fileSize must be the total size of the file in bytes. For differencing disks, call SetParent before reading.
func OpenVHDX ¶
func OpenVHDX(r io.ReaderAt, fileSize int64) (*VirtualDisk, error)
OpenVHDX opens a VHDX file. fileSize must be the total size of the file in bytes.
If the image carries a log, it is replayed into an in-memory overlay before anything else is parsed, so the disk presents the last committed state. The file itself is never modified. An image whose log cannot be replayed — no valid entries, or an incomplete sequence — is refused with ErrDirtyImage; use Open with Options.AllowDirtyImage to read it as-is anyway.
func (*VirtualDisk) AllExtents ¶
func (d *VirtualDisk) AllExtents() ([]Extent, error)
AllExtents maps the whole disk. It is shorthand for Extents(0, Size()).
func (*VirtualDisk) BlockSize ¶
func (d *VirtualDisk) BlockSize() uint32
BlockSize returns the block size in bytes.
func (*VirtualDisk) Chain ¶
func (d *VirtualDisk) Chain() []ChainEntry
Chain returns the disks backing this one, from this disk outwards.
A fixed or dynamic disk yields a single entry. A differencing disk yields one entry per attached link, so the result is the set of files that together constitute the device — which is what an evidence record needs to name.
The chain may be shorter than the image requires: if the last entry reports IsDifferencing, its parent was never attached, and ParentResolveError explains why. Reads into that parent's ranges fail with ErrParentRequired.
func (*VirtualDisk) ChainComplete ¶
func (d *VirtualDisk) ChainComplete() bool
ChainComplete reports whether every link the chain needs is attached, meaning the whole virtual disk is readable.
func (*VirtualDisk) ChainDepth ¶
func (d *VirtualDisk) ChainDepth() int
ChainDepth returns the number of disks backing this one, including itself. A fixed or dynamic disk has depth 1.
func (*VirtualDisk) Close ¶
func (d *VirtualDisk) Close() error
Close releases any resources held by the disk, including parents opened by automatic chain resolution. Parents attached by hand with SetParent are left alone; their lifetime stays with whoever opened them.
The first error encountered is returned, but every link is still closed.
func (*VirtualDisk) DiskType ¶
func (d *VirtualDisk) DiskType() types.DiskType
DiskType returns the disk type (fixed, dynamic, differencing).
func (*VirtualDisk) Extents ¶
func (d *VirtualDisk) Extents(virtualOffset, length int64) ([]Extent, error)
Extents maps a range of the virtual disk to the runs that back it.
This is the sparse-aware view of the disk: an acquisition or carving tool can walk the extents, read only what is mapped, and skip zero runs instead of reading and writing megabytes of zeroes. For a differencing chain each mapped extent also identifies which disk in the chain supplies it, which VirtualToFileOffset cannot express.
Adjacent runs are merged when they share a kind and, for mapped runs, continue contiguously in the same file. The returned extents tile the requested range exactly, clamped to the disk size, and are ordered by VirtualOffset.
A range resolving to a parent that has not been attached yields ExtentUnresolved rather than an error, so a caller can discover which parts of a chain it is missing.
func (*VirtualDisk) Format ¶
func (d *VirtualDisk) Format() types.FileFormat
Format returns the file format.
func (*VirtualDisk) GUIDString ¶
func (d *VirtualDisk) GUIDString() string
GUIDString returns the disk identifier as a formatted GUID string.
func (*VirtualDisk) HasLog ¶
func (d *VirtualDisk) HasLog() bool
HasLog reports whether this VHDX image's active header carries a log GUID, meaning it holds journalled writes. This is true whether or not the log was replayable, so it is the right signal for recording that an image was captured mid-write.
func (*VirtualDisk) Identifier ¶
func (d *VirtualDisk) Identifier() [16]byte
Identifier returns the disk's unique identifier GUID.
func (*VirtualDisk) IsDifferencing ¶
func (d *VirtualDisk) IsDifferencing() bool
IsDifferencing reports whether this is a differencing (child) disk.
func (*VirtualDisk) IsDirty ¶
func (d *VirtualDisk) IsDirty() bool
IsDirty reports whether this image carries a log that was not replayed, in which case its block allocation table and metadata may be stale and the decoded contents may not reflect the last committed state.
Such an image only opens when Options.AllowDirtyImage is set, since either the log held no valid entries or its sequence was incomplete.
func (*VirtualDisk) LogReplayStats ¶
func (d *VirtualDisk) LogReplayStats() (LogReplayStats, bool)
LogReplayStats returns what the log replay applied, and false if no log was replayed.
The sector count is a useful evidentiary signal: it measures how much of the image was still in flight when the file was captured.
func (*VirtualDisk) LogReplayed ¶
func (d *VirtualDisk) LogReplayed() bool
LogReplayed reports whether the image's log was replayed into an in-memory overlay, in which case reads present the last committed state. The file itself is never modified.
func (*VirtualDisk) MappedBytes ¶
func (d *VirtualDisk) MappedBytes() (int64, error)
MappedBytes returns how many bytes of the disk are backed by real data, which for a sparse image is what an acquisition actually has to read.
func (*VirtualDisk) NeedsParent ¶
func (d *VirtualDisk) NeedsParent() bool
NeedsParent reports whether this disk is a differencing disk whose parent has not been attached yet. Reads that resolve to the parent fail with ErrParentRequired while this is true.
func (*VirtualDisk) Parent ¶
func (d *VirtualDisk) Parent() *VirtualDisk
Parent returns the attached parent disk, or nil if none is attached.
func (*VirtualDisk) ParentFilename ¶
func (d *VirtualDisk) ParentFilename() string
ParentFilename returns the parent disk path for a differencing disk.
func (*VirtualDisk) ParentIdentifier ¶
func (d *VirtualDisk) ParentIdentifier() [16]byte
ParentIdentifier returns the parent disk GUID for a VHD differencing disk. Returns a zero GUID if this is not a differencing VHD.
func (*VirtualDisk) ParentLocators ¶
func (d *VirtualDisk) ParentLocators() []types.ParentLocatorEntry
ParentLocators returns the parent locator entries recorded in a differencing disk, which may carry candidate paths to the parent image.
func (*VirtualDisk) ParentResolveError ¶
func (d *VirtualDisk) ParentResolveError() error
ParentResolveError reports why automatic parent chain resolution stopped short, or nil if the chain is complete or no resolution was attempted.
Resolution is best-effort by default, so a disk can open successfully with an incomplete chain. Reads that need the missing parent fail with ErrParentRequired rather than returning zeroes.
func (*VirtualDisk) Path ¶
func (d *VirtualDisk) Path() string
Path returns the filesystem path this disk was opened from, or "" when it was opened from a bare io.ReaderAt.
func (*VirtualDisk) ReadAt ¶
func (d *VirtualDisk) ReadAt(p []byte, offset int64) (int, error)
ReadAt reads len(p) bytes from the virtual disk at the given virtual offset. Implements io.ReaderAt.
Reads are clamped to the virtual disk size: a request straddling the end of the device returns the available bytes and io.EOF. Without clamping, callers would receive trailing block padding — and, for fixed VHDs, the file footer — as if it were disk content.
func (*VirtualDisk) SectorSize ¶
func (d *VirtualDisk) SectorSize() uint32
SectorSize returns the logical sector size in bytes.
func (*VirtualDisk) SetParent ¶
func (d *VirtualDisk) SetParent(parent *VirtualDisk) error
SetParent wires a parent disk for this differencing disk. After calling SetParent, reads on unallocated blocks are transparently satisfied by the parent disk. Returns an error if the disk is not a differencing disk or if the parent's virtual size doesn't match.
func (*VirtualDisk) Size ¶
func (d *VirtualDisk) Size() uint64
Size returns the total virtual disk size in bytes.
func (*VirtualDisk) VirtualToFileOffset ¶
func (d *VirtualDisk) VirtualToFileOffset(virtualOffset int64) (fileOffset int64, mapped bool, err error)
VirtualToFileOffset resolves a virtual disk byte offset to an absolute byte offset in the backing file when a direct mapping exists.
The returned mapped flag is false for sparse/unallocated regions (virtual zeros) and for differencing disks, where a single file offset cannot express the answer because different byte ranges come from different files in the chain. Use Extents for those: it resolves per sector and reports which disk in the chain backs each run.
Offsets returned by this method are absolute from the start of the backing VHD/VHDX file, not relative to BAT/region/block structures.