#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h> #define GPT_HEADER_SIGNATURE 0x5452415020494645LL typedef char *PSTR;
typedef const char *PCSTR; typedef struct {
uint64_t signature;
int revision;
int header_size;
uint32_t crc_header;
int reserved;
uint64_t lba_current;
uint64_t lba_backup;
uint64_t lba_first_usable;
uint64_t lba_last_usable;
uint8_t disk_guid[];
uint64_t lba_entry_start;
int entry_count;
int entry_size;
uint32_t crc_entries;
int reserved1[];
}__attribute__ ((packed)) gpt_header; typedef struct {
uint8_t type_guid[];
uint8_t unique_guid[];
uint64_t lba_first;
uint64_t lba_last;
uint64_t attribute;
uint16_t name[];
}__attribute__ ((packed)) partition_entry; typedef struct {
uint8_t status;
uint8_t start_head;
uint16_t start_sector;
uint8_t part_type;
uint8_t end_head;
uint16_t end_sector;
uint32_t first_abs_sector;
uint32_t sector_count;
}__attribute__ ((packed)) mbr_part_entry; typedef struct {
uint8_t boot_code[];
int unique_mbr_signature;
short unknown;
mbr_part_entry partition_record[];
uint16_t signature;
}__attribute__ ((packed)) legacy_mbr; static const uint32_t crc32_tab[] = { 0x00000000L, 0x77073096L, 0xee0e612cL,
0x990951baL, 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L,
0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL,
0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L,
0xf3b97148L, 0x84be41deL, 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L,
0x83d385c7L, 0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL,
0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L,
0x4c69105eL, 0xd56041e4L, 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L,
0xd20d85fdL, 0xa50ab56bL, 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L,
0xacbcf940L, 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L,
0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L,
0x56b3c423L, 0xcfba9599L, 0xb8bda50fL, 0x2802b89eL, 0x5f058808L,
0xc60cd9b2L, 0xb10be924L, 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL,
0xb6662d3dL, 0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL,
0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L,
0x0f00f934L, 0x9609a88eL, 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL,
0x91646c97L, 0xe6635c01L, 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L,
0xf262004eL, 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L,
0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL,
0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL,
0xa3bc0074L, 0xd4bb30e2L, 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL,
0xd3d6f4fbL, 0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L,
0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL,
0x270241aaL, 0xbe0b1010L, 0xc90c2086L, 0x5768b525L, 0x206f85b3L,
0xb966d409L, 0xce61e49fL, 0x5edef90eL, 0x29d9c998L, 0xb0d09822L,
0xc7d7a8b4L, 0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL,
0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL, 0xead54739L,
0x9dd277afL, 0x04db2615L, 0x73dc1683L, 0xe3630b12L, 0x94643b84L,
0x0d6d6a3eL, 0x7a6a5aa8L, 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L,
0x7d079eb1L, 0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL,
0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L,
0x89d32be0L, 0x10da7a5aL, 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L,
0x17b7be43L, 0x60b08ed5L, 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L,
0x4fdff252L, 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL,
0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L, 0xdf60efc3L,
0xa867df55L, 0x316e8eefL, 0x4669be79L, 0xcb61b38cL, 0xbc66831aL,
0x256fd2a0L, 0x5268e236L, 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L,
0x5505262fL, 0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L,
0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L,
0xec63f226L, 0x756aa39cL, 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL,
0x72076785L, 0x05005713L, 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL,
0x0cb61b38L, 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L,
0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL,
0xf6b9265bL, 0x6fb077e1L, 0x18b74777L, 0x88085ae6L, 0xff0f6a70L,
0x66063bcaL, 0x11010b5cL, 0x8f659effL, 0xf862ae69L, 0x616bffd3L,
0x166ccf45L, 0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L,
0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL,
0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L,
0x47b2cf7fL, 0x30b5ffe9L, 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L,
0x24b4a3a6L, 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL,
0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L,
0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL };
static uint32_t __efi_crc32(const void *buf, int len, uint32_t seed) {
int i;
register uint32_t crc32val;
const unsigned char *s = buf;
crc32val = seed;
for (i = ; i < len; i++) {
crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> );
}
return crc32val;
} uint32_t crc32(const void *buf, int len) {
return (__efi_crc32(buf, len, ~0L) ^ ~0L);
} PSTR uuid_to_str(uint8_t *data) {
PSTR buf = (PSTR) malloc();
PCSTR hex = "0123456789ABCDEF"; PSTR p = buf;
uint32_t num = *((uint32_t *) data);
p += sprintf(p, "%08X-", num);
data += ; uint16_t num2 = *((uint16_t *) data);
p += sprintf(p, "%04hX-", num2);
data += ; num2 = *((uint16_t *) data);
p += sprintf(p, "%04hX-", num2);
data += ; int i;
for (i = ; i < ; i++) {
if (i == ) *p++ = '-';
*p++ = hex[data[i] >> ];
*p++ = hex[data[i] & 0xF];
} buf[] = '\0';
return buf;
} wchar_t *utf16_to_wchar(uint16_t *str, int len) {
int i = ;
wchar_t *buf = (wchar_t *) malloc((len + ) * sizeof(wchar_t));
for (; i < len; i++)
buf[i] = (wchar_t) str[i];
buf[len] = L'\0';
return buf;
} int measure_block_size(int fd, int isAlt) {
int i = , offset, size = , whence = isAlt ? SEEK_END : SEEK_SET;
uint64_t signature;
for (; i < ; i++) {
offset = i * size;
if (lseek(fd, isAlt ? (- * offset) : offset, whence) == -) {
perror("Can't lseek"); return -;
}
signature = ;
if (read(fd, &signature, ) == -) {
perror("read file error"); return -;
}
if (signature == GPT_HEADER_SIGNATURE) return offset;
}
return ;
} int print_legacy_mbr(int fd) {
legacy_mbr mbr;
memset(&mbr, , sizeof(legacy_mbr));
if (read(fd, &mbr, sizeof(legacy_mbr)) == -) {
perror("read file error"); return -;
} mbr_part_entry empty;
memset(&empty, , sizeof(mbr_part_entry));
mbr_part_entry *p;
int i = ;
for (; i < ; i++) {
p = &mbr.partition_record[i];
if (!memcmp(p, &empty, sizeof(mbr_part_entry))) continue;
printf("status=%hhu\tstart_head=%hhu\tstart_sector=%hu\tpart_type=0x%hhx\t"
"end_head=%hhu\tend_sector=%hu\tfirst_abs_sector=%u\tsector_count=%u\n",
p->status, p->start_head, p->start_sector, p->part_type,
p->end_head, p->end_sector, p->first_abs_sector,
p->sector_count);
} printf("signature=0x%hX\n", mbr.signature);
return ;
} int print_gpt_header(int fd, gpt_header *gpt) {
memset(gpt, , sizeof(gpt_header));
if (read(fd, gpt, sizeof(gpt_header)) == -) {
perror("read file error"); return -;
} char sz[];
memcpy(sz, &gpt->signature, );
sz[] = '\0';
printf("signature=%s\n", sz);
printf("revision=%d\n", gpt->revision);
printf("header_size=%d\n", gpt->header_size);
printf("crc_header=0x%X\n", gpt->crc_header);
printf("lba_current=%lu\n", gpt->lba_current);
printf("lba_backup=%lu\n", gpt->lba_backup);
printf("lba_first_usable=%lu\n", gpt->lba_first_usable);
printf("lba_last_usable=%lu\n", gpt->lba_last_usable);
PSTR buf = uuid_to_str(gpt->disk_guid);
printf("disk_guid=%s\n", buf);
free(buf);
printf("lba_entry_start=%lu\n", gpt->lba_entry_start);
printf("entry_count=%d\n", gpt->entry_count);
printf("entry_size=%d\n", gpt->entry_size);
printf("crc_entries=0x%X\n", gpt->crc_entries); uint32_t oldcrc = gpt->crc_header;
gpt->crc_header = ;
if (crc32(gpt, gpt->header_size) != oldcrc)
fputs("Bad crc_header.\n", stderr);
gpt->crc_header = oldcrc; return ;
} int print_gpt_partitions(int fd, const gpt_header *gpt) {
int entries_size = gpt->entry_count * gpt->entry_size;
PSTR buf = (PSTR) malloc(entries_size);
if (read(fd, buf, entries_size) == -) {
perror("read file error"); return -;
} wchar_t *gpt_entry_name;
partition_entry *gentry = (partition_entry *) buf;
partition_entry gentry_empty;
memset(&gentry_empty, , sizeof(partition_entry)); PSTR tmp;
int i = ;
for (; i < gpt->entry_count; i++) {
if (!memcmp(gentry, &gentry_empty, sizeof(partition_entry)))
continue;
gpt_entry_name = utf16_to_wchar(gentry->name, );
tmp = uuid_to_str(gentry->type_guid);
printf("type_guid=%s\t", tmp);
free(tmp);
tmp = uuid_to_str(gentry->unique_guid);
printf("unique_guid=%s\t", tmp);
free(tmp);
printf("lba_first=%lu\tlba_last=%lu\tattribute=%lu\tname=%ls\n",
gentry->lba_first, gentry->lba_last, gentry->attribute,
gpt_entry_name);
free(gpt_entry_name);
gentry++;
} if (crc32(buf, entries_size) != gpt->crc_entries)
fputs("Bad crc_entries.\n", stderr); free(buf);
return ;
} /*
* Usage1: Show primary GPT header and entries
* <app> /dev/sda
* Usage2: Show secondary GPT header and entries
* <app> /dev/sda alternate
*/
int main(int argc, PCSTR argv[]) {
int exitCode = EXIT_SUCCESS;
PCSTR filename;
int isAlternate = ;
if (argc < ) {
fputs("Missing argument.\n", stderr);
return EXIT_FAILURE;
} else {
filename = argv[];
if (argc > ) isAlternate = ;
} int fd = open(filename, O_RDONLY);
if (fd == -) {
perror("Can't open device"); return EXIT_FAILURE;
} int logical_blk_size = measure_block_size(fd, isAlternate);
if (logical_blk_size < ) {
if (!logical_blk_size)
fputs("Unknown logical block size.\n", stderr);
exitCode = EXIT_FAILURE; goto END;
}
printf("Logical block size: %dbytes\n\n", logical_blk_size); if (isAlternate) {
if (lseek(fd, - * logical_blk_size, SEEK_END) == -) {
perror("Can't lseek"); exitCode = EXIT_FAILURE; goto END;
}
} else {
if (lseek(fd, , SEEK_SET) == -) {
perror("Can't lseek"); exitCode = EXIT_FAILURE; goto END;
}
if (print_legacy_mbr(fd)) {
exitCode = EXIT_FAILURE; goto END;
}
putchar('\n'); if (lseek(fd, logical_blk_size, SEEK_SET) == -) {
perror("Can't lseek"); exitCode = EXIT_FAILURE; goto END;
}
} gpt_header header;
if (print_gpt_header(fd, &header)) {
exitCode = EXIT_FAILURE; goto END;
}
putchar('\n'); if (isAlternate) {
if (lseek(fd, - * (header.entry_count * header.entry_size + logical_blk_size), SEEK_END) == -) {
perror("Can't lseek"); exitCode = EXIT_FAILURE; goto END;
}
} else if (lseek(fd, logical_blk_size * header.lba_entry_start, SEEK_SET) == -) {
perror("Can't lseek"); exitCode = EXIT_FAILURE; goto END;
}
print_gpt_partitions(fd, &header); END:
close(fd);
return exitCode;
}

