exfat

package module
v0.0.0-...-5e932fb Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 6, 2019 License: MIT Imports: 14 Imported by: 0

README

GoDoc Build Status Coverage Status Go Report Card

Overview

This is a read-only exFAT implementation based on the Microsoft-published specs (exFAT file system specification). The primary purpose of this project is to provide an unprivileged API to access an exFAT filesystem from any platform. This project also provides several tools that can be used to explore the filesystem and extract files from it.

Command-Line Tools

  • exfat_list_contents: List all files with or without complete directory-entry information.
  • exfat_extract_file: Extract a single file to a file or STDOUT. May also be used to print all clusters and sectors visited for the extraction.
  • exfat_print_boot_sector_header: Dump filesystem parameters. Largely sourced from the boot-sector header.

Notes

  • All entry-types are parsed as per the requirements of the specification. However:

    • Up-case tables, which support case insensitivity, are not read and therefore not applied. As a result, all file-operations are case-sensitive (and the villagers rejoiced).

    • Allocation bitmaps are not read, so it's not possible to know which clusters are or are not used. This is not required for browsing the filesystem or reading files.

  • Timestamps are accurate to one second.

Documentation

Index

Constants

View Source
const (
	// VolumeFlagActiveFat : This field is mandatory and Section 3.1.13.1 defines its contents.
	//
	// The ActiveFat field shall describe which FAT and Allocation Bitmap are active (and implementations shall use), as follows:
	//
	// 0, which means the First FAT and First Allocation Bitmap are active
	//
	// 1, which means the Second FAT and Second Allocation Bitmap are active and is possible only when the NumberOfFats field contains the value 2
	//
	// Implementations shall consider the inactive FAT and Allocation Bitmap as stale. Only TexFAT-aware implementations shall switch the active FAT and Allocation Bitmaps (see Section 7.1).
	VolumeFlagActiveFat VolumeFlags = 1

	// VolumeFlagVolumeDirty : This field is mandatory and Section 3.1.13.2 defines its contents.
	//
	// The VolumeDirty field shall describe whether the volume is dirty or not, as follows:
	//
	// 0, which means the volume is probably in a consistent state
	//
	// 1, which means the volume is probably in an inconsistent state
	//
	// Implementations should set the value of this field to 1 upon encountering file system metadata inconsistencies which they do not resolve. If, upon mounting a volume, the value of this field is 1, only implementations which resolve file system metadata inconsistencies may clear the value of this field to 0. Such implementations shall only clear the value of this field to 0 after ensuring the file system is in a consistent state.
	//
	// If, upon mounting a volume, the value of this field is 0, implementations should set this field to 1 before updating file system metadata and clear this field to 0 afterwards, similar to the recommended write ordering described in Section 8.1.
	VolumeFlagVolumeDirty = 2

	// VolumeFlagMediaFailure : This field is mandatory and Section 3.1.13.3 defines its contents.
	//
	// The MediaFailure field shall describe whether an implementation has discovered media failures or not, as follows:
	//
	// 0, which means the hosting media has not reported failures or any known failures are already recorded in the FAT as "bad" clusters
	//
	// 1, which means the hosting media has reported failures (i.e. has failed read or write operations)
	//
	// An implementation should set this field to 1 when:
	//
	// The hosting media fails access attempts to any region in the volume
	//
	// The implementation has exhausted access retry algorithms, if any
	//
	// If, upon mounting a volume, the value of this field is 1, implementations which scan the entire volume for media failures and record all failures as "bad" clusters in the FAT (or otherwise resolve media failures) may clear the value of this field to 0.
	VolumeFlagMediaFailure = 4

	// VolumeFlagClearToZero : This field is mandatory and Section 3.1.13.4 defines its contents.
	//
	// 3.1.13.4 ClearToZero Field
	// The ClearToZero field does not have significant meaning in this specification.
	//
	// The valid values for this field are:
	//
	// 0, which does not have any particular meaning
	//
	// 1, which means implementations shall clear this field to 0 prior to modifying any file system structures, directories, or files
	VolumeFlagClearToZero = 8
)

Variables

This section is empty.

Functions

func UnicodeFromAscii

func UnicodeFromAscii(raw []byte, unicodeCharCount int) string

UnicodeFromAscii returns Unicode from raw utf16 data.

Types

type BootSectorHeader

