如何读取二进制文件的整个64字节?

时间:2017-03-23 09:47:14

标签: c++ binary partitioning disk istream

我正在编写一个小程序,它以二进制形式读取磁盘映像文件,然后检查其分区条目表以显示每个分区,它的类型,起始扇区和大小。

到目前为止,它准确地读取了前16个字节,但其余的分区条目无法识别或出现某种错误。 结果如下: enter image description here 编辑:输出的第一行应该是这样的:

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

我错过了什么?如何修复代码以便所有分区条目都能提供适当的结果?

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;
}

1 个答案:

答案 0 :(得分:1)

你不必要的程序不可读并且难以调试。 您可以一次读取整个引导扇区,而不是显示所需的内容。 这是我的快速示例(它不会检查文件是否存在,有些人可能会抱怨它应该使用memcpy来处理某些字段等。)

#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;
}

更容易阅读,对吧?