1*62718823Skrw /* $OpenBSD: part.c,v 1.131 2022/08/29 07:19:14 krw Exp $ */ 2a1705421Sweingart 3a1705421Sweingart /* 4a1705421Sweingart * Copyright (c) 1997 Tobias Weingartner 5a1705421Sweingart * 610a68084Skrw * Permission to use, copy, modify, and distribute this software for any 710a68084Skrw * purpose with or without fee is hereby granted, provided that the above 810a68084Skrw * copyright notice and this permission notice appear in all copies. 9a1705421Sweingart * 1010a68084Skrw * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1110a68084Skrw * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1210a68084Skrw * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1310a68084Skrw * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1410a68084Skrw * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1510a68084Skrw * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1610a68084Skrw * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17a1705421Sweingart */ 18a1705421Sweingart 19a7568474Sderaadt #include <sys/types.h> 20a7568474Sderaadt #include <sys/disklabel.h> 21729290c0Skrw 22e8252b55Skrw #include <err.h> 2398952941Skrw #include <stdint.h> 24a1705421Sweingart #include <stdio.h> 25fba7235cSkrw #include <stdlib.h> 26184a329bSmillert #include <string.h> 27fba7235cSkrw #include <uuid.h> 28abc6f793Skrw 29199eafeaSkrw #include "part.h" 30a5472107Skrw #include "disk.h" 31a1705421Sweingart #include "misc.h" 3265deb39bSkrw #include "gpt.h" 33a1705421Sweingart 345308a554Skrw struct mbr_type { 355308a554Skrw int mt_type; 365308a554Skrw char mt_sname[14]; 375308a554Skrw }; 385308a554Skrw 395308a554Skrw const struct mbr_type mbr_types[] = { 405308a554Skrw { 0x00, "unused" }, /* unused */ 415308a554Skrw { 0x01, "DOS FAT-12" }, /* Primary DOS with 12 bit FAT */ 42764d6d49Stom { 0x02, "XENIX /" }, /* XENIX / filesystem */ 43764d6d49Stom { 0x03, "XENIX /usr" }, /* XENIX /usr filesystem */ 445308a554Skrw { 0x04, "DOS FAT-16" }, /* Primary DOS with 16 bit FAT */ 45764d6d49Stom { 0x05, "Extended DOS" }, /* Extended DOS */ 465308a554Skrw { 0x06, "DOS > 32MB" }, /* Primary 'big' DOS (> 32MB) */ 475308a554Skrw { 0x07, "NTFS" }, /* NTFS */ 48764d6d49Stom { 0x08, "AIX fs" }, /* AIX filesystem */ 49764d6d49Stom { 0x09, "AIX/Coherent" }, /* AIX boot partition or Coherent */ 50764d6d49Stom { 0x0A, "OS/2 Bootmgr" }, /* OS/2 Boot Manager or OPUS */ 515308a554Skrw { 0x0B, "Win95 FAT-32" }, /* Primary Win95 w/ 32-bit FAT */ 525308a554Skrw { 0x0C, "Win95 FAT32L" }, /* Primary Win95 w/ 32-bit FAT LBA-mapped */ 535308a554Skrw { 0x0E, "DOS FAT-16" }, /* Primary DOS w/ 16-bit FAT, CHS-mapped */ 54764d6d49Stom { 0x0F, "Extended LBA" }, /* Extended DOS LBA-mapped */ 55764d6d49Stom { 0x10, "OPUS" }, /* OPUS */ 565308a554Skrw { 0x11, "OS/2 hidden" }, /* OS/2 BM: hidden DOS 12-bit FAT */ 5772c8f31dSkrw { 0x12, "Compaq Diag" }, /* Compaq Diagnostics */ 585308a554Skrw { 0x14, "OS/2 hidden" }, /* OS/2 BM: hidden DOS 16-bit FAT <32M or Novell DOS 7.0 bug */ 595308a554Skrw { 0x16, "OS/2 hidden" }, /* OS/2 BM: hidden DOS 16-bit FAT >=32M */ 605308a554Skrw { 0x17, "OS/2 hidden" }, /* OS/2 BM: hidden IFS */ 61764d6d49Stom { 0x18, "AST swap" }, /* AST Windows swapfile */ 62764d6d49Stom { 0x19, "Willowtech" }, /* Willowtech Photon coS */ 635308a554Skrw { 0x1C, "ThinkPad Rec" }, /* IBM ThinkPad recovery partition */ 64fba7235cSkrw { 0x20, "Willowsoft" }, /* Willowsoft OFS1 */ 655308a554Skrw { 0x24, "NEC DOS" }, /* NEC DOS */ 665308a554Skrw { 0x27, "Win Recovery" }, /* Windows hidden Recovery Partition */ 67764d6d49Stom { 0x38, "Theos" }, /* Theos */ 68764d6d49Stom { 0x39, "Plan 9" }, /* Plan 9 */ 69764d6d49Stom { 0x40, "VENIX 286" }, /* VENIX 286 or LynxOS */ 70764d6d49Stom { 0x41, "Lin/Minux DR" }, /* Linux/MINIX (sharing disk with DRDOS) or Personal RISC boot */ 715308a554Skrw { 0x42, "LinuxSwap DR" }, /* SFS or Linux swap (sharing disk with DRDOS) */ 72764d6d49Stom { 0x43, "Linux DR" }, /* Linux native (sharing disk with DRDOS) */ 73764d6d49Stom { 0x4D, "QNX 4.2 Pri" }, /* QNX 4.2 Primary */ 74764d6d49Stom { 0x4E, "QNX 4.2 Sec" }, /* QNX 4.2 Secondary */ 75764d6d49Stom { 0x4F, "QNX 4.2 Ter" }, /* QNX 4.2 Tertiary */ 76764d6d49Stom { 0x50, "DM" }, /* DM (disk manager) */ 77764d6d49Stom { 0x51, "DM" }, /* DM6 Aux1 (or Novell) */ 78764d6d49Stom { 0x52, "CP/M or SysV" }, /* CP/M or Microport SysV/AT */ 79764d6d49Stom { 0x53, "DM" }, /* DM6 Aux3 */ 80764d6d49Stom { 0x54, "Ontrack" }, /* Ontrack */ 81764d6d49Stom { 0x55, "EZ-Drive" }, /* EZ-Drive (disk manager) */ 82764d6d49Stom { 0x56, "Golden Bow" }, /* Golden Bow (disk manager) */ 83764d6d49Stom { 0x5C, "Priam" }, /* Priam Edisk (disk manager) */ 84764d6d49Stom { 0x61, "SpeedStor" }, /* SpeedStor */ 85764d6d49Stom { 0x63, "ISC, HURD, *" }, /* ISC, System V/386, GNU HURD or Mach */ 86764d6d49Stom { 0x64, "NetWare 2.xx" }, /* Novell NetWare 2.xx */ 87764d6d49Stom { 0x65, "NetWare 3.xx" }, /* Novell NetWare 3.xx */ 88764d6d49Stom { 0x66, "NetWare 386" }, /* Novell 386 NetWare */ 89764d6d49Stom { 0x67, "Novell" }, /* Novell */ 90764d6d49Stom { 0x68, "Novell" }, /* Novell */ 91764d6d49Stom { 0x69, "Novell" }, /* Novell */ 92764d6d49Stom { 0x70, "DiskSecure" }, /* DiskSecure Multi-Boot */ 93764d6d49Stom { 0x75, "PCIX" }, /* PCIX */ 94764d6d49Stom { 0x80, "Minix (old)" }, /* Minix 1.1 ... 1.4a */ 95764d6d49Stom { 0x81, "Minix (new)" }, /* Minix 1.4b ... 1.5.10 */ 965308a554Skrw { 0x82, "Linux swap" }, /* Linux swap */ 975308a554Skrw { 0x83, "Linux files*" }, /* Linux filesystem */ 98764d6d49Stom { 0x84, "OS/2 hidden" }, /* OS/2 hidden C: drive */ 99764d6d49Stom { 0x85, "Linux ext." }, /* Linux extended */ 100764d6d49Stom { 0x86, "NT FAT VS" }, /* NT FAT volume set */ 101764d6d49Stom { 0x87, "NTFS VS" }, /* NTFS volume set or HPFS mirrored */ 1025308a554Skrw { 0x8E, "Linux LVM" }, /* Linux LVM */ 103764d6d49Stom { 0x93, "Amoeba FS" }, /* Amoeba filesystem */ 104764d6d49Stom { 0x94, "Amoeba BBT" }, /* Amoeba bad block table */ 105764d6d49Stom { 0x99, "Mylex" }, /* Mylex EISA SCSI */ 106764d6d49Stom { 0x9F, "BSDI" }, /* BSDI BSD/OS */ 107764d6d49Stom { 0xA0, "NotebookSave" }, /* Phoenix NoteBIOS save-to-disk */ 1085308a554Skrw { 0xA5, "FreeBSD" }, /* FreeBSD */ 1095308a554Skrw { 0xA6, "OpenBSD" }, /* OpenBSD */ 110764d6d49Stom { 0xA7, "NEXTSTEP" }, /* NEXTSTEP */ 1115308a554Skrw { 0xA8, "MacOS X" }, /* MacOS X main partition */ 1125308a554Skrw { 0xA9, "NetBSD" }, /* NetBSD */ 1135308a554Skrw { 0xAB, "MacOS X boot" }, /* MacOS X boot partition */ 1145308a554Skrw { 0xAF, "MacOS X HFS+" }, /* MacOS X HFS+ partition */ 115764d6d49Stom { 0xB7, "BSDI filesy*" }, /* BSDI BSD/386 filesystem */ 116764d6d49Stom { 0xB8, "BSDI swap" }, /* BSDI BSD/386 swap */ 1175308a554Skrw { 0xBF, "Solaris" }, /* Solaris */ 118764d6d49Stom { 0xC0, "CTOS" }, /* CTOS */ 119764d6d49Stom { 0xC1, "DRDOSs FAT12" }, /* DRDOS/sec (FAT-12) */ 120764d6d49Stom { 0xC4, "DRDOSs < 32M" }, /* DRDOS/sec (FAT-16, < 32M) */ 121764d6d49Stom { 0xC6, "DRDOSs >=32M" }, /* DRDOS/sec (FAT-16, >= 32M) */ 122764d6d49Stom { 0xC7, "HPFS Disbled" }, /* Syrinx (Cyrnix?) or HPFS disabled */ 123764d6d49Stom { 0xDB, "CPM/C.DOS/C*" }, /* Concurrent CPM or C.DOS or CTOS */ 124764d6d49Stom { 0xDE, "Dell Maint" }, /* Dell maintenance partition */ 125764d6d49Stom { 0xE1, "SpeedStor" }, /* DOS access or SpeedStor 12-bit FAT extended partition */ 126764d6d49Stom { 0xE3, "SpeedStor" }, /* DOS R/O or SpeedStor or Storage Dimensions */ 127764d6d49Stom { 0xE4, "SpeedStor" }, /* SpeedStor 16-bit FAT extended partition < 1024 cyl. */ 1285308a554Skrw { 0xEB, "BeOS/i386" }, /* BeOS for Intel */ 1292d874a94Sderaadt { 0xEE, "EFI GPT" }, /* EFI Protective Partition */ 1305308a554Skrw { 0xEF, "EFI Sys" }, /* EFI System Partition */ 131764d6d49Stom { 0xF1, "SpeedStor" }, /* SpeedStor or Storage Dimensions */ 132764d6d49Stom { 0xF2, "DOS 3.3+ Sec" }, /* DOS 3.3+ Secondary */ 133764d6d49Stom { 0xF4, "SpeedStor" }, /* SpeedStor >1024 cyl. or LANstep or IBM PS/2 IML */ 134764d6d49Stom { 0xFF, "Xenix BBT" }, /* Xenix Bad Block Table */ 135a1705421Sweingart }; 136a1705421Sweingart 1375308a554Skrw struct gpt_type { 1385308a554Skrw int gt_type; 139f458660aSkrw int gt_attr; 140f458660aSkrw #define GTATTR_PROTECT (1 << 0) 141f458660aSkrw #define GTATTR_PROTECT_EFISYS (1 << 1) 1425308a554Skrw char gt_sname[14]; 1435308a554Skrw char gt_guid[UUID_STR_LEN + 1]; 1445308a554Skrw }; 1455308a554Skrw 1465308a554Skrw const struct gpt_type gpt_types[] = { 147c96c378cSkrw { 0x00, 0, "unused", 148c96c378cSkrw "00000000-0000-0000-0000-000000000000" }, 149c96c378cSkrw { 0x01, 0, "FAT12", 150c96c378cSkrw "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" }, 151c96c378cSkrw { 0x04, 0, "FAT16S", 152c96c378cSkrw "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" }, 153c96c378cSkrw { 0x06, 0, "FAT16B", 154c96c378cSkrw "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" }, 155c96c378cSkrw { 0x07, 0, "NTFS", 156c96c378cSkrw "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" }, 157c96c378cSkrw { 0x0B, 0, "FAT32", 158c96c378cSkrw "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" }, 159c96c378cSkrw { 0x0C, 0, "FAT32L", 160c96c378cSkrw "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" }, 161f458660aSkrw { 0x0D, GTATTR_PROTECT, "BIOS Boot", 162c96c378cSkrw "21686148-6449-6e6f-744e-656564454649" }, 163c96c378cSkrw { 0x0E, 0, "FAT16L", 164c96c378cSkrw "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" }, 165c96c378cSkrw { 0x11, 0, "OS/2 hidden", 166c96c378cSkrw "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" }, 167c96c378cSkrw { 0x14, 0, "OS/2 hidden", 168c96c378cSkrw "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" }, 169c96c378cSkrw { 0x16, 0, "OS/2 hidden", 170c96c378cSkrw "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" }, 171c96c378cSkrw { 0x17, 0, "OS/2 hidden", 172c96c378cSkrw "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" }, 173c96c378cSkrw { 0x1C, 0, "ThinkPad Rec", 174c96c378cSkrw "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" }, 175c96c378cSkrw { 0x27, 0, "Win Recovery", 176c96c378cSkrw "de94bba4-06d1-4d40-a16a-bfd50179d6ac" }, 177c96c378cSkrw { 0x42, 0, "LinuxSwap DR", 178c96c378cSkrw "af9b60a0-1431-4f62-bc68-3311714a69ad" }, 179c96c378cSkrw { 0x7f, 0, "ChromeKernel", 180c96c378cSkrw "fe3a2a5d-4f32-41a7-b725-accc3285a309" }, 181c96c378cSkrw { 0x82, 0, "Linux swap", 182c96c378cSkrw "0657fd6d-a4ab-43c4-84e5-0933c84b4f4f" }, 183c96c378cSkrw { 0x83, 0, "Linux files*", 184c96c378cSkrw "0fc63daf-8483-4772-8e79-3d69d8477de4" }, 185c96c378cSkrw { 0x8E, 0, "Linux LVM", 186c96c378cSkrw "e6d6d379-f507-44c2-a23c-238f2a3df928" }, 187c96c378cSkrw { 0xA5, 0, "FreeBSD", 188c96c378cSkrw "516e7cb4-6ecf-11d6-8ff8-00022d09712b" }, 189c96c378cSkrw { 0xA6, 0, "OpenBSD", 190c96c378cSkrw "824cc7a0-36a8-11e3-890a-952519ad3f61" }, 191c96c378cSkrw { 0xA8, 0, "MacOS X", 192c96c378cSkrw "55465300-0000-11aa-aa11-00306543ecac" }, 193c96c378cSkrw { 0xA9, 0, "NetBSD", 194c96c378cSkrw "516e7cb4-6ecf-11d6-8ff8-00022d09712b" }, 195c96c378cSkrw { 0xAB, 0, "MacOS X boot", 196c96c378cSkrw "426f6f74-0000-11aa-aa11-00306543ecac" }, 197c96c378cSkrw { 0xAF, 0, "MacOS X HFS+", 198c96c378cSkrw "48465300-0000-11aa-aa11-00306543ecac" }, 199f458660aSkrw { 0xB0, GTATTR_PROTECT | GTATTR_PROTECT_EFISYS, "APFS", 200c96c378cSkrw "7c3457ef-0000-11aa-aa11-00306543ecac" }, 201f458660aSkrw { 0xB1, GTATTR_PROTECT | GTATTR_PROTECT_EFISYS, "APFS ISC", 202c96c378cSkrw "69646961-6700-11aa-aa11-00306543ecac" }, 203f458660aSkrw { 0xB2, GTATTR_PROTECT | GTATTR_PROTECT_EFISYS, "APFS Recovery", 204c96c378cSkrw "52637672-7900-11aa-aa11-00306543ecac" }, 205f458660aSkrw { 0xB3, GTATTR_PROTECT, "HiFive FSBL", 206c96c378cSkrw "5b193300-fc78-40cd-8002-e86c45580b47" }, 207f458660aSkrw { 0xB4, GTATTR_PROTECT, "HiFive BBL", 208c96c378cSkrw "2e54b353-1271-4842-806f-e436d6af6985" }, 209c96c378cSkrw { 0xBF, 0, "Solaris", 210c96c378cSkrw "6a85cf4d-1dd2-11b2-99a6-080020736631" }, 211c96c378cSkrw { 0xEB, 0, "BeOS/i386", 212c96c378cSkrw "42465331-3ba3-10f1-802a-4861696b7521" }, 213c96c378cSkrw { 0xEF, 0, "EFI Sys", 214c96c378cSkrw "c12a7328-f81f-11d2-ba4b-00a0c93ec93b" }, 21595e8765cSkrw }; 21695e8765cSkrw 217f2ec1a13Skrw const struct gpt_type *find_gpt_type(const struct uuid *); 218c96c378cSkrw const char *ascii_id(const int); 219f458660aSkrw int uuid_attr(const struct uuid *); 220c96c378cSkrw 221c96c378cSkrw const struct gpt_type * 222c96c378cSkrw find_gpt_type(const struct uuid *uuid) 223c96c378cSkrw { 224c96c378cSkrw char *uuidstr = NULL; 225c96c378cSkrw unsigned int i; 226c96c378cSkrw uint32_t status; 227c96c378cSkrw 228c96c378cSkrw uuid_to_string(uuid, &uuidstr, &status); 229c96c378cSkrw if (status == uuid_s_ok) { 230c96c378cSkrw for (i = 0; i < nitems(gpt_types); i++) { 231c96c378cSkrw if (memcmp(gpt_types[i].gt_guid, uuidstr, 232c96c378cSkrw sizeof(gpt_types[i].gt_guid)) == 0) 233c96c378cSkrw break; 234c96c378cSkrw } 235c96c378cSkrw } else 236c96c378cSkrw i = nitems(gpt_types); 237c96c378cSkrw free(uuidstr); 238c96c378cSkrw 239c96c378cSkrw if (i < nitems(gpt_types)) 240c96c378cSkrw return &gpt_types[i]; 241c96c378cSkrw else 242c96c378cSkrw return NULL; 243c96c378cSkrw } 244c96c378cSkrw 245c96c378cSkrw const char * 246c96c378cSkrw ascii_id(const int id) 247c96c378cSkrw { 248c96c378cSkrw static char unknown[] = "<Unknown ID>"; 249c96c378cSkrw int i; 250c96c378cSkrw 251c96c378cSkrw for (i = 0; i < nitems(mbr_types); i++) { 252c96c378cSkrw if (mbr_types[i].mt_type == id) 253c96c378cSkrw return mbr_types[i].mt_sname; 254c96c378cSkrw } 255c96c378cSkrw 256c96c378cSkrw return unknown; 257c96c378cSkrw } 258c96c378cSkrw 259f458660aSkrw int 260f458660aSkrw uuid_attr(const struct uuid *uuid) 261f458660aSkrw { 262f458660aSkrw const struct gpt_type *gt; 263f458660aSkrw 264f458660aSkrw gt = find_gpt_type(uuid); 265f458660aSkrw if (gt == NULL) 266f458660aSkrw return 0; 267f458660aSkrw else 268f458660aSkrw return gt->gt_attr; 269f458660aSkrw } 270f2ec1a13Skrw 27195e8765cSkrw int 2722ea83235Skrw PRT_protected_guid(const struct uuid *uuid) 27395e8765cSkrw { 274f458660aSkrw const struct gpt_type *gt; 2758e294713Skrw unsigned int pn; 2768e294713Skrw 277f458660aSkrw gt = find_gpt_type(uuid); 278f458660aSkrw if (gt && gt->gt_attr & GTATTR_PROTECT) 279f458660aSkrw return 1; 28095e8765cSkrw 281f458660aSkrw if (gt && gt->gt_type == DOSPTYP_EFISYS) { 2822de77560Skrw for (pn = 0; pn < gh.gh_part_num; pn++) { 283f458660aSkrw if (uuid_attr(&gp[pn].gp_type) & GTATTR_PROTECT_EFISYS) 284f458660aSkrw return 1; 28595e8765cSkrw } 28665deb39bSkrw } 28795e8765cSkrw 2888e294713Skrw return 0; 28995e8765cSkrw } 29095e8765cSkrw 2914b464610Sderaadt void 2925308a554Skrw PRT_print_mbrtypes(void) 2934b464610Sderaadt { 29472c8f31dSkrw unsigned int cidx, i, idrows; 295d20bdfc6Skrw 2965308a554Skrw idrows = (nitems(mbr_types) + 3) / 4; 2974b464610Sderaadt 298c2ad5584Sderaadt printf("Choose from the following Partition id values:\n"); 299d20bdfc6Skrw for (i = 0; i < idrows; i++) { 30072c8f31dSkrw for (cidx = i; cidx < i + idrows * 3; cidx += idrows) { 30172c8f31dSkrw printf("%02X %-*s", mbr_types[cidx].mt_type, 30272c8f31dSkrw (int)sizeof(mbr_types[cidx].mt_sname) + 1, 30372c8f31dSkrw mbr_types[cidx].mt_sname); 30472c8f31dSkrw } 30572c8f31dSkrw if (cidx < nitems(mbr_types)) 30672c8f31dSkrw printf("%02X %s", mbr_types[cidx].mt_type, 30772c8f31dSkrw mbr_types[cidx].mt_sname); 3085308a554Skrw printf("\n"); 3095308a554Skrw } 3105308a554Skrw } 3115308a554Skrw 3125308a554Skrw void 3135308a554Skrw PRT_print_gpttypes(void) 3145308a554Skrw { 31572c8f31dSkrw unsigned int cidx, i, idrows; 3165308a554Skrw 3175308a554Skrw idrows = (nitems(gpt_types) + 3) / 4; 3185308a554Skrw 3195308a554Skrw printf("Choose from the following Partition id values:\n"); 3205308a554Skrw for (i = 0; i < idrows; i++) { 32172c8f31dSkrw for (cidx = i; cidx < i + idrows * 3; cidx += idrows) { 32272c8f31dSkrw printf("%02X %-*s", gpt_types[cidx].gt_type, 32372c8f31dSkrw (int)sizeof(gpt_types[cidx].gt_sname) + 1, 32472c8f31dSkrw gpt_types[cidx].gt_sname); 32572c8f31dSkrw } 32672c8f31dSkrw if (cidx < nitems(gpt_types)) 32772c8f31dSkrw printf("%02X %s", gpt_types[cidx].gt_type, 32872c8f31dSkrw gpt_types[cidx].gt_sname); 3294b464610Sderaadt printf("\n"); 3304b464610Sderaadt } 331d20bdfc6Skrw } 332a1705421Sweingart 333a1705421Sweingart void 3340cd9e2afSkrw PRT_parse(const struct dos_partition *dp, const uint64_t lba_self, 3350cd9e2afSkrw const uint64_t lba_firstembr, struct prt *prt) 336a1705421Sweingart { 337ca2e86e1Sprovos off_t off; 338b87d3542Skrw uint32_t t; 339a1705421Sweingart 340ee38fe33Skrw prt->prt_flag = dp->dp_flag; 341ee38fe33Skrw prt->prt_id = dp->dp_typ; 342a1705421Sweingart 343ee38fe33Skrw if ((prt->prt_id == DOSPTYP_EXTEND) || (prt->prt_id == DOSPTYP_EXTENDL)) 344061e6e0aSkrw off = lba_firstembr; 345c3e3230dSderaadt else 346061e6e0aSkrw off = lba_self; 347ca2e86e1Sprovos 348ee38fe33Skrw memcpy(&t, &dp->dp_start, sizeof(uint32_t)); 349ee38fe33Skrw prt->prt_bs = letoh32(t) + off; 350ee38fe33Skrw memcpy(&t, &dp->dp_size, sizeof(uint32_t)); 351ee38fe33Skrw prt->prt_ns = letoh32(t); 352ee38fe33Skrw if (prt->prt_id == DOSPTYP_EFI && prt->prt_ns == UINT32_MAX) 353ee38fe33Skrw prt->prt_ns = DL_GETDSIZE(&dl) - prt->prt_bs; 3544ed7cd7eSrahnds } 35549241bdaSkrw 356a1705421Sweingart void 35799e0469cSkrw PRT_make(const struct prt *prt, const uint64_t lba_self, 35899e0469cSkrw const uint64_t lba_firstembr, struct dos_partition *dp) 359a1705421Sweingart { 36077392607Skrw struct chs start, end; 3610cd9e2afSkrw uint64_t off, t; 362c3e3230dSderaadt 3636aca8866Skrw if (prt->prt_ns == 0 || prt->prt_id == DOSPTYP_UNUSED) { 3646aca8866Skrw memset(dp, 0, sizeof(*dp)); 3656aca8866Skrw return; 3666aca8866Skrw } 3676aca8866Skrw 368ee38fe33Skrw if ((prt->prt_id == DOSPTYP_EXTEND) || (prt->prt_id == DOSPTYP_EXTENDL)) 369ee38fe33Skrw off = lba_firstembr; 370c3e3230dSderaadt else 371ee38fe33Skrw off = lba_self; 372a1705421Sweingart 37377392607Skrw if (PRT_lba_to_chs(prt, &start, &end) == 0) { 37477392607Skrw dp->dp_shd = start.chs_head & 0xFF; 37577392607Skrw dp->dp_ssect = (start.chs_sect & 0x3F) | ((start.chs_cyl & 0x300) >> 2); 37677392607Skrw dp->dp_scyl = start.chs_cyl & 0xFF; 37777392607Skrw dp->dp_ehd = end.chs_head & 0xFF; 37877392607Skrw dp->dp_esect = (end.chs_sect & 0x3F) | ((end.chs_cyl & 0x300) >> 2); 37977392607Skrw dp->dp_ecyl = end.chs_cyl & 0xFF; 3804ed7cd7eSrahnds } else { 381ee38fe33Skrw memset(dp, 0xFF, sizeof(*dp)); 3824ed7cd7eSrahnds } 383a1705421Sweingart 384ee38fe33Skrw dp->dp_flag = prt->prt_flag & 0xFF; 385ee38fe33Skrw dp->dp_typ = prt->prt_id & 0xFF; 38640b0f5f3Skrw 387ee38fe33Skrw t = htole64(prt->prt_bs - off); 388ee38fe33Skrw memcpy(&dp->dp_start, &t, sizeof(uint32_t)); 389ee38fe33Skrw if (prt->prt_id == DOSPTYP_EFI && (prt->prt_bs + prt->prt_ns) > 39098952941Skrw DL_GETDSIZE(&dl)) 39198952941Skrw t = htole64(UINT32_MAX); 39298952941Skrw else 393ee38fe33Skrw t = htole64(prt->prt_ns); 394ee38fe33Skrw memcpy(&dp->dp_size, &t, sizeof(uint32_t)); 3956d5e103bSkjell } 396a1705421Sweingart 397a1705421Sweingart void 3987b70791fSkrw PRT_print_parthdr(void) 399a1705421Sweingart { 400ba49db25Skrw printf(" Starting Ending " 401ba49db25Skrw " LBA Info:\n"); 402ba49db25Skrw printf(" #: id C H S - C H S " 403ba49db25Skrw "[ start: size ]\n"); 404ba49db25Skrw printf("---------------------------------------" 405ba49db25Skrw "----------------------------------------\n"); 4067b70791fSkrw } 4077b70791fSkrw 4087b70791fSkrw void 4097b70791fSkrw PRT_print_part(const int num, const struct prt *prt, const char *units) 4107b70791fSkrw { 4117b70791fSkrw const struct unit_type *ut; 41277392607Skrw struct chs start, end; 4137b70791fSkrw double size; 4147b70791fSkrw 4153e9b7d6bSkrw size = units_size(units, prt->prt_ns, &ut); 41677392607Skrw PRT_lba_to_chs(prt, &start, &end); 41777392607Skrw 41877392607Skrw printf("%c%1d: %.2X %6llu %3u %3u - %6llu %3u %3u " 419ba49db25Skrw "[%12llu:%12.0f%s] %s\n", 420ee38fe33Skrw (prt->prt_flag == DOSACTIVE)?'*':' ', 421ee38fe33Skrw num, prt->prt_id, 42277392607Skrw start.chs_cyl, start.chs_head, start.chs_sect, 42377392607Skrw end.chs_cyl, end.chs_head, end.chs_sect, 4243e9b7d6bSkrw prt->prt_bs, size, ut->ut_abbr, ascii_id(prt->prt_id)); 425*62718823Skrw 426*62718823Skrw if (prt->prt_bs >= DL_GETDSIZE(&dl)) 427*62718823Skrw printf("partition %d starts beyond the end of %s\n", num, 428*62718823Skrw disk.dk_name); 429*62718823Skrw else if (prt->prt_bs + prt->prt_ns > DL_GETDSIZE(&dl)) 430*62718823Skrw printf("partition %d extends beyond the end of %s\n", num, 431*62718823Skrw disk.dk_name); 432a1705421Sweingart } 433a1705421Sweingart 43477392607Skrw int 43577392607Skrw PRT_lba_to_chs(const struct prt *prt, struct chs *start, struct chs *end) 436a1705421Sweingart { 43777392607Skrw uint64_t lba; 438a1705421Sweingart 43977392607Skrw if (prt->prt_ns == 0 || prt->prt_id == DOSPTYP_UNUSED) { 44077392607Skrw memset(start, 0, sizeof(*start)); 44177392607Skrw memset(end, 0, sizeof(*end)); 44277392607Skrw return -1; 443eb4cb19dSkjell } 444eb4cb19dSkjell 44577392607Skrw /* 44677392607Skrw * C = LBA ÷ (HPC × SPT) 44777392607Skrw * H = (LBA ÷ SPT) mod HPC 44877392607Skrw * S = (LBA mod SPT) + 1 44977392607Skrw */ 450a1705421Sweingart 45177392607Skrw lba = prt->prt_bs; 45277392607Skrw start->chs_cyl = lba / (disk.dk_sectors * disk.dk_heads); 45377392607Skrw start->chs_head = (lba / disk.dk_sectors) % disk.dk_heads; 45477392607Skrw start->chs_sect = (lba % disk.dk_sectors) + 1; 455a1705421Sweingart 45677392607Skrw lba = prt->prt_bs + prt->prt_ns - 1; 45777392607Skrw end->chs_cyl = lba / (disk.dk_sectors * disk.dk_heads); 45877392607Skrw end->chs_head = (lba / disk.dk_sectors) % disk.dk_heads; 45977392607Skrw end->chs_sect = (lba % disk.dk_sectors) + 1; 460a1705421Sweingart 46177392607Skrw if (start->chs_head > 255 || end->chs_head > 255 || 46277392607Skrw start->chs_sect > 63 || end->chs_sect > 63 || 46377392607Skrw start->chs_cyl > 1023 || end->chs_cyl > 1023) 46477392607Skrw return -1; 465a1705421Sweingart 46677392607Skrw return 0; 467a1705421Sweingart } 468fba7235cSkrw 469f2ec1a13Skrw const char * 470e48f25a4Skrw PRT_uuid_to_sname(const struct uuid *uuid) 471f2ec1a13Skrw { 472f2ec1a13Skrw static char typename[UUID_STR_LEN + 1]; 4735c01edd6Skrw const uint8_t gpt_uuid_msdos[] = GPT_UUID_MSDOS; 4745c01edd6Skrw struct uuid uuid_msdos; 475f2ec1a13Skrw const struct gpt_type *gt; 476f2ec1a13Skrw char *uuidstr; 477351f0068Skrw uint32_t status; 478f2ec1a13Skrw 4795c01edd6Skrw uuid_dec_be(gpt_uuid_msdos, &uuid_msdos); 4805c01edd6Skrw if (uuid_compare(&uuid_msdos, uuid, NULL) == 0) 4815c01edd6Skrw return "Microsoft basic data"; 482f2ec1a13Skrw 483f2ec1a13Skrw gt = find_gpt_type(uuid); 4845c01edd6Skrw if (gt != NULL) 4855c01edd6Skrw return gt->gt_sname; 4865c01edd6Skrw 487f2ec1a13Skrw uuid_to_string(uuid, &uuidstr, &status); 488f2ec1a13Skrw if (status == uuid_s_ok) 489f2ec1a13Skrw strlcpy(typename, uuidstr, sizeof(typename)); 4905c01edd6Skrw else 4915c01edd6Skrw typename[0] = '\0'; 492f2ec1a13Skrw free(uuidstr); 493f2ec1a13Skrw 494f2ec1a13Skrw return typename; 495fba7235cSkrw } 496fba7235cSkrw 497145e5a87Stim int 498859be6c9Skrw PRT_uuid_to_type(const struct uuid *uuid) 499145e5a87Stim { 500f2ec1a13Skrw const struct gpt_type *gt; 501145e5a87Stim 502f2ec1a13Skrw gt = find_gpt_type(uuid); 503f2ec1a13Skrw if (gt == NULL) 504f2ec1a13Skrw return 0; 505f2ec1a13Skrw else 506f2ec1a13Skrw return gt->gt_type; 507145e5a87Stim } 508145e5a87Stim 509e48f25a4Skrw const struct uuid * 510e48f25a4Skrw PRT_type_to_guid(const int type) 511fba7235cSkrw { 512fba7235cSkrw static struct uuid guid; 513351f0068Skrw int i, entries; 514351f0068Skrw uint32_t status = uuid_s_ok; 515fba7235cSkrw 516fba7235cSkrw memset(&guid, 0, sizeof(guid)); 517fba7235cSkrw 5185308a554Skrw entries = nitems(gpt_types); 519fba7235cSkrw 520fba7235cSkrw for (i = 0; i < entries; i++) { 5215308a554Skrw if (gpt_types[i].gt_type == type) 522fba7235cSkrw break; 523fba7235cSkrw } 524fba7235cSkrw if (i < entries) 5255308a554Skrw uuid_from_string(gpt_types[i].gt_guid, &guid, &status); 526fba7235cSkrw if (i == entries || status != uuid_s_ok) 5275308a554Skrw uuid_from_string(gpt_types[0].gt_guid, &guid, &status); 528fba7235cSkrw 5292a536aa2Skrw return &guid; 530fba7235cSkrw } 531