type BootSectorHeader struct {
	// JumpBoot: This field is mandatory and Section 3.1.1 defines its contents.
	//
	// The JumpBoot field shall contain the jump instruction for CPUs common in personal computers, which, when executed, "jumps" the CPU to execute the boot-strapping instructions in the BootCode field.
	//
	// The valid value for this field is (in order of low-order byte to high-order byte) EBh 76h 90h.
	JumpBoot [3]byte

	// FileSystemName: This field is mandatory and Section 3.1.2 defines its contents.
	//
	// The FileSystemName field shall contain the name of the file system on the volume.
	//
	// The valid value for this field is, in ASCII characters, "EXFAT   ", which includes three trailing white spaces.
	FileSystemName [8]byte

	// MustBeZero: This field is mandatory and Section 3.1.3 defines its contents.
	//
	// The MustBeZero field shall directly correspond with the range of bytes the packed BIOS parameter block consumes on FAT12/16/32 volumes.
	//
	// The valid value for this field is 0, which helps to prevent FAT12/16/32 implementations from mistakenly mounting an exFAT volume.
	MustBeZero [53]byte

	// PartitionOffset: This field is mandatory and Section 3.1.4 defines its contents.
	//
	// The PartitionOffset field shall describe the media-relative sector offset of the partition which hosts the given exFAT volume. This field aids boot-strapping from the volume using extended INT 13h on personal computers.
	//
	// All possible values for this field are valid; however, the value 0 indicates implementations shall ignore this field.
	PartitionOffset uint64

	// VolumeLength: This field is mandatory and Section 3.1.5 defines its contents.
	//
	// The VolumeLength field shall describe the size of the given exFAT volume in sectors.
	//
	// The valid range of values for this field shall be:
	//
	// At least 220/ 2BytesPerSectorShift, which ensures the smallest volume is no less than 1MB
	//
	// At most 264- 1, the largest value this field can describe
	//
	// However, if the size of the Excess Space sub-region is 0, then the value of this field is ClusterHeapOffset + (232- 11) * 2SectorsPerClusterShift.
	VolumeLength uint64

	// FatOffset: This field is mandatory and Section 3.1.6 defines its contents.
	//
	// The FatOffset field shall describe the volume-relative sector offset of the First FAT. This field enables implementations to align the First FAT to the characteristics of the underlying storage media.
	//
	// The valid range of values for this field shall be:
	//
	// At least 24, which accounts for the sectors the Main Boot and Backup Boot regions consume
	//
	// At most ClusterHeapOffset - (FatLength * NumberOfFats), which accounts for the sectors the Cluster Heap consumes
	FatOffset uint32

	// FatLength: This field is mandatory and Section 3.1.7 defines its contents.
	//
	// The FatLength field shall describe the length, in sectors, of each FAT table (the volume may contain up to two FATs).
	//
	// The valid range of values for this field shall be:
	//
	// At least (ClusterCount + 2) * 22/ 2BytesPerSectorShiftrounded up to the nearest integer, which ensures each FAT has sufficient space for describing all the clusters in the Cluster Heap
	//
	// At most (ClusterHeapOffset - FatOffset) / NumberOfFats rounded down to the nearest integer, which ensures the FATs exist before the Cluster Heap
	//
	// This field may contain a value in excess of its lower bound (as described above) to enable the Second FAT, if present, to also be aligned to the characteristics of the underlying storage media. The contents of the space which exceeds what the FAT itself requires, if any, are undefined.
	FatLength uint32

	// ClusterHeapOffset: This field is mandatory and Section 3.1.8 defines its contents.
	//
	// The ClusterHeapOffset field shall describe the volume-relative sector offset of the Cluster Heap. This field enables implementations to align the Cluster Heap to the characteristics of the underlying storage media.
	//
	// The valid range of values for this field shall be:
	//
	// At least FatOffset + FatLength * NumberOfFats, to account for the sectors all the preceding regions consume
	//
	// At most 232- 1 or VolumeLength - (ClusterCount * 2SectorsPerClusterShift), whichever calculation is less
	ClusterHeapOffset uint32

	// ClusterCount: This field is mandatory and Section 3.1.9 defines its contents.
	//
	// The ClusterCount field shall describe the number of clusters the Cluster Heap contains.
	//
	// The valid value for this field shall be the lesser of the following:
	//
	// (VolumeLength - ClusterHeapOffset) / 2SectorsPerClusterShiftrounded down to the nearest integer, which is exactly the number of clusters which can fit between the beginning of the Cluster Heap and the end of the volume
	//
	// 232- 11, which is the maximum number of clusters a FAT can describe
	//
	// The value of the ClusterCount field determines the minimum size of a FAT. To avoid extremely large FATs, implementations can control the number of clusters in the Cluster Heap by increasing the cluster size (via the SectorsPerClusterShift field). This specification recommends no more than 224- 2 clusters in the Cluster Heap. However, implementations shall be able to handle volumes with up to 232- 11 clusters in the Cluster Heap.
	ClusterCount uint32

	// FirstClusterOfRootDirectory: This field is mandatory and Section 3.1.10 defines its contents.
	//
	// The FirstClusterOfRootDirectory field shall contain the cluster index of the first cluster of the root directory. Implementations should make every effort to place the first cluster of the root directory in the first non-bad cluster after the clusters the Allocation Bitmap and Up-case Table consume.
	//
	// The valid range of values for this field shall be:
	//
	// At least 2, the index of the first cluster in the Cluster Heap
	//
	// At most ClusterCount + 1, the index of the last cluster in the Cluster Heap
	FirstClusterOfRootDirectory uint32

	// VolumeSerialNumber: This field is mandatory and Section 3.1.11 defines its contents.
	//
	// The VolumeSerialNumber field shall contain a unique serial number. This assists implementations to distinguish among different exFAT volumes. Implementations should generate the serial number by combining the date and time of formatting the exFAT volume. The mechanism for combining date and time to form a serial number is implementation-specific.
	//
	// All possible values for this field are valid.
	VolumeSerialNumber uint32

	// FileSystemRevision: This field is mandatory and Section 3.1.12 defines its contents.
	//
	// The FileSystemRevision field shall describe the major and minor revision numbers of the exFAT structures on the given volume.
	//
	// The high-order byte is the major revision number and the low-order byte is the minor revision number. For example, if the high-order byte contains the value 01h and if the low-order byte contains the value 05h, then the FileSystemRevision field describes the revision number 1.05. Likewise, if the high-order byte contains the value 0Ah and if the low-order byte contains the value 0Fh, then the FileSystemRevision field describes the revision number 10.15.
	//
	// The valid range of values for this field shall be:
	//
	// At least 0 for the low-order byte and 1 for the high-order byte
	//
	// At most 99 for the low-order byte and 99 for the high-order byte
	//
	// The revision number of exFAT this specification describes is 1.00. Implementations of this specification should mount any exFAT volume with major revision number 1 and shall not mount any exFAT volume with any other major revision number. Implementations shall honor the minor revision number and shall not perform operations or create any file system structures not described in the given minor revision number's corresponding specification.
	FileSystemRevision [2]uint8

	// VolumeFlags: This field is mandatory and Section 3.1.13 defines its contents.
	//
	// The VolumeFlags field shall contain flags which indicate the status of various file system structures on the exFAT volume (see Table 5).
	//
	// Implementations shall not include this field when computing its respective Main Boot or Backup Boot region checksum. When referring to the Backup Boot Sector, implementations shall treat this field as stale.
	VolumeFlags VolumeFlags

	// BytesPerSectorShift: This field is mandatory and Section 3.1.14 defines its contents.
	//
	// The BytesPerSectorShift field shall describe the bytes per sector expressed as log~2~(N), where N is the number of bytes per sector. For example, for 512 bytes per sector, the value of this field is 9.
	//
	// The valid range of values for this field shall be:
	//
	// At least 9 (sector size of 512 bytes), which is the smallest sector possible for an exFAT volume
	//
	// At most 12 (sector size of 4096 bytes), which is the memory page size of CPUs common in personal computers
	BytesPerSectorShift uint8

	// SectorsPerClusterShift: This field is mandatory and Section 3.1.15 defines its contents.
	//
	// The SectorsPerClusterShift field shall describe the sectors per cluster expressed as log~2~(N), where N is number of sectors per cluster. For example, for 8 sectors per cluster, the value of this field is 3.
	//
	// The valid range of values for this field shall be:
	//
	// At least 0 (1 sector per cluster), which is the smallest cluster possible
	//
	// At most 25 - BytesPerSectorShift, which evaluates to a cluster size of 32MB
	SectorsPerClusterShift uint8

	// NumberOfFats: This field is mandatory and Section 3.1.16 defines its contents.
	//
	// The NumberOfFats field shall describe the number of FATs and Allocation Bitmaps the volume contains.
	//
	// The valid range of values for this field shall be:
	//
	// 1, which indicates the volume only contains the First FAT and First Allocation Bitmap
	//
	// 2, which indicates the volume contains the First FAT, Second FAT, First Allocation Bitmap, and Second Allocation Bitmap; this value is only valid for TexFAT volumes
	NumberOfFats uint8

	// DriveSelect: This field is mandatory and Section 3.1.17 defines its contents.
	//
	// The DriveSelect field shall contain the extended INT 13h drive number, which aids boot-strapping from this volume using extended INT 13h on personal computers.
	//
	// All possible values for this field are valid. Similar fields in previous FAT-based file systems frequently contained the value 80h.
	DriveSelect uint8

	// PercentInUse: This field is mandatory and Section 3.1.18 defines its contents.
	//
	// The PercentInUse field shall describe the percentage of clusters in the Cluster Heap which are allocated.
	//
	// The valid range of values for this field shall be:
	//
	// Between 0 and 100 inclusively, which is the percentage of allocated clusters in the Cluster Heap, rounded down to the nearest integer
	//
	// Exactly FFh, which indicates the percentage of allocated clusters in the Cluster Heap is not available
	//
	// Implementations shall change the value of this field to reflect changes in the allocation of clusters in the Cluster Heap or shall change it to FFh.
	//
	// Implementations shall not include this field when computing its respective Main Boot or Backup Boot region checksum. When referring to the Backup Boot Sector, implementations shall treat this field as stale.
	PercentInUse uint8

	// Reserved: This field is mandatory and its contents are reserved.
	Reserved [7]byte

	// BootCode: This field is mandatory and Section 3.1.19 defines its contents.
	//
	// The BootCode field shall contain boot-strapping instructions. Implementations may populate this field with the CPU instructions necessary for boot-strapping a computer system. Implementations which don't provide boot-strapping instructions shall initialize each byte in this field to F4h (the halt instruction for CPUs common in personal computers) as part of their format operation.
	BootCode [390]byte

	// BootSignature: This field is mandatory and Section 3.1.20 defines its contents.
	//
	// The BootSignature field shall describe whether the intent of a given sector is for it to be a Boot Sector or not.
	//
	// The valid value for this field is AA55h. Any other value in this field invalidates its respective Boot Sector. Implementations should verify the contents of this field prior to depending on any other field in its respective Boot Sector.
	BootSignature uint16
}

