2 Display partition tables entries in a file
4 Author: TJ <linux@tjworld.net>
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, version 3 of the License.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <sys/types.h>
30 #define PT_SIGNATURE 0x1FE
32 static const char const *version = "1.0.0";
47 struct partition_table {
49 unsigned char first_head;
50 unsigned int first_cylinder;
51 unsigned char first_sector;
53 unsigned char last_head;
54 unsigned int last_cylinder;
55 unsigned char last_sector;
56 unsigned int first_LBA;
57 unsigned int count_LBA;
61 usage(const char *name) {
62 printf("Usage: %s [-d] -f <needle>\n"
63 " version %s\n", name, version);
64 printf("Copyright 2010 TJ <linux@tjworld.net>\n"
65 "Licensed under the terms of the GNU GPL v3\n\n"
66 "\t-d\tprint values in decimal not hexadecimal\n"
67 "\t-f\tpath to the file containing the partition table (it is scanned for sectors containing the signature)\n"
72 main(int argc, char *argv[], char *env[]) {
74 int c, use_decimal, pt_fd;
78 char signature[2] = {0x55, 0xAA};
79 pt_name = pt_mmap = NULL;
82 if (argc > 1) { // must have some parameters
85 while ((c = getopt(argc, argv, "f:d")) != -1 ) { // iterate the options
98 if ((pt_fd = open(pt_name, O_RDONLY)) == -1) {
99 perror("Unable to open file");
104 fstat(pt_fd, &pt_stat);
105 fprintf(stderr, "Base:\t%s\n", use_decimal == 1 ? "decimal" : "hexadecimal");
106 fprintf(stderr, "File:\t\t%12ld\t%s\n", pt_stat.st_size, pt_name);
108 if(MAP_FAILED == (pt_mmap = mmap(pt_mmap, pt_stat.st_size, PROT_READ, MAP_SHARED, pt_fd, 0))) {
109 perror("Unable to memory-map file");
114 char *format[2][4] = {
115 { "%8lX", "%08lX", "%02X", "%04X" },
116 { "%8ld", "%10ld", "%2d", "%4d" }
118 struct partition_table pt_table[4];
119 unsigned long offset, found;
120 unsigned long sector;
121 unsigned int pt_entry;
122 unsigned int pt_offset;
124 fprintf(stderr, "Searching...\n");
125 for (offset = 0, sector = 0; offset <= pt_stat.st_size; offset+=512, sector++) {
126 if ( memcmp(signature, pt_mmap + offset + PT_SIGNATURE, 2) == 0) {
128 sprintf(fmt_spec, "Signature found. sector: %s offset:%s\n", format[use_decimal][0], format[use_decimal][1]);
129 printf(fmt_spec, sector, offset);
131 for (pt_entry = 0; pt_entry < 4; pt_entry++) {
132 pt_offset = offset + (pt_entry * 16);
133 pt_table[pt_entry].status = *(unsigned char *)(pt_mmap + pt_offset + PT_BASE + PT_STATUS);
134 pt_table[pt_entry].type = *(unsigned char *)(pt_mmap + pt_offset + PT_BASE + PT_TYPE);
135 pt_table[pt_entry].first_cylinder = *(unsigned char *)(pt_mmap + pt_offset + PT_BASE + PT_FIRST_CYLINDER);
136 pt_table[pt_entry].first_cylinder |= (((*(unsigned char *)(pt_mmap + pt_offset + PT_BASE + PT_FIRST_SECTOR)) && 0xC0) << 8);
137 pt_table[pt_entry].first_head = *(unsigned char *)(pt_mmap + pt_offset + PT_BASE + PT_FIRST_HEAD);
138 pt_table[pt_entry].first_sector = (*(unsigned char *)(pt_mmap + pt_offset + PT_BASE + PT_FIRST_SECTOR)) && 0x3F;
139 pt_table[pt_entry].last_cylinder = *(unsigned char *)(pt_mmap + pt_offset + PT_BASE + PT_LAST_CYLINDER);
140 pt_table[pt_entry].last_cylinder |= (((*(unsigned char *)(pt_mmap + pt_offset + PT_BASE + PT_LAST_SECTOR)) && 0xC0) << 8);
141 pt_table[pt_entry].last_head = *(unsigned char *)(pt_mmap + pt_offset + PT_BASE + PT_LAST_HEAD);
142 pt_table[pt_entry].last_sector = (*(unsigned char *)(pt_mmap + pt_offset + PT_BASE + PT_LAST_SECTOR)) && 0x3F;
143 pt_table[pt_entry].first_LBA = *(unsigned int *)(pt_mmap + pt_offset + PT_BASE + PT_FIRST_LBA);
144 pt_table[pt_entry].count_LBA = *(unsigned int *)(pt_mmap + pt_offset + PT_BASE + PT_COUNT_LBA);
146 sprintf(fmt_spec, "%%d %%s %s %s %s %s %s %s %s %s %s (next %s)\n",
147 format[use_decimal][2], // type
148 format[use_decimal][3], // cyl
149 format[use_decimal][2], // head
150 format[use_decimal][2], // sector
151 format[use_decimal][3], // cyl
152 format[use_decimal][2], // head
153 format[use_decimal][2], // sector
154 format[use_decimal][1], // LBA
155 format[use_decimal][1], // LBA count
156 format[use_decimal][1] // LBA next
160 pt_table[pt_entry].status == 0x80 ? "A" : " ",
161 pt_table[pt_entry].type,
162 pt_table[pt_entry].first_cylinder,
163 pt_table[pt_entry].first_head,
164 pt_table[pt_entry].first_sector,
165 pt_table[pt_entry].last_cylinder,
166 pt_table[pt_entry].last_head,
167 pt_table[pt_entry].last_sector,
168 pt_table[pt_entry].first_LBA,
169 pt_table[pt_entry].count_LBA,
170 pt_table[pt_entry].first_LBA + pt_table[pt_entry].count_LBA
175 fprintf(stderr, "Done.\n");
182 if (pt_mmap > 0) munmap(pt_mmap, pt_stat.st_size);
183 if (pt_fd > 0) close(pt_fd);