mbr_partition_table: C++/STL parsing library

This page hosts a formal specification of mbr_partition_table using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.

Usage

Using Kaitai Struct in C++/STL usually consists of 3 steps.

  1. We need to create an STL input stream (std::istream).
    • One can open a stream for reading from a local file:
      #include <fstream>
      
      std::ifstream is("path/to/local/file.mbr_partition_table", std::ifstream::binary);
    • Or one can prepare a stream for reading from existing std::string str:
      #include <sstream>
      
      std::istringstream is(str);
    • Or one can parse arbitrary char* buffer in memory, given that we know its size:
      #include <sstream>
      
      const char buf[] = { ... };
      std::string str(buf, sizeof buf);
      std::istringstream is(str);
  2. We need to wrap our input stream into Kaitai stream:
    #include <kaitai/kaitaistream.h>
    
    kaitai::kstream ks(&is);
  3. And finally, we can invoke the parsing:
    mbr_partition_table_t data(&ks);

After that, one can get various attributes from the structure by invoking getter methods like:

data.bootstrap_code() // => get bootstrap code

C++/STL source code to parse mbr_partition_table

mbr_partition_table.h

#ifndef MBR_PARTITION_TABLE_H_
#define MBR_PARTITION_TABLE_H_

// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild

#include "kaitai/kaitaistruct.h"

#include <stdint.h>
#include <vector>

#if KAITAI_STRUCT_VERSION < 7000L
#error "Incompatible Kaitai Struct C++/STL API: version 0.7 or later is required"
#endif

class mbr_partition_table_t : public kaitai::kstruct {

public:
    class partition_entry_t;
    class chs_t;

    mbr_partition_table_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, mbr_partition_table_t* p__root = 0);

private:
    void _read();

public:
    ~mbr_partition_table_t();

    class partition_entry_t : public kaitai::kstruct {

    public:

        partition_entry_t(kaitai::kstream* p__io, mbr_partition_table_t* p__parent = 0, mbr_partition_table_t* p__root = 0);

    private:
        void _read();

    public:
        ~partition_entry_t();

    private:
        uint8_t m_status;
        chs_t* m_chs_start;
        uint8_t m_partition_type;
        chs_t* m_chs_end;
        uint32_t m_lba_start;
        uint32_t m_num_sectors;
        mbr_partition_table_t* m__root;
        mbr_partition_table_t* m__parent;

    public:
        uint8_t status() const { return m_status; }
        chs_t* chs_start() const { return m_chs_start; }
        uint8_t partition_type() const { return m_partition_type; }
        chs_t* chs_end() const { return m_chs_end; }
        uint32_t lba_start() const { return m_lba_start; }
        uint32_t num_sectors() const { return m_num_sectors; }
        mbr_partition_table_t* _root() const { return m__root; }
        mbr_partition_table_t* _parent() const { return m__parent; }
    };

    class chs_t : public kaitai::kstruct {

    public:

        chs_t(kaitai::kstream* p__io, mbr_partition_table_t::partition_entry_t* p__parent = 0, mbr_partition_table_t* p__root = 0);

    private:
        void _read();

    public:
        ~chs_t();

    private:
        bool f_sector;
        int32_t m_sector;

    public:
        int32_t sector();

    private:
        bool f_cylinder;
        int32_t m_cylinder;

    public:
        int32_t cylinder();

    private:
        uint8_t m_head;
        uint8_t m_b2;
        uint8_t m_b3;
        mbr_partition_table_t* m__root;
        mbr_partition_table_t::partition_entry_t* m__parent;

    public:
        uint8_t head() const { return m_head; }
        uint8_t b2() const { return m_b2; }
        uint8_t b3() const { return m_b3; }
        mbr_partition_table_t* _root() const { return m__root; }
        mbr_partition_table_t::partition_entry_t* _parent() const { return m__parent; }
    };

private:
    std::string m_bootstrap_code;
    std::vector<partition_entry_t*>* m_partitions;
    std::string m_boot_signature;
    mbr_partition_table_t* m__root;
    kaitai::kstruct* m__parent;

public:
    std::string bootstrap_code() const { return m_bootstrap_code; }
    std::vector<partition_entry_t*>* partitions() const { return m_partitions; }
    std::string boot_signature() const { return m_boot_signature; }
    mbr_partition_table_t* _root() const { return m__root; }
    kaitai::kstruct* _parent() const { return m__parent; }
};

#endif  // MBR_PARTITION_TABLE_H_

mbr_partition_table.cpp

// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild

#include "mbr_partition_table.h"



mbr_partition_table_t::mbr_partition_table_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, mbr_partition_table_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = this;
    _read();
}

void mbr_partition_table_t::_read() {
    m_bootstrap_code = m__io->read_bytes(446);
    int l_partitions = 4;
    m_partitions = new std::vector<partition_entry_t*>();
    m_partitions->reserve(l_partitions);
    for (int i = 0; i < l_partitions; i++) {
        m_partitions->push_back(new partition_entry_t(m__io, this, m__root));
    }
    m_boot_signature = m__io->ensure_fixed_contents(std::string("\x55\xAA", 2));
}

mbr_partition_table_t::~mbr_partition_table_t() {
    for (std::vector<partition_entry_t*>::iterator it = m_partitions->begin(); it != m_partitions->end(); ++it) {
        delete *it;
    }
    delete m_partitions;
}

mbr_partition_table_t::partition_entry_t::partition_entry_t(kaitai::kstream* p__io, mbr_partition_table_t* p__parent, mbr_partition_table_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    _read();
}

void mbr_partition_table_t::partition_entry_t::_read() {
    m_status = m__io->read_u1();
    m_chs_start = new chs_t(m__io, this, m__root);
    m_partition_type = m__io->read_u1();
    m_chs_end = new chs_t(m__io, this, m__root);
    m_lba_start = m__io->read_u4le();
    m_num_sectors = m__io->read_u4le();
}

mbr_partition_table_t::partition_entry_t::~partition_entry_t() {
    delete m_chs_start;
    delete m_chs_end;
}

mbr_partition_table_t::chs_t::chs_t(kaitai::kstream* p__io, mbr_partition_table_t::partition_entry_t* p__parent, mbr_partition_table_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    f_sector = false;
    f_cylinder = false;
    _read();
}

void mbr_partition_table_t::chs_t::_read() {
    m_head = m__io->read_u1();
    m_b2 = m__io->read_u1();
    m_b3 = m__io->read_u1();
}

mbr_partition_table_t::chs_t::~chs_t() {
}

int32_t mbr_partition_table_t::chs_t::sector() {
    if (f_sector)
        return m_sector;
    m_sector = (b2() & 63);
    f_sector = true;
    return m_sector;
}

int32_t mbr_partition_table_t::chs_t::cylinder() {
    if (f_cylinder)
        return m_cylinder;
    m_cylinder = (b3() + ((b2() & 192) << 2));
    f_cylinder = true;
    return m_cylinder;
}