BootSectorHeader describes the main set of filesystem parameters.

func (BootSectorHeader) Dump

func (bsh BootSectorHeader) Dump()

Dump prints all of the BSH parameters along with the common calculated ones.

func (BootSectorHeader) SectorSize

func (bsh BootSectorHeader) SectorSize() uint32

SectorSize returns the effective sector-size.

func (BootSectorHeader) SectorsPerCluster

func (bsh BootSectorHeader) SectorsPerCluster() uint32

SectorsPerCluster returns the effective sectors-per-cluster count.

func (BootSectorHeader) String

func (bsh BootSectorHeader) String() string

Strings return a description of BSH.

type ClusterVisitorFunc

type ClusterVisitorFunc func(ec *ExfatCluster) (doContinue bool, err error)

ClusterVisitorFunc is a visitor callback as all clusters in the chain are visited.

type DirectoryEntry

type DirectoryEntry interface {
	TypeName() string
}

DirectoryEntry represents any of the directory-entry structs defined here.

type DirectoryEntryIndex

type DirectoryEntryIndex map[string][]IndexedDirectoryEntry

DirectoryEntryIndex is a collection of all indexed-directory-entries in a specific directory. This is colloquially referred to simply as an "index".

func (DirectoryEntryIndex) Dump

func (dei DirectoryEntryIndex) Dump()

Dump prints a bunch of information about an index.

func (DirectoryEntryIndex) FileCount

func (dei DirectoryEntryIndex) FileCount() (count int)

FileCount returns the number of files in the directory.

func (DirectoryEntryIndex) Filenames

func (dei DirectoryEntryIndex) Filenames() (filenames map[string]bool)

Filenames returns a map of all filenames in the directory and whether they are directories or just files.

func (DirectoryEntryIndex) FindIndexedFile

func (dei DirectoryEntryIndex) FindIndexedFile(filename string) (ide IndexedDirectoryEntry, found bool)

FindIndexedFile returns an IDE for a given file.

func (DirectoryEntryIndex) FindIndexedFileDirectoryEntry

func (dei DirectoryEntryIndex) FindIndexedFileDirectoryEntry(filename, entryTypeName string, i int) (de DirectoryEntry)

FindIndexedFileDirectoryEntry returns the i'th occurrence of the given entry- type under the given file.

func (DirectoryEntryIndex) FindIndexedFileFileDirectoryEntry

func (dei DirectoryEntryIndex) FindIndexedFileFileDirectoryEntry(filename string) (fdf *ExfatFileDirectoryEntry)

FindIndexedFileFileDirectoryEntry is a convenience function to get the FDE for the given file.

func (DirectoryEntryIndex) FindIndexedFileStreamExtensionDirectoryEntry

func (dei DirectoryEntryIndex) FindIndexedFileStreamExtensionDirectoryEntry(filename string) (sede *ExfatStreamExtensionDirectoryEntry)