C语言实现GPT头和分区表的读取(gcc)的更多相关文章

  1. 转:C语言中的头文件可以自己写吗?

    转自:http://www.eefocus.com/computer00/blog/08-09/155791_9ebdc.html 一些初学C语言的人,不知道头文件(*.h文件)原来还可以自己写的. ...

  2. 为什么C语言会有头文件

    前段时间一个刚转到C语言的同事问我,为什么C会多一个头文件,而不是像Java和Python那样所有的代码都在源文件中.我当时回答的是C是静态语言很多东西都是需要事先定义的,所以按照惯例我们是将所有的定 ...

  3. C语言中的头文件

    1.头文件#include <> :表示引用标准库头文件,编译器会从系统配置的库环境中去寻找 2.头文件#include "":一般表示用户自己定义使用的头文件,编译器 ...

  4. [CentOS7] parted用于磁盘分区(同时支持GPT和MBR分区表)

    声明:本文主要总结自:鸟哥的Linux私房菜-第七章.Linux 磁碟與檔案系統管理,如有侵权,请通知博主 fdisk支持MBR分区表,gdisk支持GPT分区表,而parted支持两者 不知道为什么 ...

  5. C语言笔记 11_头文件&强制类型转换&错误处理&递归

    头文件 头文件是扩展名为 .h 的文件,包含了 C 函数声明和宏定义,被多个源文件中引用共享.有两种类型的头文件:程序员编写的头文件和编译器自带的头文件. 在程序中要使用头文件,需要使用 C 预处理指 ...

  6. 正确使用c语言中的头文件

    我们在使用c编程的时候经常会遇到头文件,前段时间我自己做了个小项目的时候,也遇到了关于头文件的问题. 预处理器发现#include 指令后,就会寻找后跟的文件名并把这个文件包含的内容包含到当前文件中. ...

  7. 整理一下C++语言中的头文件

    对于每一个像我一样的蒟蒻来说,C++最重要的东西就是头文件的使用了.由于初学,直到现在我打代码还是靠一些事先写好的的头文件,仍然不能做到使用自己需要的.最近看了几位大佬打代码,心中突然闪过要把自己冗长 ...

  8. C语言库函数,头文件

    参看:https://zhidao.baidu.com/question/328173842.html 该文件包含了的C语言标准库函数的定义 stdlib.h里面定义了五种类型.一些宏和通用工具函数. ...

  9. C语言之在头文件中定义全局变量

    通常情况下,都是在C文件中定义全局变量,在头文件中声明,但是,如果我们定义的全局变量需要被很多的C文件使用的话,那么将全局变量定义在头文件里面会方便很多,那到底是如何实现的? os_var.c文件内容 ...

