3 * Platform-independent code common to gptsync and showpart
5 * Copyright (c) 2006-2007 Christoph Pfisterer
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * * Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the
20 * * Neither the name of Christoph Pfisterer nor the names of the
21 * contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 UINT8 empty_guid
[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
43 PARTITION_INFO mbr_parts
[4];
44 UINTN mbr_part_count
= 0;
45 PARTITION_INFO gpt_parts
[128];
46 UINTN gpt_part_count
= 0;
48 PARTITION_INFO new_mbr_parts
[4];
49 UINTN new_mbr_part_count
= 0;
53 MBR_PARTTYPE mbr_types
[] = {
54 { 0x01, STR("FAT12 (CHS)") },
55 { 0x04, STR("FAT16 <32M (CHS)") },
56 { 0x05, STR("Extended (CHS)") },
57 { 0x06, STR("FAT16 (CHS)") },
58 { 0x07, STR("NTFS/HPFS") },
59 { 0x0b, STR("FAT32 (CHS)") },
60 { 0x0c, STR("FAT32 (LBA)") },
61 { 0x0e, STR("FAT16 (LBA)") },
62 { 0x0f, STR("Extended (LBA)") },
63 { 0x11, STR("Hidden FAT12 (CHS)") },
64 { 0x14, STR("Hidden FAT16 <32M (CHS)") },
65 { 0x16, STR("Hidden FAT16 (CHS)") },
66 { 0x17, STR("Hidden NTFS/HPFS") },
67 { 0x1b, STR("Hidden FAT32 (CHS)") },
68 { 0x1c, STR("Hidden FAT32 (LBA)") },
69 { 0x1e, STR("Hidden FAT16 (LBA)") },
70 { 0x82, STR("Linux swap / Solaris") },
71 { 0x83, STR("Linux") },
72 { 0x85, STR("Linux Extended") },
73 { 0x86, STR("NT FAT volume set") },
74 { 0x87, STR("NTFS volume set") },
75 { 0x8e, STR("Linux LVM") },
76 { 0xa5, STR("FreeBSD") },
77 { 0xa6, STR("OpenBSD") },
78 { 0xa7, STR("NeXTSTEP") },
79 { 0xa8, STR("Mac OS X UFS") },
80 { 0xa9, STR("NetBSD") },
81 { 0xab, STR("Mac OS X Boot") },
82 { 0xac, STR("Apple RAID") },
83 { 0xaf, STR("Mac OS X HFS+") },
84 { 0xbe, STR("Solaris Boot") },
85 { 0xbf, STR("Solaris") },
86 { 0xeb, STR("BeOS") },
87 { 0xee, STR("EFI Protective") },
88 { 0xef, STR("EFI System (FAT)") },
89 { 0xfd, STR("Linux RAID") },
93 GPT_PARTTYPE gpt_types
[] = {
95 { "\x32\x97\x01\xF4\x6E\x06\x12\x4E\x82\x73\x34\x6C\x56\x41\x49\x4F", 0x00, STR("Sony System (FAT)"), GPT_KIND_FATAL
},
96 // Defined by EFI/UEFI specification
97 { "\x28\x73\x2A\xC1\x1F\xF8\xD2\x11\xBA\x4B\x00\xA0\xC9\x3E\xC9\x3B", 0xef, STR("EFI System (FAT)"), GPT_KIND_SYSTEM
},
98 { "\x41\xEE\x4D\x02\xE7\x33\xD3\x11\x9D\x69\x00\x08\xC7\x81\xF3\x9F", 0x00, STR("MBR partition scheme"), GPT_KIND_FATAL
},
99 // Generally well-known
100 { "\x16\xE3\xC9\xE3\x5C\x0B\xB8\x4D\x81\x7D\xF9\x2D\xF0\x02\x15\xAE", 0x00, STR("MS Reserved"), GPT_KIND_SYSTEM
},
101 { "\xA2\xA0\xD0\xEB\xE5\xB9\x33\x44\x87\xC0\x68\xB6\xB7\x26\x99\xC7", 0x00, STR("Basic Data"), GPT_KIND_BASIC_DATA
},
103 { "\xAA\xC8\x08\x58\x8F\x7E\xE0\x42\x85\xD2\xE1\xE9\x04\x34\xCF\xB3", 0x00, STR("MS LDM Metadata"), GPT_KIND_FATAL
},
104 { "\xA0\x60\x9B\xAF\x31\x14\x62\x4F\xBC\x68\x33\x11\x71\x4A\x69\xAD", 0x00, STR("MS LDM Data"), GPT_KIND_FATAL
},
105 { "\x1E\x4C\x89\x75\xEB\x3A\xD3\x11\xB7\xC1\x7B\x03\xA0\x00\x00\x00", 0x00, STR("HP/UX Data"), GPT_KIND_DATA
},
106 { "\x28\xE7\xA1\xE2\xE3\x32\xD6\x11\xA6\x82\x7B\x03\xA0\x00\x00\x00", 0x00, STR("HP/UX Service"), GPT_KIND_SYSTEM
},
107 // From Linux repository, fs/partitions/efi.h
108 { "\x0F\x88\x9D\xA1\xFC\x05\x3B\x4D\xA0\x06\x74\x3F\x0F\x84\x91\x1E", 0xfd, STR("Linux RAID"), GPT_KIND_DATA
},
109 { "\x6D\xFD\x57\x06\xAB\xA4\xC4\x43\x84\xE5\x09\x33\xC8\x4B\x4F\x4F", 0x82, STR("Linux Swap"), GPT_KIND_SYSTEM
},
110 { "\x79\xD3\xD6\xE6\x07\xF5\xC2\x44\xA2\x3C\x23\x8F\x2A\x3D\xF9\x28", 0x8e, STR("Linux LVM"), GPT_KIND_DATA
},
111 { "\xAF\x3D\xC6\x0F\x83\x84\x72\x47\x8E\x79\x3D\x69\xD8\x47\x7D\xE4", 0x83, STR("Linux Filesystem"), GPT_KIND_DATA
},
113 { "\x39\x33\xA6\x8D\x07\x00\xC0\x60\xC4\x36\x08\x3A\xC8\x23\x09\x08", 0x00, STR("Linux Reserved"), GPT_KIND_SYSTEM
},
114 // From grub2 repository, grub/include/grub/gpt_partition.h
115 { "\x48\x61\x68\x21\x49\x64\x6F\x6E\x74\x4E\x65\x65\x64\x45\x46\x49", 0x00, STR("GRUB2 BIOS Boot"), GPT_KIND_SYSTEM
},
116 // From FreeBSD repository, sys/sys/gpt.h
117 { "\xB4\x7C\x6E\x51\xCF\x6E\xD6\x11\x8F\xF8\x00\x02\x2D\x09\x71\x2B", 0xa5, STR("FreeBSD Data"), GPT_KIND_DATA
},
118 { "\xB5\x7C\x6E\x51\xCF\x6E\xD6\x11\x8F\xF8\x00\x02\x2D\x09\x71\x2B", 0x00, STR("FreeBSD Swap"), GPT_KIND_SYSTEM
},
119 { "\xB6\x7C\x6E\x51\xCF\x6E\xD6\x11\x8F\xF8\x00\x02\x2D\x09\x71\x2B", 0xa5, STR("FreeBSD UFS"), GPT_KIND_DATA
},
120 { "\xB8\x7C\x6E\x51\xCF\x6E\xD6\x11\x8F\xF8\x00\x02\x2D\x09\x71\x2B", 0x00, STR("FreeBSD Vinum"), GPT_KIND_DATA
},
121 { "\xBA\x7C\x6E\x51\xCF\x6E\xD6\x11\x8F\xF8\x00\x02\x2D\x09\x71\x2B", 0xa5, STR("FreeBSD ZFS"), GPT_KIND_DATA
},
122 { "\x9D\x6B\xBD\x83\x41\x7F\xDC\x11\xBE\x0B\x00\x15\x60\xB8\x4F\x0F", 0xa5, STR("FreeBSD Boot"), GPT_KIND_DATA
},
123 // From NetBSD repository, sys/sys/disklabel_gpt.h
124 { "\x32\x8D\xF4\x49\x0E\xB1\xDC\x11\xB9\x9B\x00\x19\xD1\x87\x96\x48", 0x00, STR("NetBSD Swap"), GPT_KIND_SYSTEM
},
125 { "\x5A\x8D\xF4\x49\x0E\xB1\xDC\x11\xB9\x9B\x00\x19\xD1\x87\x96\x48", 0xa9, STR("NetBSD FFS"), GPT_KIND_DATA
},
126 { "\x82\x8D\xF4\x49\x0E\xB1\xDC\x11\xB9\x9B\x00\x19\xD1\x87\x96\x48", 0xa9, STR("NetBSD LFS"), GPT_KIND_DATA
},
127 { "\xAA\x8D\xF4\x49\x0E\xB1\xDC\x11\xB9\x9B\x00\x19\xD1\x87\x96\x48", 0xa9, STR("NetBSD RAID"), GPT_KIND_DATA
},
128 { "\xC4\x19\xB5\x2D\x0E\xB1\xDC\x11\xB9\x9B\x00\x19\xD1\x87\x96\x48", 0xa9, STR("NetBSD CCD"), GPT_KIND_DATA
},
129 { "\xEC\x19\xB5\x2D\x0E\xB1\xDC\x11\xB9\x9B\x00\x19\xD1\x87\x96\x48", 0xa9, STR("NetBSD CGD"), GPT_KIND_DATA
},
130 // From http://developer.apple.com/mac/library/technotes/tn2006/tn2166.html
131 // { "\x00\x53\x46\x48\x00\x00\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0x00, STR("Mac OS X HFS+"), GPT_KIND_SYSTEM },
132 { "\x00\x53\x46\x48\x00\x00\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0xaf, STR("Mac OS X HFS+"), GPT_KIND_DATA
},
133 { "\x72\x6F\x74\x53\x67\x61\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0xaf, STR("Mac OS X Core Storage"), GPT_KIND_DATA
},
134 { "\x00\x53\x46\x55\x00\x00\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0xa8, STR("Mac OS X UFS"), GPT_KIND_DATA
},
135 { "\x74\x6F\x6F\x42\x00\x00\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0xab, STR("Mac OS X Boot"), GPT_KIND_DATA
},
136 { "\x44\x49\x41\x52\x00\x00\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0xac, STR("Apple RAID"), GPT_KIND_DATA
},
137 { "\x44\x49\x41\x52\x4F\x5F\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0xac, STR("Apple RAID (Offline)"), GPT_KIND_DATA
},
138 { "\x65\x62\x61\x4C\x00\x6C\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0x00, STR("Apple Label"), GPT_KIND_SYSTEM
},
140 { "\x6F\x63\x65\x52\x65\x76\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0x00, STR("Apple TV Recovery"), GPT_KIND_DATA
},
141 // From OpenSolaris repository, usr/src/uts/common/sys/efi_partition.h
142 { "\x7f\x23\x96\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0x00, STR("Solaris Reserved"), GPT_KIND_SYSTEM
},
143 { "\x45\xCB\x82\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0xbf, STR("Solaris Boot"), GPT_KIND_DATA
},
144 { "\x4D\xCF\x85\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0xbf, STR("Solaris Root"), GPT_KIND_DATA
},
145 { "\x6F\xC4\x87\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0x00, STR("Solaris Swap"), GPT_KIND_SYSTEM
},
146 { "\xC3\x8C\x89\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0xbf, STR("Solaris Usr / Apple ZFS"), GPT_KIND_DATA
},
147 { "\x2B\x64\x8B\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0x00, STR("Solaris Backup"), GPT_KIND_SYSTEM
},
148 { "\xC7\x2A\x8D\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0x00, STR("Solaris Reserved (Stand)"), GPT_KIND_SYSTEM
},
149 { "\xE9\xF2\x8E\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0xbf, STR("Solaris Var"), GPT_KIND_DATA
},
150 { "\x39\xBA\x90\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0xbf, STR("Solaris Home"), GPT_KIND_DATA
},
151 { "\xA5\x83\x92\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0x00, STR("Solaris Alternate Sector"), GPT_KIND_SYSTEM
},
152 { "\x3B\x5A\x94\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0x00, STR("Solaris Reserved (Cache)"), GPT_KIND_SYSTEM
},
153 { "\xD1\x30\x96\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0x00, STR("Solaris Reserved"), GPT_KIND_SYSTEM
},
154 { "\x67\x07\x98\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0x00, STR("Solaris Reserved"), GPT_KIND_SYSTEM
},
156 { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 0, NULL
, 0 },
158 GPT_PARTTYPE gpt_dummy_type
=
159 { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 0, STR("Unknown"), GPT_KIND_FATAL
};
165 CHARN
* mbr_parttype_name(UINT8 type
)
169 for (i
= 0; mbr_types
[i
].name
; i
++)
170 if (mbr_types
[i
].type
== type
)
171 return mbr_types
[i
].name
;
172 return STR("Unknown");
180 MBR_PART_INFO
*table
;
182 Print(L
"\nCurrent MBR partition table:\n");
185 status
= read_sector(0, sector
);
189 // check for validity
190 if (*((UINT16
*)(sector
+ 510)) != 0xaa55) {
191 Print(L
" No MBR partition table present!\n");
194 table
= (MBR_PART_INFO
*)(sector
+ 446);
195 for (i
= 0; i
< 4; i
++) {
196 if (table
[i
].flags
!= 0x00 && table
[i
].flags
!= 0x80) {
197 Print(L
" MBR partition table is invalid!\n");
204 for (i
= 0; i
< 4; i
++) {
205 if (table
[i
].start_lba
> 0 && table
[i
].size
> 0) {
211 Print(L
" No partitions defined\n");
215 // dump current state & fill internal structures
216 Print(L
" # A Start LBA End LBA Type\n");
217 for (i
= 0; i
< 4; i
++) {
218 if (table
[i
].start_lba
== 0 || table
[i
].size
== 0)
221 mbr_parts
[mbr_part_count
].index
= i
;
222 mbr_parts
[mbr_part_count
].start_lba
= (UINT64
)table
[i
].start_lba
;
223 mbr_parts
[mbr_part_count
].end_lba
= (UINT64
)table
[i
].start_lba
+ (UINT64
)table
[i
].size
- 1;
224 mbr_parts
[mbr_part_count
].mbr_type
= table
[i
].type
;
225 mbr_parts
[mbr_part_count
].active
= (table
[i
].flags
== 0x80) ? TRUE
: FALSE
;
227 Print(L
" %d %s %12lld %12lld %02x %s\n",
228 mbr_parts
[mbr_part_count
].index
+ 1,
229 mbr_parts
[mbr_part_count
].active
? STR("*") : STR(" "),
230 mbr_parts
[mbr_part_count
].start_lba
,
231 mbr_parts
[mbr_part_count
].end_lba
,
232 mbr_parts
[mbr_part_count
].mbr_type
,
233 mbr_parttype_name(mbr_parts
[mbr_part_count
].mbr_type
));
245 GPT_PARTTYPE
* gpt_parttype(UINT8
*type_guid
)
249 for (i
= 0; gpt_types
[i
].name
; i
++)
250 if (guids_are_equal(gpt_types
[i
].guid
, type_guid
))
251 return &(gpt_types
[i
]);
252 return &gpt_dummy_type
;
261 UINTN entry_count
, entry_size
, i
;
263 Print(L
"\nCurrent GUID partition table:\n");
266 status
= read_sector(1, sector
);
271 header
= (GPT_HEADER
*)sector
;
272 if (header
->signature
!= 0x5452415020494645ULL
) {
273 Print(L
" No GPT partition table present!\n");
276 if (header
->spec_revision
!= 0x00010000UL
) {
277 Print(L
" Warning: Unknown GPT spec revision 0x%08x\n", header
->spec_revision
);
279 if ((512 % header
->entry_size
) > 0 || header
->entry_size
> 512) {
280 Print(L
" Error: Invalid GPT entry size (misaligned or more than 512 bytes)\n");
285 entry_lba
= header
->entry_lba
;
286 entry_size
= header
->entry_size
;
287 entry_count
= header
->entry_count
;
289 for (i
= 0; i
< entry_count
; i
++) {
290 if (((i
* entry_size
) % 512) == 0) {
291 status
= read_sector(entry_lba
, sector
);
296 entry
= (GPT_ENTRY
*)(sector
+ ((i
* entry_size
) % 512));
298 if (guids_are_equal(entry
->type_guid
, empty_guid
))
300 if (gpt_part_count
== 0) {
301 Print(L
" # Start LBA End LBA Type\n");
304 gpt_parts
[gpt_part_count
].index
= i
;
305 gpt_parts
[gpt_part_count
].start_lba
= entry
->start_lba
;
306 gpt_parts
[gpt_part_count
].end_lba
= entry
->end_lba
;
307 gpt_parts
[gpt_part_count
].mbr_type
= 0;
308 copy_guid(gpt_parts
[gpt_part_count
].gpt_type
, entry
->type_guid
);
309 gpt_parts
[gpt_part_count
].gpt_parttype
= gpt_parttype(gpt_parts
[gpt_part_count
].gpt_type
);
310 gpt_parts
[gpt_part_count
].active
= FALSE
;
312 Print(L
" %d %12lld %12lld %s\n",
313 gpt_parts
[gpt_part_count
].index
+ 1,
314 gpt_parts
[gpt_part_count
].start_lba
,
315 gpt_parts
[gpt_part_count
].end_lba
,
316 gpt_parts
[gpt_part_count
].gpt_parttype
->name
);
320 if (gpt_part_count
== 0) {
321 Print(L
" No partitions defined\n");
329 // detect file system type
332 UINTN
detect_mbrtype_fs(UINT64 partlba
, UINTN
*parttype
, CHARN
**fsname
)
335 UINTN signature
, score
;
336 UINTN sectsize
, clustersize
, reserved
, fatcount
, dirsize
, sectcount
, fatsize
, clustercount
;
338 *fsname
= STR("Unknown");
341 // READ sector 0 / offset 0K
342 status
= read_sector(partlba
, sector
);
347 signature
= *((UINT32
*)(sector
));
348 if (signature
== 0x42534658) {
350 *fsname
= STR("XFS");
354 // detect FAT and NTFS
355 sectsize
= *((UINT16
*)(sector
+ 11));
356 clustersize
= sector
[13];
357 if (sectsize
>= 512 && (sectsize
& (sectsize
- 1)) == 0 &&
358 clustersize
> 0 && (clustersize
& (clustersize
- 1)) == 0) {
359 // preconditions for both FAT and NTFS are now met
361 if (CompareMem(sector
+ 3, "NTFS ", 8) == 0) {
363 *fsname
= STR("NTFS");
369 if ((sector
[0] == 0xEB && sector
[2] == 0x90) ||
373 if (sector
[510] == 0x55 && sector
[511] == 0xAA)
376 reserved
= *((UINT16
*)(sector
+ 14));
377 if (reserved
== 1 || reserved
== 32)
380 fatcount
= sector
[16];
383 // number of root dir entries
384 dirsize
= *((UINT16
*)(sector
+ 17));
385 // sector count (16-bit and 32-bit versions)
386 sectcount
= *((UINT16
*)(sector
+ 19));
388 sectcount
= *((UINT32
*)(sector
+ 32));
390 if (sector
[21] == 0xF0 || sector
[21] >= 0xF8)
392 // FAT size in sectors
393 fatsize
= *((UINT16
*)(sector
+ 22));
395 fatsize
= *((UINT32
*)(sector
+ 36));
397 // determine FAT type
398 dirsize
= ((dirsize
* 32) + (sectsize
- 1)) / sectsize
;
399 clustercount
= sectcount
- (reserved
+ (fatcount
* fatsize
) + dirsize
);
400 clustercount
/= clustersize
;
403 if (clustercount
< 4085) {
405 *fsname
= STR("FAT12");
406 } else if (clustercount
< 65525) {
408 *fsname
= STR("FAT16");
411 *fsname
= STR("FAT32");
413 // TODO: check if 0e and 0c are okay to use, maybe we should use 06 and 0b instead...
418 // READ sector 2 / offset 1K
419 status
= read_sector(partlba
+ 2, sector
);
424 signature
= *((UINT16
*)(sector
));
425 if (signature
== 0x4442) {
427 if (*((UINT16
*)(sector
+ 0x7c)) == 0x2B48)
428 *fsname
= STR("HFS Extended (HFS+)");
430 *fsname
= STR("HFS Standard");
432 } else if (signature
== 0x2B48) {
434 *fsname
= STR("HFS Extended (HFS+)");
438 // detect ext2/ext3/ext4
439 signature
= *((UINT16
*)(sector
+ 56));
440 if (signature
== 0xEF53) {
442 if (*((UINT16
*)(sector
+ 96)) & 0x02C0 ||
443 *((UINT16
*)(sector
+ 100)) & 0x0078)
444 *fsname
= STR("ext4");
445 else if (*((UINT16
*)(sector
+ 92)) & 0x0004)
446 *fsname
= STR("ext3");
448 *fsname
= STR("ext2");
452 // READ sector 128 / offset 64K
453 status
= read_sector(partlba
+ 128, sector
);
458 if (CompareMem(sector
+ 64, "_BHRfS_M", 8) == 0) {
460 *fsname
= STR("btrfs");
465 if (CompareMem(sector
+ 52, "ReIsErFs", 8) == 0 ||
466 CompareMem(sector
+ 52, "ReIsEr2Fs", 9) == 0 ||
467 CompareMem(sector
+ 52, "ReIsEr3Fs", 9) == 0) {
469 *fsname
= STR("ReiserFS");
474 if (CompareMem(sector
, "ReIsEr4", 7) == 0) {
476 *fsname
= STR("Reiser4");
480 // READ sector 64 / offset 32K
481 status
= read_sector(partlba
+ 64, sector
);
486 if (CompareMem(sector
, "JFS1", 4) == 0) {
488 *fsname
= STR("JFS");
492 // READ sector 16 / offset 8K
493 status
= read_sector(partlba
+ 16, sector
);
498 if (CompareMem(sector
+ 52, "ReIsErFs", 8) == 0 ||
499 CompareMem(sector
+ 52, "ReIsEr2Fs", 9) == 0 ||
500 CompareMem(sector
+ 52, "ReIsEr3Fs", 9) == 0) {
502 *fsname
= STR("ReiserFS");