FindIndexedFileStreamExtensionDirectoryEntry is a convenience function to get the SEDE for the given file.

func (DirectoryEntryIndex) GetFile

func (dei DirectoryEntryIndex) GetFile(i int) (filename string, fdf *ExfatFileDirectoryEntry)

GetFile returns the file directory-entry with index `i`.

type DirectoryEntryParserKey

type DirectoryEntryParserKey struct {
	// contains filtered or unexported fields
}

DirectoryEntryParserKey describes the combination of attributes that uniquely identify an entry-type (`isCritical` corresponds directly to `TypeImportance` and `isPrimary` corresponds directly to `TypeCategory`):

6.2.1.1 TypeCode Field

The TypeCode field partially describes the specific type of the given directory entry. This field, plus the TypeImportance and TypeCategory fields (see Sections 6.2.1.2 and 6.2.1.3, respectively) uniquely identify the type of the given directory entry.

func (DirectoryEntryParserKey) String

func (depk DirectoryEntryParserKey) String() string

String returns a descriptive string.

type DirectoryEntryVisitorFunc

type DirectoryEntryVisitorFunc func(primaryEntry DirectoryEntry, secondaryEntries []DirectoryEntry) (err error)

DirectoryEntryVisitorFunc is a function type used as a callback over each file directory entry.

type DumpableDirectoryEntry

type DumpableDirectoryEntry interface {
	Dump()
}

DumpableDirectoryEntry represents any directory-entry that can dump its information to the screen. This is really just DEs that we've taken the time to do this for that also contain a wealth of information.

type EntryType

type EntryType uint8

EntryType allows us to decompose an EntryType value.

func (EntryType) Dump

func (et EntryType) Dump()

Dump dumps all flags/states embedded in the entry-type value.

func (EntryType) IsBenign

func (et EntryType) IsBenign() bool

IsBenign indicates whether 'importance' is set (disabled).

func (EntryType) IsCritical

func (et EntryType) IsCritical() bool

IsCritical indicates whether 'importance' is cleared (enabled).

func (EntryType) IsEndOfDirectory

func (et EntryType) IsEndOfDirectory() bool

IsEndOfDirectory indicates that this is the last entry in the directory.

func (EntryType) IsInUse

func (et EntryType) IsInUse() bool

IsInUse indicates that the entry is not unused, i.e. a regular directory- entry.

func (EntryType) IsPrimary

func (et EntryType) IsPrimary() bool

IsPrimary indicates whether 'category' is cleared (enabled).

func (EntryType) IsRegular

func (et EntryType) IsRegular() bool

IsRegular indicates that this entry is a normal directory entry and unremarkable.

func (EntryType) IsSecondary

func (et EntryType) IsSecondary() bool

IsSecondary indicates whether 'category' is set (disabled).

func (EntryType) IsUnusedEntryMarker

func (et EntryType) IsUnusedEntryMarker() bool

IsUnusedEntryMarker indicates that the directory-entry is a placeholder.

func (EntryType) String

func (et EntryType) String() string

String returns a descriptive string.

func (EntryType) TypeCategory

func (et EntryType) TypeCategory() bool

TypeCategory indicates whether this is a primary record or a secondary entry (which will *accompany* a primary entry).

func (EntryType) TypeCode

func (et EntryType) TypeCode() int

TypeCode indicates the general type of the entry. This is not unique unless combined with the 'importance' flag and 'critical' flag.

func (EntryType) TypeImportance

func (et EntryType) TypeImportance() bool

TypeImportance indicates whether or not this is a mandatory or options entry- type.

type ExfatAllocationBitmapDirectoryEntry

type ExfatAllocationBitmapDirectoryEntry struct {
	// EntryType: This field is mandatory and Section 7.1.1 defines its contents.
	EntryType EntryType

	// BitmapFlags: This field is mandatory and Section 7.1.2 defines its contents.
	BitmapFlags uint8

	// Reserved: This field is mandatory and its contents are reserved.
	Reserved [18]byte

	// FirstCluster: This field is mandatory and Section 7.1.3 defines its contents.
	FirstCluster uint32

	// DataLength: This field is mandatory and Section 7.1.4 defines its contents.
	DataLength uint64
}

ExfatAllocationBitmapDirectoryEntry points to the cluster that has the allocation bitmap.

func (ExfatAllocationBitmapDirectoryEntry) String

String returns a string description.

func (ExfatAllocationBitmapDirectoryEntry) TypeName

TypeName returns a unique name for this entry-type.

type ExfatCluster

type ExfatCluster struct {
	// contains filtered or unexported fields
}

ExfatCluster manages reads on the sectors in a cluster and checks that the requested sectors are within bounds.

func (*ExfatCluster) ClusterNumber

func (ec *ExfatCluster) ClusterNumber() uint32

ClusterNumber gets the number of the cluster that this instance represents.

func (*ExfatCluster) EnumerateSectors

func (ec *ExfatCluster) EnumerateSectors(cb SectorVisitorFunc) (err error)

EnumerateSectors calls the given callback for each sector in the cluster that this instance represents.

func (*ExfatCluster) GetSectorByIndex

func (ec *ExfatCluster) GetSectorByIndex(sectorIndex uint32) (data []byte, err error)

GetSectorByIndex gets the data for the given sector within the cluster that this instance represents.

type ExfatFileDirectoryEntry

