Documentation
¶
Index ¶
Constants ¶
const DefaultMaxDataSize = maxDataSize
DefaultMaxDataSize is the most bytes one ReadFile / ReadStream / directory read will materialise from a real NTFS volume unless SetMaxDataSize says otherwise. A sparse file legitimately reads back as far more bytes than the image holds, so this is a ceiling on the amplification, not a structural bound; the structural bounds (a run must lie inside the image, metadata is never sparse) are applied first.
const MaxLabelLen = 128
MaxLabelLen is the cap we enforce on the volume label. The real NTFS limit is 32 UTF-16 code units (~64 on-disk bytes); we use a slightly generous byte cap here since this mock driver stores raw bytes — that gives users headroom while still rejecting absurdly long input.
Variables ¶
var ErrReadOnlyReader = errors.New("ntfs: this filesystem was opened over a reader that cannot be written")
ErrReadOnlyReader is what a write gets when the filesystem was opened over something that can only be read.
var ErrShrinkTooSmall = errors.New("ntfs: shrink target smaller than highest used offset")
ErrShrinkTooSmall is returned by Shrink and Resize when the requested new size is smaller than the highest byte currently occupied by a live file blob. Callers must Compact or delete files before retrying.
var ErrTooLarge = safeio.ErrTooLarge
ErrTooLarge is wrapped by the error a read returns when the data it would have to materialise exceeds the ceiling. Test it with errors.Is.
Functions ¶
func Format ¶
func Format(path string, sizeBytes int64, cfg FormatConfig) (filesystem.Filesystem, error)
func OpenReader ¶ added in v0.2.0
func OpenReader(r io.ReaderAt, size int64) (filesystem.Filesystem, error)
OpenReader opens the NTFS volume that starts at offset zero of r.
It exists so this driver fits the one shape the rest of go-filesystems agrees on: github.com/go-filesystems/detect's Opener is func(io.ReaderAt, int64) (filesystem.Filesystem, error), and until now this driver could only be opened from a PATH. A caller with an image already open -- a partition inside a disk image, a section of a larger file, an image in memory -- had to write it to a temporary file first, and detect.Register could not be given this driver at all.
There is no partition index: r is expected to begin at the filesystem, which is what detect has just established by reading the magic there. Open remains the way to look through a partition table.
WRITES need an io.WriterAt. A reader that is only a reader gives a filesystem that serves every read and refuses every write with ErrReadOnlyReader -- rather than one that accepts a write and loses it.
The richer FS interface this package's Open returns is still there: a caller that wants Layout, Compact or the fragmentation statistics can assert for it. What is returned here is filesystem.Filesystem because that is what detect.Opener is, and fitting it is the point.
The reader is NOT closed by Close: the caller opened it and still owns it. That is the same division as iso9660, squashfs, hfsplus and ufs, whose reader-based constructors have always worked this way.
Types ¶
type DataLimiter ¶ added in v0.3.0
type DataLimiter interface {
// SetMaxDataSize sets the most bytes one read may allocate. n <= 0
// restores DefaultMaxDataSize. A read over the ceiling fails with an error
// wrapping ErrTooLarge before anything is allocated.
SetMaxDataSize(n int64)
}
DataLimiter is implemented by the filesystem Open and OpenReader return for a genuine NTFS volume. A caller reading untrusted images asserts for it to lower the per-read ceiling:
if l, ok := fs.(ntfs.DataLimiter); ok {
l.SetMaxDataSize(64 << 20)
}
type FS ¶
type FS interface {
filesystem.Filesystem
FragmentationStats() (files int, used uint64, freeExtents int, totalFree uint64, largestFree uint64)
Layout() []FileLayout
Compact() error
Symlink(target, linkPath string) error
Label() string
SetLabel(label string) error
Grow(newSizeBytes int64) error
Shrink(newSizeBytes int64) error
Resize(newSizeBytes int64) error
}
FS is the public interface returned by Open. It extends filesystem.Filesystem with NTFS-specific operations (fragmentation analysis, compaction and NTFSIMG1 image resize). Callers that only need the generic interface can use it directly; callers that want the extras type-assert (or accept *FS via Open's return type).
NOTE: Grow / Shrink / Resize operate on the NTFSIMG1 image format this driver implements, NOT on real NTFS. Resizing a real NTFS volume would require manipulating the MFT, $Bitmap and runlists and is a separate, much larger project.
type FileLayout ¶
FileLayout describes a stored file blob location inside the image.
type FormatConfig ¶
type FormatConfig struct{ Label string }
Format creates a fresh NTFS-like image at path with the given size.
type StreamReader ¶
type StreamReader interface {
// ListStreams returns the names of every $DATA stream on the file, with
// the unnamed default stream represented by "". Names are sorted and
// de-duplicated.
ListStreams(path string) ([]string, error)
// ReadStream returns the full content of the named $DATA stream (name ""
// selects the default stream), transparently decompressing LZNT1 data.
ReadStream(path, name string) ([]byte, error)
}
StreamReader is the optional capability, satisfied by the real-NTFS reader, for enumerating and reading a file's named data streams (alternate data streams). The unnamed default stream is reported as "".
if sr, ok := fs.(ntfs.StreamReader); ok {
names, _ := sr.ListStreams("/notes.txt") // ["", "author"]
b, _ := sr.ReadStream("/notes.txt", "author")
}