随机推荐

  1. python整理之(字符串、元组、列表、字典)

    一.关于字符串的整理总结 对于字符串的操作常用的有这些: 字符串的操作通过dir()函数可以查看 我们先整理没有下划线的用法,有下划线的暂时不去考虑. 1.capitalize 功能:使字符串的首字母 ...

  2. 利用SPM工具运行自己创建的小组件(使用common-model向后台接口请求数据)

    步骤如下: 1.安装依赖:spm install -e 2.编译:spm build (编译好的东西会放在trunk-dist里面) 3.发布:spm app -d (会出来一个export端口,一般 ...

  3. oracle数据库从入门到精通之四

    序列是oracle中较为重要的概念事务对于ddl是不起作用的查询,更新,数据表,约束这些个概念要掌握.在许多数据库之中都会存在一种数据类型--自动增长列,它能够创建流水号12c之前并没有提供这样一个自 ...

  4. [原]php远程odbc连接sqlsvr数据库,自定义端口,命名实例的连接方式

    远程odbc连接sqlsvr数据库,自定义端口,命名实例的连接方式,默认如果不修改的话sqlsvr的端口号是1433,默认实例名就是机器名,,如果既用了命名实例,又改了默认端口,改怎么连接数据库呢? ...

  5. electron知识点

    1.打开chrome开发工具栏: BrowserWindow.openDevTools();

  6. 在实现和使用上与select和poll有很大差异

    在看此课程的读者,希望先阅读关于函数基础内容 函数定义与函数作用域 的章节,因为此课程或多或少会涉及函数基础的内容,而基础内容,本人放在 函数定义函数作用域 章节. 本文直接赘述函数参数与闭包,若涉及 ...

  7. Microsoft Win32 to Microsoft .NET Framework API Map

    Microsoft Win32 to Microsoft .NET Framework API Map .NET Development (General) Technical Articles   ...

  8. 使用curl命令获取文件下载速度

    使用curl可以下载网络内容,那如何获取curl下载时的下载速度呢,使用下面的命令即可: # curl -Lo /dev/null -skw "%{speed_download}\n&quo ...

  9. Netty系列之Netty百万级推送服务设计要点

    1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...

  10. 阿里weex学习入门必备

    1.阿里weex学习前景 至于这些东西,可以参照一下链接去看看其作用.... http://share.iclient.ifeng.com/news/sharenews.f?forward=1& ...