type ExfatFileDirectoryEntry struct {
	// EntryType: This field is mandatory and Section 7.4.1 defines its contents.
	EntryType EntryType

	// SecondaryCount: This field is mandatory and Section 7.4.2 defines its contents.
	SecondaryCountRaw uint8

	// SetChecksum: This field is mandatory and Section 7.4.3 defines its contents.
	SetChecksum uint16

	// FileAttributes: This field is mandatory and Section 7.4.4 defines its contents.
	FileAttributes FileAttributes

	// Reserved1: This field is mandatory and its contents are reserved.
	Reserved1 uint16

	// CreateTimestampRaw: This field is mandatory and Section 7.4.5 defines its contents.
	CreateTimestampRaw ExfatTimestamp

	// LastModifiedTimestampRaw: This field is mandatory and Section 7.4.6 defines its contents.
	LastModifiedTimestampRaw ExfatTimestamp

	// LastAccessedTimestampRaw: This field is mandatory and Section 7.4.7 defines its contents.
	LastAccessedTimestampRaw ExfatTimestamp

	// Create10msIncrement: This field is mandatory and Section 7.4.5 defines its contents.
	Create10msIncrement uint8

	// LastModified10msIncrement: This field is mandatory and Section 7.4.6 defines its contents.
	LastModified10msIncrement uint8

	// CreateUtcOffset: This field is mandatory and Section 7.4.5 defines its contents.
	CreateUtcOffset uint8

	// LastModifiedUtcOffset: This field is mandatory and Section 7.4.6 defines its contents.
	LastModifiedUtcOffset uint8

	// LastAccessedUtcOffset: This field is mandatory and Section 7.4.7 defines its contents.
	LastAccessedUtcOffset uint8

	// Reserved2: This field is mandatory and its contents are reserved.
	Reserved2 [7]byte
}

ExfatFileDirectoryEntry describes file entries.

func (ExfatFileDirectoryEntry) CreateTimestamp

func (fdf ExfatFileDirectoryEntry) CreateTimestamp() time.Time

CreateTimestamp returns the offset-corrected ctime.

func (ExfatFileDirectoryEntry) Dump

func (fdf ExfatFileDirectoryEntry) Dump()

Dump prints the file entry's info to STDOUT.

func (ExfatFileDirectoryEntry) LastAccessedTimestamp

func (fdf ExfatFileDirectoryEntry) LastAccessedTimestamp() time.Time

LastAccessedTimestamp returns the offset-corrected atime.

func (ExfatFileDirectoryEntry) LastModifiedTimestamp

func (fdf ExfatFileDirectoryEntry) LastModifiedTimestamp() time.Time

LastModifiedTimestamp returns the offset-corrected mtime.

func (ExfatFileDirectoryEntry) SecondaryCount

func (fdf ExfatFileDirectoryEntry) SecondaryCount() uint8

SecondaryCount indicates how many of the subsequent secondary entries should be collected to support this entry.

func (ExfatFileDirectoryEntry) String

func (fdf ExfatFileDirectoryEntry) String() string

String returns a descriptive string.

func (ExfatFileDirectoryEntry) TypeName

func (fdf ExfatFileDirectoryEntry) TypeName() string

TypeName returns a unique name for this entry-type.

type ExfatFileNameDirectoryEntry

type ExfatFileNameDirectoryEntry struct {
	// EntryType: This field is mandatory and Section 7.7.1 defines its contents.
	EntryType EntryType

	// GeneralSecondaryFlags: This field is mandatory and Section 7.7.2 defines its contents.
	GeneralSecondaryFlags GeneralSecondaryFlags

	// FileName: This field is mandatory and Section 7.7.3 defines its contents.
	FileName [30]byte
}

ExfatFileNameDirectoryEntry describes one part of the file's complete filename.

func (ExfatFileNameDirectoryEntry) String

func (fnde ExfatFileNameDirectoryEntry) String() string

String returns a descriptive string.

func (ExfatFileNameDirectoryEntry) TypeName

TypeName returns a unique name for this entry-type.

type ExfatNavigator

type ExfatNavigator struct {
	// contains filtered or unexported fields
}

ExfatNavigator knows how to get and manipulate the entries of a single directory.

func NewExfatNavigator

func NewExfatNavigator(er *ExfatReader, firstClusterNumber uint32) (en *ExfatNavigator)

NewExfatNavigator returns a new ExfatNavigator instance.

func (*ExfatNavigator) EnumerateDirectoryEntries

func (en *ExfatNavigator) EnumerateDirectoryEntries(cb DirectoryEntryVisitorFunc) (visitedClusters, visitedSectors []uint32, err error)

EnumerateDirectoryEntries will enumerate each primary directory entry associated with the given file along with an secondary entries that they're associated with.

func (*ExfatNavigator) IndexDirectoryEntries

func (en *ExfatNavigator) IndexDirectoryEntries() (index DirectoryEntryIndex, visitedClusters, visitedSectors []uint32, err error)

IndexDirectoryEntries builds an index for the current directory.

type ExfatReader

type ExfatReader struct {
	// contains filtered or unexported fields
}

ExfatReader knows where to find all of the statically-located structures and how to parse them, and how to find clusters and chains of clusters.

func NewExfatReader

func NewExfatReader(rs io.ReadSeeker) *ExfatReader

NewExfatReader returns a new instance of ExfatReader.

func (*ExfatReader) ActiveBootSectorHeader

func (er *ExfatReader) ActiveBootSectorHeader() BootSectorHeader

ActiveBootSectorHeader returns the active boot-sector struct (whether main or backup).

func (*ExfatReader) EnumerateClusters

func (er *ExfatReader) EnumerateClusters(startingClusterNumber uint32, cb ClusterVisitorFunc, useFat bool) (err error)

EnumerateClusters calls the given callback for each cluster in the chain starting from the given cluster.

func (*ExfatReader) FirstClusterOfRootDirectory

func (er *ExfatReader) FirstClusterOfRootDirectory() uint32

FirstClusterOfRootDirectory is the first-cluster of the directory-entry data.

func (*ExfatReader) GetCluster

func (er *ExfatReader) GetCluster(clusterNumber uint32) *ExfatCluster

GetCluster gets a Cluster instance for the given cluster.

func (*ExfatReader) Parse

func (er *ExfatReader) Parse() (err error)

Parse loads all of the main filesystem structures. This is always a small read (does not scale with size).

func (*ExfatReader) SectorSize

func (er *ExfatReader) SectorSize() uint32

SectorSize is the sector-size from the active FAT.

func (*ExfatReader) SectorsPerCluster

func (er *ExfatReader) SectorsPerCluster() uint32

SectorsPerCluster is the sectors-per-cluster from the active FAT.

func (*ExfatReader) WriteFromClusterChain

func (er *ExfatReader) WriteFromClusterChain(firstClusterNumber uint32, dataSize uint64, useFat bool, w io.Writer) (visitedClusters, visitedSectors []uint32, err error)

