xaizek / tos (License: GPLv3 only) (since 2018-12-07)
This is an alternative version of sources presented as part of Write Your Own OS video tutorial by Viktor Engelmann.
<root> / src / fs / fat.hpp (0256b67f9d2cd53d76984869f057ac778adb8dcd) (3,074B) (mode 100644) [raw]
#ifndef TOS__FILESYSTEM__FAT_HPP__
#define TOS__FILESYSTEM__FAT_HPP__

#include <cstdint>

#include "utils/struct.hpp"

namespace drv {
    class ATA;
}

namespace fs {

struct BiosParameterBlock32
{
    Fields<std::uint8_t, 3> jump;
    Fields<std::uint8_t, 8> softName;
    Field<std::uint16_t> bytesPerSector;
    Field<std::uint8_t> sectorsPerCluster;
    Field<std::uint16_t> reservedSectors;
    Field<std::uint8_t> fatCopies;
    Field<std::uint16_t> rootDirEntries;
    Field<std::uint16_t> totalSectors;
    Field<std::uint8_t> mediaType;
    Field<std::uint16_t> fatSectorCount;
    Field<std::uint16_t> sectorsPerTrack;
    Field<std::uint16_t> headCount;
    Field<std::uint32_t> hiddenSectors;
    Field<std::uint32_t> totalSectorCount;

    Field<std::uint32_t> tableSize;
    Field<std::uint16_t> extFlags;
    Field<std::uint16_t> fatVersion;
    Field<std::uint32_t> rootCluster;
    Field<std::uint16_t> fatInfo;
    Field<std::uint16_t> backupSector;
    Fields<std::uint8_t, 12> reserved0;
    Field<std::uint8_t> driveNumber;
    Field<std::uint8_t> reserved;
    Field<std::uint8_t> bootSignature;
    Field<std::uint32_t> volumeId;
    Fields<std::uint8_t, 11> volumeLabel;
    Fields<std::uint8_t, 8> fatTypeLabel;

    explicit BiosParameterBlock32(std::uint8_t data[])
        : jump(data), softName(data), bytesPerSector(data),
          sectorsPerCluster(data), reservedSectors(data), fatCopies(data),
          rootDirEntries(data), totalSectors(data), mediaType(data),
          fatSectorCount(data), sectorsPerTrack(data), headCount(data),
          hiddenSectors(data), totalSectorCount(data), tableSize(data),
          extFlags(data), fatVersion(data), rootCluster(data), fatInfo(data),
          backupSector(data), reserved0(data), driveNumber(data),
          reserved(data), bootSignature(data), volumeId(data),
          volumeLabel(data), fatTypeLabel(data)
    {
    }
};

struct DirectoryEntryFat32
{
    Fields<std::uint8_t, 8> name;
    Fields<std::uint8_t, 3> ext;
    Field<std::uint8_t> attributes;
    Field<std::uint8_t> reserved;
    Field<std::uint8_t> cTimeTenth;
    Field<std::uint16_t> cTime;
    Field<std::uint16_t> cDate;
    Field<std::uint16_t> aTime;
    Field<std::uint16_t> firstClusterHi;
    Field<std::uint16_t> wTime;
    Field<std::uint16_t> wDate;
    Field<std::uint16_t> firstClusterLow;
    Field<std::uint32_t> size;

    explicit DirectoryEntryFat32(std::uint8_t *&data)
        : name(data), ext(data), attributes(data), reserved(data),
          cTimeTenth(data), cTime(data), cDate(data), aTime(data),
          firstClusterHi(data), wTime(data), wDate(data), firstClusterLow(data),
          size(data)
    {
    }
};

class FAT
{
public:
    FAT(drv::ATA &hd, std::uint32_t partitionOffset);

public:
    void printFiles();

private:
    void printFileContents(const DirectoryEntryFat32 &ent) const;

private:
    drv::ATA &hd;
    std::uint32_t fatStart;
    std::uint32_t dataStart;
    std::uint32_t rootStart;
    std::uint32_t sectorsPerCluster;
};

}

#endif // TOS__FILESYSTEM__FAT_HPP__
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/tos

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/tos

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master