AdetunjiOp
AdetunjiOp

Reputation: 3

How do I read the whole 64 bytes of a binary file?

I am writing a little program that reads a disk image file in binary and then checks its partition entry tables to display each partition, it's type, start sector and size.

So far it reads the first 16 bytes accurately but the rest of the partition entries are not recognized or have some kind of error. The result looks like this: enter image description here EDIT: The first line of the output is supposed to look like this:

 `Partition 0: Type: FAT-16 Start: 63 Size: 518760`

What am I missing? How do I fix the code so that all the partition entries give the appropriate result?

using namespace std;
#include <iostream>
#include <fstream>

struct Partition { char type; int start_sect; int size; } part_entry[4];  // 4 x partition table entry 


int main(int argc, char *argv[])
{
//DECLARATIONS
int i, offset = 26, not_exist = 0;
char buf_part_table[64], vol_type[12];
char* diskdata;
int n;
streampos begin, end;


ifstream diskimage;
diskimage.open("Sample_1.dd", ios::in | ios::binary | ios::out);


diskdata = new char[begin];
begin = diskimage.tellg();
diskdata = new char[begin];
diskimage.seekg(446, ios::beg);

diskimage.read(buf_part_table, 64);


for (i = 0; i < 4; i++)
{
    part_entry[i].type = *(char*)(buf_part_table + 0x04 + (i * offset));

    if (part_entry[i].type == 0) not_exist++;

    part_entry[i].start_sect = *(int*)(buf_part_table + 0x08 + (i * offset));

    part_entry[i].size = *(int*)(buf_part_table + 0x0C + (i * offset));

    switch (part_entry[i].type)
    {
    case 00:  strcpy(vol_type, "NOT-VALID");
        break;
    case 06:  strcpy(vol_type, "FAT-16");
        break;
    case 07:  strcpy(vol_type, "NTFS");
        break;
    case 0x0B:  strcpy(vol_type, "FAT-32");
        break;
    default:    strcpy(vol_type, "NOT-DECODED");
        break;
    }

    cout << "Partition " << i << ":" << " Type:" << vol_type << " Start: " << part_entry[i].start_sect << " Size: " << part_entry[i].size << endl;

}

return 0;
}

Upvotes: 0

Views: 334

Answers (1)

Anty
Anty

Reputation: 1516

You unnecesary made program unreadable and harder to debug. You can read whole boot sector at once and than display desired content. Here is my quick example (it does not check if file exists, some may complain it should use memcpy for some fields etc.)

#include <iostream>
#include <fstream>
#include <cstdint>
#include <cstddef>
#include <iomanip>

using namespace std;

struct partition_t {
    uint8_t  status;
    uint8_t  start_CHS[3];
    uint8_t  type;
    uint8_t  end_CHS[3];
    uint32_t start_LBA;
    uint32_t size_LBA;
} __attribute__((packed));

struct mbr_t
{
    uint8_t     bootstrap[446];
    partition_t partitions[4];
    uint16_t    signature;
} __attribute__((packed));

int main(int argc, char *argv[])
{
    mbr_t mbr;
    ifstream diskimage;
    diskimage.open( "/tmp/mbr.dd", ios::in | ios::binary );
    diskimage.read( reinterpret_cast<char*>(&mbr), sizeof(mbr) );
    diskimage.close();

    for( int idx = 0 ; idx < 4 ; idx++ )
    {
      string bootable = (mbr.partitions[idx].status == 128) ? "yes" : "no";
      cout << " bootable : " <<  setw(5) << bootable << 
              " type : " << setw(5) << (int)mbr.partitions[idx].type << 
              " start LBA : " << setw(10) << mbr.partitions[idx].start_LBA << 
              " size : " << setw(10) << mbr.partitions[idx].size_LBA << endl;
    }

    return 0;
}

It is easier to read, right?

Upvotes: 1

Related Questions