WriteFromClusterChain enumerates all sectors from all clusters starting from the given one.

type ExfatStreamExtensionDirectoryEntry

type ExfatStreamExtensionDirectoryEntry struct {

	// EntryType: This field is mandatory and Section 7.6.1 defines its contents.
	EntryType EntryType

	// GeneralSecondaryFlags: This field is mandatory and Section 7.6.2 defines its contents.
	GeneralSecondaryFlags GeneralSecondaryFlags

	// Reserved1: This field is mandatory and its contents are reserved.
	Reserved1 [1]byte

	// NameLength: This field is mandatory and Section 7.6.3 defines its contents.
	NameLength uint8

	// NameHash: This field is mandatory and Section 7.6.4 defines its contents.
	NameHash uint16

	// Reserved2: This field is mandatory and its contents are reserved.
	Reserved2 [2]byte

	// ValidDataLength: This field is mandatory and Section 7.6.5 defines its contents.
	//
	// NOTES
	//
	// - For files, `ValidDataLength` is the real amount of data. Ostensibly,
	//   subsequent updates to a file don't necessarily have to occupy as much
	//   space as is already allocated and this describes the actual data size.
	//   For directories, only `DataLength` should be considered.
	//
	//   From the spec (7.6.5 ValidDataLength Field):
	//
	//      The ValidDataLength field shall describe how far into the data
	//      stream user data has been written. Implementations shall update this
	//      field as they write data further out into the data stream. On the
	//      storage media, the data between the valid data length and the data
	//      length of the data stream is undefined. Implementations shall return
	//      zeroes for read operations beyond the valid data length.
	//
	//      If the corresponding File directory entry describes a directory,
	//      then the only valid value for this field is equal to the value of
	//      the DataLength field.
	//
	ValidDataLength uint64

	// Reserved3: This field is mandatory and its contents are reserved.
	Reserved3 [4]byte

	// FirstCluster: This field is mandatory and Section 7.6.6 defines its contents.
	//
	// NOTES
	//
	// - If a directory, this cluster has all of the subdirectories and files
	//   for that directory (formatted the same as the root directory located at
	//   cluster FirstClusterOfRootDirectory).
	//
	FirstCluster uint32

	// DataLength: This field is mandatory and Section 7.6.7 defines its contents.
	DataLength uint64
}

ExfatStreamExtensionDirectoryEntry describes the actual contents of a file.

func (ExfatStreamExtensionDirectoryEntry) Dump

Dump prints the stream entry's info to STDOUT.

func (ExfatStreamExtensionDirectoryEntry) String

String returns a descriptive string.

func (ExfatStreamExtensionDirectoryEntry) TypeName

TypeName returns a unique name for this entry-type.

type ExfatTexFATDirectoryEntry

type ExfatTexFATDirectoryEntry struct {
	// Reserved: Not covered by the exFAT specification. Just mask the whole thing as reserved.
	Reserved [32]byte
}

ExfatTexFATDirectoryEntry is a mobile-device entry-type that is not defined by exFAT.

func (ExfatTexFATDirectoryEntry) String

String returns a descriptive string.

func (ExfatTexFATDirectoryEntry) TypeName

func (ExfatTexFATDirectoryEntry) TypeName() string

TypeName returns a unique name for this entry-type.

type ExfatTimestamp

type ExfatTimestamp uint32

ExfatTimestamp is the raw packaged integer with timestamp information. It embeds its parsing semantics.

func (ExfatTimestamp) Day

func (et ExfatTimestamp) Day() int

Day returns the day component.

func (ExfatTimestamp) Hour

func (et ExfatTimestamp) Hour() int

Hour returns the hour component.

func (ExfatTimestamp) Minute

func (et ExfatTimestamp) Minute() int

Minute returns the minute component.

func (ExfatTimestamp) Month

func (et ExfatTimestamp) Month() int

Month returns the minute component.

func (ExfatTimestamp) Second

func (et ExfatTimestamp) Second() int

Second returns the second component.

func (ExfatTimestamp) TimestampWithOffset

func (et ExfatTimestamp) TimestampWithOffset(offset int) time.Time

TimestampWithOffset returns a location-corrected timestamp.

func (ExfatTimestamp) Year

func (et ExfatTimestamp) Year() int

Year returns the year component.

type ExfatUpcaseTableDirectoryEntry

type ExfatUpcaseTableDirectoryEntry struct {
	// EntryType: This field is mandatory and Section 7.2.1 defines its contents.
	EntryType EntryType

	// Reserved1: This field is mandatory and its contents are reserved.
	Reserved1 [3]byte

	// TableChecksum: This field is mandatory and Section 7.2.2 defines its contents.
	TableChecksum uint32

	// Reserved2: This field is mandatory and its contents are reserved.
	Reserved2 [12]byte

	// FirstCluster: This field is mandatory and Section 7.2.3 defines its contents.
	FirstCluster uint32

	// DataLength: This field is mandatory and Section 7.2.4 defines its contents.
	DataLength uint64
}

ExfatUpcaseTableDirectoryEntry points to the cluster that provides the mapping for various characters back to the original characters in order to support case-insensitivity.

func (ExfatUpcaseTableDirectoryEntry) String

func (utde ExfatUpcaseTableDirectoryEntry) String() string

String returns a string description.

func (ExfatUpcaseTableDirectoryEntry) TypeName

TypeName returns a unique name for this entry-type.

type ExfatVendorAllocationDirectoryEntry

type ExfatVendorAllocationDirectoryEntry struct {
	// EntryType: This field is mandatory and Section 7.9.1 defines its contents.
	EntryType EntryType

	// GeneralSecondaryFlags: This field is mandatory and Section 7.9.2 defines its contents.
	GeneralSecondaryFlags GeneralSecondaryFlags

	// VendorGuid: This field is mandatory and Section 7.9.3 defines its contents.
	VendorGuid [16]byte

	// VendorDefined: This field is mandatory and vendors may define its contents.
	VendorDefined [2]byte

	// FirstCluster: This field is mandatory and Section 7.9.4 defines its contents.
	FirstCluster uint32

	// DataLength: This field is mandatory and Section 7.9.5 defines its contents.
	DataLength uint64
}

