# nobodd.fat

Defines the data structures used by the FAT file system. You should never need these directly; use the `nobodd.fs.FatFileSystem` class instead.

## Data structures

class nobodd.fat.BIOSParameterBlock(jump_instruction, oem_name, bytes_per_sector, sectors_per_cluster, reserved_sectors, fat_count, max_root_entries, fat16_total_sectors, media_descriptor, sectors_per_fat, sectors_per_track, heads_per_disk, hidden_sectors, fat32_total_sectors)

  A `namedtuple()` representing the BIOS Parameter Block found at the very start of a FAT file system (of any type). This provides several (effectively unused) legacy fields, but also several fields still used exclusively in later FAT variants (like the count of FAT-32 sectors).

  classmethod from_buffer(buf, offset=0)

    Construct a `BIOSParameterBlock` from the specified offset (which defaults to 0) in the buffer protocol object, buf.

  classmethod from_bytes(s)

    Construct a `BIOSParameterBlock` from the byte-string s.

  to_buffer(buf, offset=0)

    Write this `BIOSParameterBlock` to buf, a buffer protocol object, at the specified offset (which defaults to 0).

class nobodd.fat.ExtendedBIOSParameterBlock(drive_number, extended_boot_sig, volume_id, volume_label, file_system)

  A `namedtuple()` representing the Extended BIOS Parameter Block found either immediately after the BIOS Parameter Block (in FAT-12 and FAT-16 formats), or after the FAT32 BIOS Parameter Block (in FAT-32 formats).

  This provides several (effectively unused) legacy fields, but also provides the “file_system” field which is used as the primary means of distinguishing the different FAT types (see `nobodd.fs.fat_type()`), and the self-explanatory “volume_label” field.

  classmethod from_buffer(buf, offset=0)

    Construct a `ExtendedBIOSParameterBlock` from the specified offset (which defaults to 0) in the buffer protocol object, buf.

  classmethod from_bytes(s)

    Construct a `ExtendedBIOSParameterBlock` from the byte-string s.

  to_buffer(buf, offset=0)

    Write this `ExtendedBIOSParameterBlock` to buf, a buffer protocol object, at the specified offset (which defaults to 0).

class nobodd.fat.FAT32BIOSParameterBlock(sectors_per_fat, mirror_flags, version, root_dir_cluster, info_sector, backup_sector)

  A `namedtuple()` representing the FAT32 BIOS Parameter Block found immediately after the BIOS Parameter Block in FAT-32 formats. In FAT-12 and FAT-16 formats it should not occur.

  This crucially provides the cluster containing the root directory (which is structured as a normal sub-directory in FAT-32) as well as the number of sectors per FAT, specifically for FAT-32. All other fields are ignored by this implementation.

  classmethod from_buffer(buf, offset=0)

    Construct a `FAT32BIOSParameterBlock` from the specified offset (which defaults to 0) in the buffer protocol object, buf.

  classmethod from_bytes(s)

    Construct a `FAT32BIOSParameterBlock` from the byte-string s.

  to_buffer(buf, offset=0)

    Write this `FAT32BIOSParameterBlock` to buf, a buffer protocol object, at the specified offset (which defaults to 0).

class nobodd.fat.FAT32InfoSector(sig1, reserved1, sig2, free_clusters, last_alloc, reserved2, sig3)

  A `namedtuple()` representing the FAT32 Info Sector typically found in the sector after the BIOS Parameter Block in FAT-32 formats. In FAT-12 and FAT-16 formats it is not present.

  This records the number of free clusters available, and the last allocated cluster, which can speed up the search for free clusters during allocation. Because this implementation is capable of writing, and thus allocating clusters, and because the reserved fields must be ignored but not re-written, they are represented as strings here (rather than “x” NULs) to ensure they are preserved when writing.

  classmethod from_buffer(buf, offset=0)

    Construct a `FAT32InfoSector` from the specified offset (which defaults to 0) in the buffer protocol object, buf.

  classmethod from_bytes(s)

    Construct a `FAT32InfoSector` from the byte-string s.

  to_buffer(buf, offset=0)

    Write this `FAT32InfoSector` to buf, a buffer protocol object, at the specified offset (which defaults to 0).

class nobodd.fat.DirectoryEntry(filename, ext, attr, attr2, ctime_cs, ctime, cdate, adate, first_cluster_hi, mtime, mdate, first_cluster_lo, size)

  A `namedtuple()` representing a FAT directory entry. This is a fixed-size structure which repeats up to the size of a cluster within a FAT root or sub-directory.

  It contains the (8.3 sized) filename of an entry, the size in bytes, the cluster at which the entry’s data starts, the entry’s attributes (which determine whether the entry represents a file or another sub-directory), and (depending on the format), the creation, modification, and access timestamps.

  Entries may represent deleted items in which case the first character of the filename will be 0xE5. If the attr is 0x0F, the entry is actually a long-filename entry and should be converted to `LongFilenameEntry`. If attr is 0x10, the entry represents a sub-directory. See directory entry for more details.

  classmethod eof()

    Make a directory entry from NUL bytes; this is used to signify the end of the directory in indexes.

  classmethod from_buffer(buf, offset=0)

    Construct a `DirectoryEntry` from the specified offset (which defaults to 0) in the buffer protocol object, buf.

  classmethod from_bytes(s)

    Construct a `DirectoryEntry` from the byte-string s.

  classmethod iter_over(buf)

    Iteratively yields successive `DirectoryEntry` instances from the buffer protocol object, buf.

    Note

    This method is entirely dumb and does not check whether the yielded instances are valid; it is up to the caller to determine the validity of entries.

  to_buffer(buf, offset=0)

    Write this `DirectoryEntry` to buf, a buffer protocol object, at the specified offset (which defaults to 0).

class nobodd.fat.LongFilenameEntry(sequence, name_1, attr, checksum, name_2, first_cluster, name_3)

  A `namedtuple()` representing a FAT long filename. This is a variant of the FAT directory entry where the attr field is 0x0F.

  Several of these entries will appear before their corresponding `DirectoryEntry`, but will be in reverse order. A checksum is incorporated for additional verification, and a sequence number indicating the number of segments, and which one is “last” (first in the byte-stream, but last in character order).

  classmethod from_buffer(buf, offset=0)

    Construct a `LongFilenameEntry` from the specified offset (which defaults to 0) in the buffer protocol object, buf.

  classmethod from_bytes(s)

    Construct a `LongFilenameEntry` from the byte-string s.

  classmethod iter_over(buf)

    Iteratively yields successive `LongFilenameEntry` instances from the buffer protocol object, buf.

    Note

    This method is entirely dumb and does not check whether the yielded instances are valid; it is up to the caller to determine the validity of entries.

  to_buffer(buf, offset=0)

    Write this `LongFilenameEntry` to buf, a buffer protocol object, at the specified offset (which defaults to 0).

## Support functions

These utility functions help decode certain fields within the aforementioned structure, or check that tentative contents are valid.

nobodd.fat.lfn_checksum(sfn, ext)

  Calculate the expected long-filename checksum given the filename and ext byte-strings of the short filename (from the corresponding `Directoryentry`).

nobodd.fat.lfn_valid(s)

  Returns `True` if `str` s only contains characters valid in a VFAT long filename. Almost every Unicode character is permitted with a few exceptions (angle brackets, wildcards, etc).