c++如何读取和修改磁盘分区的GPT分区表【深度】

浅伟大大_5016

浅伟大大_5016

2026-04-14

899人浏览

原创

直接读写磁盘设备文件需严格遵循权限、缓存、对齐与校验规范:Linux/macOS/Windows各有权限与缓存要求;GPT主备头必须同步更新并重算CRC32;分区字段须合法GUID、不重叠、字节序正确且结构体紧凑对齐。

c++如何读取和修改磁盘分区的gpt分区表【深度】

直接读写磁盘设备文件会触发权限和缓存问题

Linux/macOS 下不能用 fopen("/dev/sda", "r+") 随意读写 GPT 分区表——系统内核可能已将该设备挂载,或启用 write-back 缓存,导致你改了内存里的缓冲区却没刷到物理扇区;Windows 下更严格,CreateFile 打开 \\.\PhysicalDrive0 必须以 GENERIC_READ | GENERIC_WRITE 权限 + FILE_SHARE_READ | FILE_SHARE_WRITE 共享模式,且进程需管理员权限(UAC 提权),否则返回 ERROR_ACCESS_DENIED。

  • Linux:先 sudo blockdev --flushbufs /dev/sda 清缓存,再用 O_DIRECT | O_SYNC 标志打开设备(绕过页缓存)
  • macOS:需禁用 SIP 后才能写入 /dev/disk0,否则 write() 直接返回 EPERM
  • Windows:必须调用 SetFilePointer 定位到 LBA 1(GPT 头位置),再用 WriteFile 写入 512 字节,且不能跨扇区对齐写

GPT 头在 LBA 1,但备份头在最后一个 LBA,别只改一个

GPT 规范要求主头(LBA 1)和备份头(最后一个可用 LBA)内容镜像一致。若只修改主头不更新备份头,某些固件或工具(如 gdisk)会检测到校验和不匹配,自动拒绝加载或强制恢复备份头——你的修改就白做了。

  • 读取时:先读 LBA 1 的 struct gpt_header,验证 signature(应为 "EFI PART")、header_crc32 和 partition_entries_crc32
  • 修改后:必须重新计算两个 CRC32(用 ~0 初始化、跳过自身字段),再把整个结构体 memcpy 到备份头位置
  • 分区数组起始 LBA 存在 partition_entry_lba 字段,典型值是 LBA 2;数组长度由 num_partition_entries × sizeof(struct gpt_entry) 决定(通常 128 × 128 = 16KB)

修改分区条目前必须检查 GUID 和类型 GUID 是否合法

GPT 分区条目(struct gpt_entry)里有两个关键 GUID:partition_type_guid(决定系统是否识别该分区)和 unique_partition_guid(唯一标识)。填错 partition_type_guid 可能导致 Windows 拒绝挂载、Linux blkid 无法识别文件系统类型;而 unique_partition_guid 若与其他分区重复,某些工具(如 macOS Disk Utility)会报 “duplicate UUID” 并拒绝操作。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
  • 常用类型 GUID 示例:0fc63daf-8483-4772-8e79-3d69d8477de4(Linux filesystem)、c12a7328-f81f-11d2-ba4b-00a0c93ec93b(EFI System Partition)
  • 生成新 unique_partition_guid 时,不能用零值或全 F 值;建议用 uuid_generate_random()(Linux)或 CoCreateGuid()(Windows)
  • 修改 starting_lba/ending_lba 后,务必确保不与其它分区重叠,且落在设备总容量范围内(可通过 ioctl(fd, BLKGETSIZE64, &size) 获取)

用 C++ 操作需手动处理字节序和对齐,别依赖 struct 默认布局

x86_64 是小端,GPT 头中所有整数字段(如 my_lba、first_usable_lba)都按小端存储,但编译器可能因结构体对齐插入 padding,直接 memcpy 读写会导致字段错位或 CRC 校验失败。

  • 必须用 #pragma pack(1) 禁用结构体填充,例如:
    #pragma pack(1)
    struct gpt_header {
        uint64_t signature;
        uint32_t revision;
        uint32_t header_size;
        uint32_t header_crc32;
        uint32_t reserved;
        uint64_t my_lba;
        uint64_t alternate_lba;
        uint64_t first_usable_lba;
        uint64_t last_usable_lba;
        uint8_t disk_guid[16];
        uint64_t partition_entry_lba;
        uint32_t num_partition_entries;
        uint32_t sizeof_partition_entry;
        uint32_t partition_entries_crc32;
    };
    #pragma pack()
  • 读取后,所有 uint64_t/uint32_t 字段需用 le64toh() / le32toh() 转为主机序;写入前再用 htole64() 转回小端
  • 不要用 std::vector 直接 reinterpret_cast 成结构体指针——未保证对齐,UB 风险高

GPT 分区表不是普通文件,每个字节都牵扯启动、数据可见性甚至磁盘报废风险。哪怕只是改一个分区的 name 字段,也要同步更新 CRC、校验边界、刷新设备缓存——漏掉任意一环,轻则分区消失,重则系统无法启动。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

2025.06.09

5294

18

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

2025.07.04

5451

25

C++ 智能指针与现代内存管理
C++ 智能指针与现代内存管理

深入讲解 C++ 现代内存管理的核心工具——智能指针,涵盖 unique_ptr 独占所有权语义、shared_ptr 引用计数机制与循环引用问题、weak_ptr 弱引用的应用场景、make_unique/make_shared 工厂函数的性能优势、自定义删除器的编写、RAII 资源管理思想的实践,以及从裸指针迁移到智能指针的重构策略,帮助开发者编写安全无泄漏的现代 C++ 代码。

2026.04.23

379

31

css中的padding属性作用
css中的padding属性作用

在CSS中,padding属性用于设置元素的内边距。想了解更多padding的相关内容,可以阅读本专题下面的文章。

2023.12.07

3312

3

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.26

3419

3

查看端口占用情况windows
查看端口占用情况windows

端口占用是指与端口关联的软件占用端口而使得其他应用程序无法使用这些端口,端口占用问题是计算机系统编程领域的一个常见问题,端口占用的根本原因可能是操作系统的一些错误,服务器也可能会出现端口占用问题。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.07.27

2978

6

windows照片无法显示
windows照片无法显示

当我们尝试打开一张图片时,可能会出现一个错误提示,提示说"Windows照片查看器无法显示此图片,因为计算机上的可用内存不足",本专题为大家提供windows照片无法显示相关的文章,帮助大家解决该问题。

2023.08.01

1548

3

windows查看端口被占用的情况
windows查看端口被占用的情况

windows查看端口被占用的情况的方法:1、使用Windows自带的资源监视器;2、使用命令提示符查看端口信息;3、使用任务管理器查看占用端口的进程。本专题为大家提供windows查看端口被占用的情况的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2719

5

windows无法访问共享电脑
windows无法访问共享电脑

在现代社会中,共享电脑是办公室和家庭的重要组成部分。然而,有时我们可能会遇到Windows无法访问共享电脑的问题。这个问题可能会导致数据无法共享,影响工作和生活的正常进行。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.08

3350

4

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习