ExfatVendorAllocationDirectoryEntry points to a cluster with arbitrary vendor information.

func (ExfatVendorAllocationDirectoryEntry) String

String returns a descriptive string.

func (ExfatVendorAllocationDirectoryEntry) TypeName

TypeName returns a unique name for this entry-type.

type ExfatVendorExtensionDirectoryEntry

type ExfatVendorExtensionDirectoryEntry struct {
	// EntryType: This field is mandatory and Section 7.8.1 defines its contents.
	EntryType EntryType

	// GeneralSecondaryFlags: This field is mandatory and Section 7.8.2 defines its contents.
	GeneralSecondaryFlags GeneralSecondaryFlags

	// VendorGuid: This field is mandatory and Section 7.8.3 defines its contents.
	VendorGuid [16]byte

	// VendorDefined: This field is mandatory and vendors may define its contents.
	VendorDefined [14]byte
}

ExfatVendorExtensionDirectoryEntry describes arbitrary vendor information.

func (ExfatVendorExtensionDirectoryEntry) String

String returns a descriptive string.

func (ExfatVendorExtensionDirectoryEntry) TypeName

TypeName returns a unique name for this entry-type.

type ExfatVolumeGuidDirectoryEntry

type ExfatVolumeGuidDirectoryEntry struct {
	// EntryType: This field is mandatory and Section 7.5.1 defines its contents.
	EntryType EntryType

	// SecondaryCount: This field is mandatory and Section 7.5.2 defines its contents.
	SecondaryCountRaw uint8

	// SetChecksum: This field is mandatory and Section 7.5.3 defines its contents.
	SetChecksum uint16

	// GeneralPrimaryFlags: This field is mandatory and Section 7.5.4 defines its contents.
	GeneralPrimaryFlags uint16

	// VolumeGuid: This field is mandatory and Section 7.5.5 defines its contents.
	VolumeGuid [16]byte

	// Reserved: This field is mandatory and its contents are reserved.
	Reserved [10]byte
}

ExfatVolumeGuidDirectoryEntry embeds the volume GUID.

func (ExfatVolumeGuidDirectoryEntry) SecondaryCount

func (vgde ExfatVolumeGuidDirectoryEntry) SecondaryCount() uint8

SecondaryCount returns the count of associated secondary-records.

func (ExfatVolumeGuidDirectoryEntry) String

func (vgde ExfatVolumeGuidDirectoryEntry) String() string

String returns a descriptive string.

func (ExfatVolumeGuidDirectoryEntry) TypeName

TypeName returns a unique name for this entry-type.

type ExfatVolumeLabelDirectoryEntry

type ExfatVolumeLabelDirectoryEntry struct {
	// EntryType: This field is mandatory and Section 7.3.1 defines its contents.
	EntryType EntryType

	// CharacterCount: This field is mandatory and Section 7.3.2 defines its contents.
	CharacterCount uint8

	// VolumeLabel: This field is mandatory and Section 7.3.3 defines its contents.
	//
	// NOTES
	//
	// - The specification states that this is Unicode (naturally):
	//
	//      The VolumeLabel field shall contain a Unicode string, which is the
	//      user-friendly name of the volume. The VolumeLabel field has the same
	//      set of invalid characters as the FileName field of the File Name
	//      directory entry (see Section 7.7.3).
	//
	// - In practice, tools will combine both the `VolumeLabel` and `Reserved`
	//   fields. So, we combine them here.
	VolumeLabel [30]byte
}

ExfatVolumeLabelDirectoryEntry embeds the volume label.

func (ExfatVolumeLabelDirectoryEntry) Label

Label constructs and returns the final Unicode string.

func (ExfatVolumeLabelDirectoryEntry) String

func (vlde ExfatVolumeLabelDirectoryEntry) String() string

String returns a string description.

func (ExfatVolumeLabelDirectoryEntry) TypeName

TypeName returns a unique name for this entry-type.

type ExtendedBootCode

type ExtendedBootCode []byte

ExtendedBootCode is additional boot-code that might be involved in the boot process.

type Fat

type Fat []MappedCluster

Fat is the collection of all FAT entries.

type FileAttributes

type FileAttributes uint16

FileAttributes allows us to decompose the attributes integer into the various attributes that a file/directory can have.

func (FileAttributes) DumpBareIndented

func (fa FileAttributes) DumpBareIndented(indent string)

DumpBareIndented prints the various attribute states preceding by arbitrary indentation.

func (FileAttributes) IsArchive

func (fa FileAttributes) IsArchive() bool

IsArchive returns whether the archive flag has been set on the current file.

func (FileAttributes) IsDirectory

func (fa FileAttributes) IsDirectory() bool

IsDirectory returns whether this entry is a directory.

func (FileAttributes) IsHidden

func (fa FileAttributes) IsHidden() bool

IsHidden returns whether the file should not be present in standard file listings by default.

func (FileAttributes) IsReadOnly

func (fa FileAttributes) IsReadOnly() bool

IsReadOnly returns whether the file should be read-only.

func (FileAttributes) IsSystem

func (fa FileAttributes) IsSystem() bool

IsSystem returns the system flag.

func (FileAttributes) String

func (fa FileAttributes) String() string

String returns a descriptive string.

type GeneralSecondaryFlags

type GeneralSecondaryFlags uint8

GeneralSecondaryFlags allows us to decompose the flags frequently embedded in secondary directory entries.

func (GeneralSecondaryFlags) DumpBareIndented

func (gsf GeneralSecondaryFlags) DumpBareIndented(indent string)

DumpBareIndented prints the secondary-flags with arbitrary indentation.

func (GeneralSecondaryFlags) IsAllocationPossible

func (gsf GeneralSecondaryFlags) IsAllocationPossible() bool

IsAllocationPossible indicates that writes are supported for this entry-type.

func (GeneralSecondaryFlags) NoFatChain

func (gsf GeneralSecondaryFlags) NoFatChain() bool

NoFatChain whether the data is stored sequentially on disk or the FAT is required to find the subsequent ones.

func (GeneralSecondaryFlags) String

