std1.0.0-beta-7 SafeC docs

Source fs/partition.sc

View in the repository

// SafeC Standard Library — Partition Table Implementation
#pragma once
#include <std/fs/partition.h>
#include <std/fs/block.h>

// MBR layout: 446 bytes bootstrap + 4×16-byte partition entries + 2-byte signature
#define MBR_ENTRY_OFFSET  446
#define MBR_SIG_OFFSET    510
#define MBR_SIG_0         0x55
#define MBR_SIG_1         0xAA

namespace std {

inline const ?&PartEntry PartTable::get(int idx) const {
    if (idx < 0 || idx >= PART_MAX) { return (const ?&PartEntry)(const struct PartEntry*)0; }
    unsafe { return (const ?&PartEntry)(const struct PartEntry*)&self.entries[idx]; }
    return (const ?&PartEntry)(const struct PartEntry*)0;
}

int PartTable::read(&BlockDevice dev) {
    unsigned char mbr[512];
    if (dev.read((unsigned long)0, mbr[0..512]) != 0) {
        return -1;
    }
    // Validate signature.
    unsafe {
        if (mbr[MBR_SIG_OFFSET]   != (unsigned char)MBR_SIG_0 ||
            mbr[MBR_SIG_OFFSET+1] != (unsigned char)MBR_SIG_1) {
            return -1;
        }
    }
    self.count = 0;
    int i = 0;
    while (i < PART_MAX) {
        unsafe {
            unsigned char* e = (unsigned char*)mbr + MBR_ENTRY_OFFSET + i * 16;
            self.entries[i].status = e[0];
            self.entries[i].type   = e[4];
            // LBA start at bytes 8-11 (little-endian)
            self.entries[i].lba_start =
                (unsigned long)e[8]  |
                ((unsigned long)e[9]  << 8) |
                ((unsigned long)e[10] << 16) |
                ((unsigned long)e[11] << 24);
            // sector count at bytes 12-15 (little-endian)
            self.entries[i].sector_count =
                (unsigned long)e[12] |
                ((unsigned long)e[13] << 8) |
                ((unsigned long)e[14] << 16) |
                ((unsigned long)e[15] << 24);
            if (self.entries[i].type != (unsigned char)PART_TYPE_EMPTY) {
                self.count = self.count + 1;
            }
        }
        i = i + 1;
    }
    return 0;
}

} // namespace std