利用python读取磁盘二进制数据获取磁盘分区的起始扇区的LBA以及磁盘分区大小

磁盘知识储备参考

# -*-coding:utf-8-*-
import binascii
import re

"""
device_type={'type_guid':'',' lba_start','lba_end':'','partition_mbyte'}
"""
DISK_IS_GPT = 0
DISK_IS_MBR = 1
PARTITION_TABLE_SECTOR = 32
ONE_SECTOR_BYTES = 512


def check_gpt_or_mbr(device):
    """
    this is device is gpt or mbr
    :param device: mount device
    :return:0 is gpt,1 is mbr
    """
    with open(device, 'rb') as disk:
        disk_type = disk.read(ONE_SECTOR_BYTES)[450]
        if disk_type == 238:  # ee的十进制为238
            return DISK_IS_GPT
        else:
            return DISK_IS_MBR


def sort_out_partition_item_guid(guid_str):
    """
    this is calc guid
    :param guid_str:guid_str is hex str
    :return: update_guid
    """
    test = str(guid_str)
    guid = "".join([i for index, i in enumerate(test) if index != 0]).replace('\'', '')
    footer = guid[-12:]
    intermediate1 = guid[-16:-12]
    intermediate0 = guid[12:16]  # d211
    result = re.sub(r"(?<=\w)(?=(?:\w\w)+$)", " ", guid[:12]).split(' ')
    result1 = re.sub(r"(?<=\w)(?=(?:\w\w)+$)", " ", intermediate0).split(' ')
    intermediate0 = "".join(result1[::-1])  # 11d2
    header = "".join(result[:4][::-1])
    intermediate = "".join(result[4:][::-1])
    update_guid = header + '-' + intermediate + '-' + intermediate0 + '-' + intermediate1 + '-' + footer
    return update_guid


def split_first_sector(b_stream, device_type):
    step = 128 if device_type == DISK_IS_GPT else 16
    for _i in range(0, len(b_stream), step):
        yield b_stream[_i:_i + step]


def partition_info_gpt(disk, device_type):
    device_info = []  # Used to store disk information
    for i in range(PARTITION_TABLE_SECTOR):  # Iterate through the sectors of 32 partition table entries
        byte_stream = disk.read(ONE_SECTOR_BYTES)
        if i > 1 and int(binascii.b2a_hex(byte_stream), 16) != 0:
            for partition in split_first_sector(byte_stream, device_type):
                check = binascii.b2a_hex(partition)
                partition_info = {}  # Used to store partition information
                if int(check, 16) != 0:
                    partition_info['type_guid'] = sort_out_partition_item_guid(
                        binascii.b2a_hex(partition[0:16]))
                    partition_info['lba_start'] = int.from_bytes(partition[32:40], 'little')
                    partition_info['lba_end'] = int.from_bytes(partition[40:48], 'little')
                    partition_mbyte = (partition_info['lba_end'] - partition_info[
                        'lba_start'] + 1) * ONE_SECTOR_BYTES // (
                                              1024 * 1024)
                    partition_info['partition_mbyte'] = partition_mbyte
                    device_info.append(partition_info)
    return device_info


def partition_info_mbr(disk, device_type):
    device_info = []
    header_bytes = disk.read(ONE_SECTOR_BYTES)
    partition_info = header_bytes[446:510]
    for partition in split_first_sector(partition_info, device_type):
        check = binascii.b2a_hex(partition)
        partition_info = {}
        check_activity = hex(partition[0])
        if int(check,16) != 0:  # Check if the partition table entry is a meaningful partition table entry and is the active partition

            partition_info['check_activity'] = check_activity
            partition_info['check_main'] = hex(partition[4])
            partition_info['lba_start'] = int.from_bytes(partition[8:12], 'little')
            sum_sector = int.from_bytes(partition[12:16], 'little')
            partition_info['lba_end'] = sum_sector + partition_info['lba_start']
            partition_info['partition_mbyte'] = (partition_info['lba_end'] - partition_info[
                'lba_start'] + 1) * ONE_SECTOR_BYTES // (1024 * 1024)
            device_info.append(partition_info)
    return device_info


def from_sector_partition_item(device):
    """
    statistics disk information
    :param device:mount device
    :return:device_info
    """
    device_type = check_gpt_or_mbr(device)

    with open(device, 'rb') as disk:
        if device_type == DISK_IS_GPT:  # Gpt partition when equal to 0
            return partition_info_gpt(disk, device_type), device_type
        else:
            result = [i for i in partition_info_mbr(disk, device_type) if i['check_activity'] == '0x80']
            return result, device_type


if __name__ == "__main__":
    # gpt_or_mbr=0 is gpt or gpt_or_mbr=mbr
    disk_info, gpt_or_mbr = from_sector_partition_item('\\\\.\\PHYSICALDRIVE0')
    for i in disk_info:
        print(i)
    print(gpt_or_mbr)

运行结果如下,partition_mbyte为每个盘的大小单位为MB
在这里插入图片描述
可以看出运行结果和disk genius软件获取到的分区信息是一致的
在这里插入图片描述

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MBR(Master Boot Record)型磁盘是指使用MBR分区格式的磁盘。MBR扇磁盘的第一个扇,其位置在磁盘的第0柱面第0磁头第1扇(也就是逻辑地址0),大小为512字节。 MBR扇由三个部分组成:主引导记录(Master Boot Record)、分区表(Partition Table)和结束标志(End of sector marker)。其中,主引导记录占据MBR扇的前446个字节,分区表占据MBR扇的接下来的64个字节,结束标志占据MBR扇的最后2个字节。 分区表由四个16字节的分区表项组成,每个分区表项都描述了一个分区起始、结束扇分区类型等信息。分区表项的结构如下: | 偏移字节 | 长度(字节) | 描述 | | -------- | ------------ | ------------------------------------------------------------ | | 0 | 1 | 引导标志,0x80表示该分区是活动分区,即启动分区 | | 1-3 | 3 | 分区起始磁头 | | 4-5 | 2 | 分区起始(从1开始计数) | | 6-7 | 2 | 分区起始柱面 | | 8 | 1 | 分区类型,详见下面的表格 | | 9-11 | 3 | 分区结束磁头 | | 12-13 | 2 | 分区结束扇(从1开始计数) | | 14-15 | 2 | 分区结束柱面 | | 16-19 | 4 | 分区起始LBA地址(逻辑块地址) | | 20-23 | 4 | 分区大小(以扇数为单位,0表示该分区为该磁盘的最后一个分区) | 在分区类型中,常见的类型有: | 类型代码 | 分区类型 | | -------- | -------------- | | 0x01 | FAT12 | | 0x04 | FAT16(<32M) | | 0x05 | 扩展分区 | | 0x06 | FAT16(>32M) | | 0x07 | NTFS | | 0x0B | FAT32 | | 0x0C | FAT32(LBA) | | 0x0E | FAT16(LBA) | | 0x0F | 扩展分区LBA) | MBR扇分区表可以记录最多四个主分区或三个主分区和一个扩展分区。如果一个主分区被标记为活动分区,则该分区中的操作系统将被启动。如果有扩展分区,则该扩展分区可以被划分为多个逻辑分区,每个逻辑分区磁盘上都是一个独立的分区,但在分区表中没有固定的位置和顺序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值