func (gsf GeneralSecondaryFlags) String() string

String returns a descriptive string.

type IndexedDirectoryEntry

type IndexedDirectoryEntry struct {
	PrimaryEntry     DirectoryEntry
	SecondaryEntries []DirectoryEntry
	Extra            map[string]interface{}
}

IndexedDirectoryEntry is an organization type that the raw directory entries associated with a primary directory entry are assigned into.

type MappedCluster

type MappedCluster uint32

MappedCluster represents one cluster entry in the FAT.

func (MappedCluster) IsBad

func (mc MappedCluster) IsBad() bool

IsBad indicates that this cluster has been marked as having one or more bad sectors (which is somewhat a waste of space).

func (MappedCluster) IsLast

func (mc MappedCluster) IsLast() bool

IsLast indicates that no more clusters follow the cluster that led to this entry.

type MultipartFilename

type MultipartFilename []DirectoryEntry

MultipartFilename describes a set of filename components that need to be combined in order to reconstitute the original

func (MultipartFilename) Filename

func (mf MultipartFilename) Filename() string

Filename returns the reconstituted filename.

type OemParameter

type OemParameter struct {
	Parameter [48]byte
}

OemParameter is one OEM parameter.

type OemParameters

type OemParameters struct {
	Parameters [10]OemParameter
}

OemParameters is the set of OEM parameters.

type PrimaryDirectoryEntry

type PrimaryDirectoryEntry interface {
	SecondaryCount() uint8
}

PrimaryDirectoryEntry represents the common methods found on any primary- type DE, which is really just SecondaryCount().

type SectorVisitorFunc

type SectorVisitorFunc func(sectorNumber uint32, data []byte) (bool, error)

SectorVisitorFunc is a visitor callback that is called for each sector in a cluster.

type Tree

type Tree struct {
	// contains filtered or unexported fields
}

Tree is a higher-level struct that wraps the root-node.

func NewTree

func NewTree(er *ExfatReader) *Tree

NewTree returns a new Tree instance.

func (*Tree) List

func (tree *Tree) List() (files []string, nodes map[string]*TreeNode, err error)

List returns a complete list of all paths and a map of each of those paths to their node instances.

func (*Tree) Load

func (tree *Tree) Load() (err error)

Load loads the whole tree.

func (*Tree) Lookup

func (tree *Tree) Lookup(pathParts []string) (node *TreeNode, err error)

Lookup finds the node for the given absolute path.

func (*Tree) Visit

func (tree *Tree) Visit(cb TreeVisitorFunc) (err error)

Visit will pass every node in the tree to the given callback.

type TreeNode

type TreeNode struct {
	// contains filtered or unexported fields
}

TreeNode represents a single file or directory.

func NewTreeNode

func NewTreeNode(name string, isDirectory bool, ide IndexedDirectoryEntry, fde *ExfatFileDirectoryEntry, sede *ExfatStreamExtensionDirectoryEntry) (tn *TreeNode)

NewTreeNode returns a new instance of TreeNode.

func (*TreeNode) AddChild

AddChild registers a new child to this node. It's stored in sorted order.

func (*TreeNode) ChildFiles

func (tn *TreeNode) ChildFiles() []string

ChildFiles lists any child files. Only applies to directory nodes.

func (*TreeNode) ChildFolders

func (tn *TreeNode) ChildFolders() []string

ChildFolders lists any child-folders. Only applies to directory nodes.

func (*TreeNode) FileDirectoryEntry

func (tn *TreeNode) FileDirectoryEntry() *ExfatFileDirectoryEntry

FileDirectoryEntry returns the FDE for the current directory (it's actually a part of the IDE but this is important and is nicer to have directly available).

func (*TreeNode) GetChild

func (tn *TreeNode) GetChild(filename string) *TreeNode

GetChild a particular child node.

func (*TreeNode) IndexedDirectoryEntry

func (tn *TreeNode) IndexedDirectoryEntry() IndexedDirectoryEntry

IndexedDirectoryEntry returns the underlying, low-level directory-entry information that were retrieved for this directory.

func (*TreeNode) IsDirectory

func (tn *TreeNode) IsDirectory() bool

IsDirectory indicates whether the node is a directory or not.

func (*TreeNode) Lookup

func (tn *TreeNode) Lookup(pathParts []string) (lastPathParts []string, lastNode *TreeNode, found *TreeNode)

Lookup finds the given relative path within our children.

func (*TreeNode) Name

func (tn *TreeNode) Name() string

Name returns the name of the current file or directory (without any of its parents' path information).

func (*TreeNode) StreamDirectoryEntry

func (tn *TreeNode) StreamDirectoryEntry() *ExfatStreamExtensionDirectoryEntry

StreamDirectoryEntry returns the SEDE for the current directory (it's actually a part of the IDE but this is important and is nicer to have directly available).

type TreeVisitorFunc

type TreeVisitorFunc func(pathParts []string, node *TreeNode) (err error)

TreeVisitorFunc is a visitor function that receives a series of visited nodes.

type VolumeFlags

type VolumeFlags uint16

VolumeFlags represents some state flags for the filesystem.

func (VolumeFlags) ClearToZero

func (vf VolumeFlags) ClearToZero() bool

ClearToZero indicates that this flag should be cleared. Yeah.. That's what it does.

func (VolumeFlags) DumpBareIndented

func (vf VolumeFlags) DumpBareIndented(indent string)

DumpBareIndented prints the volume flags with arbitrary indentation.

func (VolumeFlags) HasHadMediaFailures

func (vf VolumeFlags) HasHadMediaFailures() bool

HasHadMediaFailures indicates whether media-errors have been detected.

func (VolumeFlags) IsDirty

func (vf VolumeFlags) IsDirty() bool

IsDirty indicates whether changes currently need to be flushed. This likely indicates whether the filesystem is currently mounted.

func (VolumeFlags) UseFirstFat

func (vf VolumeFlags) UseFirstFat() bool

UseFirstFat indicates whether the first FAT should be used.

func (VolumeFlags) UseSecondFat

func (vf VolumeFlags) UseSecondFat() bool

UseSecondFat indicates whether the second FAT should be used.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL