aboutsummaryrefslogtreecommitdiff
path: root/shared/fat32/types/boot.zig
blob: 9279fd630a805cfd11de22d494b5308b32b3e610 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
//! FAT32 Boot Sector (BPB)

const constants = @import("shared").fat32.constants;

pub const BootSector = extern struct {
    JumpBoot: [3]u8,
    OemName: [8]u8,
    BytesPerSector: u16 align(1),
    SectorsPerCluster: u8,
    ReservedSectors: u16 align(1),
    FatCount: u8,
    RootEntryCount: u16 align(1),
    TotalSectors16: u16 align(1),
    MediaType: u8,
    FatSize16: u16 align(1),
    SectorsPerTrack: u16 align(1),
    HeadCount: u16 align(1),
    HiddenSectors: u32 align(1),
    TotalSectors32: u32 align(1),
    FatSize32: u32 align(1),
    ExtFlags: u16 align(1),
    FsVersion: u16 align(1),
    RootCluster: u32 align(1),
    FsInfoSector: u16 align(1),
    BackupBootSector: u16 align(1),
    Reserved: [12]u8,
    DriveNumber: u8,
    Reserved1: u8,
    BootSignature: u8,
    VolumeId: u32 align(1),
    VolumeLabel: [11]u8,
    FsType: [8]u8,
    BootCode: [420]u8,
    Signature: u16 align(1),

    pub fn isValid(self: *const BootSector) bool {
        if (self.Signature != constants.magic.BOOT_SIGNATURE) {
            return false;
        }
        if (self.BytesPerSector < constants.sizes.SECTOR_SIZE_MIN or
            self.BytesPerSector > constants.sizes.SECTOR_SIZE_MAX)
        {
            return false;
        }
        if (self.SectorsPerCluster == 0) {
            return false;
        }
        if (self.FatCount == 0) {
            return false;
        }
        if (self.FatSize32 == 0) {
            return false;
        }
        return true;
    }

    pub fn getFatStartSector(self: *const BootSector) u32 {
        return self.ReservedSectors;
    }

    pub fn getDataStartSector(self: *const BootSector) u32 {
        return self.ReservedSectors + (@as(u32, self.FatCount) * self.FatSize32);
    }

    pub fn getTotalClusters(self: *const BootSector) u32 {
        const data_sectors = self.TotalSectors32 - self.getDataStartSector();
        return data_sectors / self.SectorsPerCluster;
    }

    pub fn clusterToSector(self: *const BootSector, cluster: u32) u32 {
        return self.getDataStartSector() + ((cluster - constants.clusters.CLUSTER_DATA_START) * self.SectorsPerCluster);
    }

    pub fn getBytesPerCluster(self: *const BootSector) u32 {
        return @as(u32, self.BytesPerSector) * self.SectorsPerCluster;
    }
};

pub const FsInfo = extern struct {
    Signature1: u32 align(1),
    Reserved1: [480]u8,
    Signature2: u32 align(1),
    FreeClusterCount: u32 align(1),
    NextFreeCluster: u32 align(1),
    Reserved2: [12]u8,
    Signature3: u32 align(1),

    pub fn isValid(self: *const FsInfo) bool {
        return self.Signature1 == constants.magic.FSINFO_SIGNATURE_1 and
            self.Signature2 == constants.magic.FSINFO_SIGNATURE_2 and
            self.Signature3 == constants.magic.FSINFO_SIGNATURE_3;
    }
};