1 /* $OpenBSD: part.c,v 1.110 2021/10/18 20:27:32 krw Exp $ */ 2 3 /* 4 * Copyright (c) 1997 Tobias Weingartner 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/types.h> 20 #include <sys/disklabel.h> 21 22 #include <err.h> 23 #include <stdint.h> 24 #include <stdio.h> 25 #include <stdlib.h> 26 #include <string.h> 27 #include <uuid.h> 28 29 #include "part.h" 30 #include "disk.h" 31 #include "misc.h" 32 33 int check_chs(const struct prt *); 34 const char *ascii_id(const int); 35 36 struct mbr_type { 37 int mt_type; 38 char mt_sname[14]; 39 }; 40 41 const struct mbr_type mbr_types[] = { 42 { 0x00, "unused " }, /* unused */ 43 { 0x01, "DOS FAT-12 " }, /* Primary DOS with 12 bit FAT */ 44 { 0x02, "XENIX / " }, /* XENIX / filesystem */ 45 { 0x03, "XENIX /usr " }, /* XENIX /usr filesystem */ 46 { 0x04, "DOS FAT-16 " }, /* Primary DOS with 16 bit FAT */ 47 { 0x05, "Extended DOS" }, /* Extended DOS */ 48 { 0x06, "DOS > 32MB " }, /* Primary 'big' DOS (> 32MB) */ 49 { 0x07, "NTFS " }, /* NTFS */ 50 { 0x08, "AIX fs " }, /* AIX filesystem */ 51 { 0x09, "AIX/Coherent" }, /* AIX boot partition or Coherent */ 52 { 0x0A, "OS/2 Bootmgr" }, /* OS/2 Boot Manager or OPUS */ 53 { 0x0B, "Win95 FAT-32" }, /* Primary Win95 w/ 32-bit FAT */ 54 { 0x0C, "Win95 FAT32L" }, /* Primary Win95 w/ 32-bit FAT LBA-mapped */ 55 { 0x0E, "DOS FAT-16 " }, /* Primary DOS w/ 16-bit FAT, CHS-mapped */ 56 { 0x0F, "Extended LBA" }, /* Extended DOS LBA-mapped */ 57 { 0x10, "OPUS " }, /* OPUS */ 58 { 0x11, "OS/2 hidden " }, /* OS/2 BM: hidden DOS 12-bit FAT */ 59 { 0x12, "Compaq Diag." }, /* Compaq Diagnostics */ 60 { 0x14, "OS/2 hidden " }, /* OS/2 BM: hidden DOS 16-bit FAT <32M or Novell DOS 7.0 bug */ 61 { 0x16, "OS/2 hidden " }, /* OS/2 BM: hidden DOS 16-bit FAT >=32M */ 62 { 0x17, "OS/2 hidden " }, /* OS/2 BM: hidden IFS */ 63 { 0x18, "AST swap " }, /* AST Windows swapfile */ 64 { 0x19, "Willowtech " }, /* Willowtech Photon coS */ 65 { 0x1C, "ThinkPad Rec" }, /* IBM ThinkPad recovery partition */ 66 { 0x20, "Willowsoft " }, /* Willowsoft OFS1 */ 67 { 0x24, "NEC DOS " }, /* NEC DOS */ 68 { 0x27, "Win Recovery" }, /* Windows hidden Recovery Partition */ 69 { 0x38, "Theos " }, /* Theos */ 70 { 0x39, "Plan 9 " }, /* Plan 9 */ 71 { 0x40, "VENIX 286 " }, /* VENIX 286 or LynxOS */ 72 { 0x41, "Lin/Minux DR" }, /* Linux/MINIX (sharing disk with DRDOS) or Personal RISC boot */ 73 { 0x42, "LinuxSwap DR" }, /* SFS or Linux swap (sharing disk with DRDOS) */ 74 { 0x43, "Linux DR " }, /* Linux native (sharing disk with DRDOS) */ 75 { 0x4D, "QNX 4.2 Pri " }, /* QNX 4.2 Primary */ 76 { 0x4E, "QNX 4.2 Sec " }, /* QNX 4.2 Secondary */ 77 { 0x4F, "QNX 4.2 Ter " }, /* QNX 4.2 Tertiary */ 78 { 0x50, "DM " }, /* DM (disk manager) */ 79 { 0x51, "DM " }, /* DM6 Aux1 (or Novell) */ 80 { 0x52, "CP/M or SysV" }, /* CP/M or Microport SysV/AT */ 81 { 0x53, "DM " }, /* DM6 Aux3 */ 82 { 0x54, "Ontrack " }, /* Ontrack */ 83 { 0x55, "EZ-Drive " }, /* EZ-Drive (disk manager) */ 84 { 0x56, "Golden Bow " }, /* Golden Bow (disk manager) */ 85 { 0x5C, "Priam " }, /* Priam Edisk (disk manager) */ 86 { 0x61, "SpeedStor " }, /* SpeedStor */ 87 { 0x63, "ISC, HURD, *" }, /* ISC, System V/386, GNU HURD or Mach */ 88 { 0x64, "NetWare 2.xx" }, /* Novell NetWare 2.xx */ 89 { 0x65, "NetWare 3.xx" }, /* Novell NetWare 3.xx */ 90 { 0x66, "NetWare 386 " }, /* Novell 386 NetWare */ 91 { 0x67, "Novell " }, /* Novell */ 92 { 0x68, "Novell " }, /* Novell */ 93 { 0x69, "Novell " }, /* Novell */ 94 { 0x70, "DiskSecure " }, /* DiskSecure Multi-Boot */ 95 { 0x75, "PCIX " }, /* PCIX */ 96 { 0x80, "Minix (old) " }, /* Minix 1.1 ... 1.4a */ 97 { 0x81, "Minix (new) " }, /* Minix 1.4b ... 1.5.10 */ 98 { 0x82, "Linux swap " }, /* Linux swap */ 99 { 0x83, "Linux files*" }, /* Linux filesystem */ 100 { 0x84, "OS/2 hidden " }, /* OS/2 hidden C: drive */ 101 { 0x85, "Linux ext. " }, /* Linux extended */ 102 { 0x86, "NT FAT VS " }, /* NT FAT volume set */ 103 { 0x87, "NTFS VS " }, /* NTFS volume set or HPFS mirrored */ 104 { 0x8E, "Linux LVM " }, /* Linux LVM */ 105 { 0x93, "Amoeba FS " }, /* Amoeba filesystem */ 106 { 0x94, "Amoeba BBT " }, /* Amoeba bad block table */ 107 { 0x99, "Mylex " }, /* Mylex EISA SCSI */ 108 { 0x9F, "BSDI " }, /* BSDI BSD/OS */ 109 { 0xA0, "NotebookSave" }, /* Phoenix NoteBIOS save-to-disk */ 110 { 0xA5, "FreeBSD " }, /* FreeBSD */ 111 { 0xA6, "OpenBSD " }, /* OpenBSD */ 112 { 0xA7, "NEXTSTEP " }, /* NEXTSTEP */ 113 { 0xA8, "MacOS X " }, /* MacOS X main partition */ 114 { 0xA9, "NetBSD " }, /* NetBSD */ 115 { 0xAB, "MacOS X boot" }, /* MacOS X boot partition */ 116 { 0xAF, "MacOS X HFS+" }, /* MacOS X HFS+ partition */ 117 { 0xB7, "BSDI filesy*" }, /* BSDI BSD/386 filesystem */ 118 { 0xB8, "BSDI swap " }, /* BSDI BSD/386 swap */ 119 { 0xBF, "Solaris " }, /* Solaris */ 120 { 0xC0, "CTOS " }, /* CTOS */ 121 { 0xC1, "DRDOSs FAT12" }, /* DRDOS/sec (FAT-12) */ 122 { 0xC4, "DRDOSs < 32M" }, /* DRDOS/sec (FAT-16, < 32M) */ 123 { 0xC6, "DRDOSs >=32M" }, /* DRDOS/sec (FAT-16, >= 32M) */ 124 { 0xC7, "HPFS Disbled" }, /* Syrinx (Cyrnix?) or HPFS disabled */ 125 { 0xDB, "CPM/C.DOS/C*" }, /* Concurrent CPM or C.DOS or CTOS */ 126 { 0xDE, "Dell Maint " }, /* Dell maintenance partition */ 127 { 0xE1, "SpeedStor " }, /* DOS access or SpeedStor 12-bit FAT extended partition */ 128 { 0xE3, "SpeedStor " }, /* DOS R/O or SpeedStor or Storage Dimensions */ 129 { 0xE4, "SpeedStor " }, /* SpeedStor 16-bit FAT extended partition < 1024 cyl. */ 130 { 0xEB, "BeOS/i386 " }, /* BeOS for Intel */ 131 { 0xEE, "EFI GPT " }, /* EFI Protective Partition */ 132 { 0xEF, "EFI Sys " }, /* EFI System Partition */ 133 { 0xF1, "SpeedStor " }, /* SpeedStor or Storage Dimensions */ 134 { 0xF2, "DOS 3.3+ Sec" }, /* DOS 3.3+ Secondary */ 135 { 0xF4, "SpeedStor " }, /* SpeedStor >1024 cyl. or LANstep or IBM PS/2 IML */ 136 { 0xFF, "Xenix BBT " }, /* Xenix Bad Block Table */ 137 }; 138 139 struct gpt_type { 140 int gt_type; 141 int gt_protected; 142 char gt_sname[14]; 143 char gt_guid[UUID_STR_LEN + 1]; 144 145 }; 146 147 const struct gpt_type gpt_types[] = { 148 { 0x00, 0, "unused ", "00000000-0000-0000-0000-000000000000" }, 149 { 0x01, 0, "FAT12 ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" }, 150 { 0x04, 0, "FAT16S ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" }, 151 { 0x06, 0, "FAT16B ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" }, 152 { 0x07, 0, "NTFS ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" }, 153 { 0x0B, 0, "FAT32 ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" }, 154 { 0x0C, 0, "FAT32L ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" }, 155 { 0x0D, 0, "BIOS Boot ", "21686148-6449-6e6f-744e-656564454649" }, 156 { 0x0E, 0, "FAT16L ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" }, 157 { 0x11, 0, "OS/2 hidden ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" }, 158 { 0x14, 0, "OS/2 hidden ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" }, 159 { 0x16, 0, "OS/2 hidden ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" }, 160 { 0x17, 0, "OS/2 hidden ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" }, 161 { 0x1C, 0, "ThinkPad Rec", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" }, 162 { 0x27, 0, "Win Recovery", "de94bba4-06d1-4d40-a16a-bfd50179d6ac" }, 163 { 0x42, 0, "LinuxSwap DR", "af9b60a0-1431-4f62-bc68-3311714a69ad" }, 164 { 0x7f, 0, "ChromeKernel", "fe3a2a5d-4f32-41a7-b725-accc3285a309" }, 165 { 0x82, 0, "Linux swap ", "0657fd6d-a4ab-43c4-84e5-0933c84b4f4f" }, 166 { 0x83, 0, "Linux files*", "0fc63daf-8483-4772-8e79-3d69d8477de4" }, 167 { 0x8E, 0, "Linux LVM ", "e6d6d379-f507-44c2-a23c-238f2a3df928" }, 168 { 0xA5, 0, "FreeBSD ", "516e7cb4-6ecf-11d6-8ff8-00022d09712b" }, 169 { 0xA6, 0, "OpenBSD ", "824cc7a0-36a8-11e3-890a-952519ad3f61" }, 170 { 0xA8, 0, "MacOS X ", "55465300-0000-11aa-aa11-00306543ecac" }, 171 { 0xA9, 0, "NetBSD ", "516e7cb4-6ecf-11d6-8ff8-00022d09712b" }, 172 { 0xAB, 0, "MacOS X boot", "426f6f74-0000-11aa-aa11-00306543ecac" }, 173 { 0xAF, 0, "MacOS X HFS+", "48465300-0000-11aa-aa11-00306543ecac" }, 174 { 0xB0, 1, "APFS ", "7c3457ef-0000-11aa-aa11-00306543ecac" }, 175 { 0xB1, 1, "APFS ISC ", "69646961-6700-11aa-aa11-00306543ecac" }, 176 { 0xB2, 1, "APFS Recovry", "52637672-7900-11aa-aa11-00306543ecac" }, 177 { 0xB3, 1, "HiFive FSBL ", "5b193300-fc78-40cd-8002-e86c45580b47" }, 178 { 0xB4, 1, "HiFive BBL ", "2e54b353-1271-4842-806f-e436d6af6985" }, 179 { 0xBF, 0, "Solaris ", "6a85cf4d-1dd2-11b2-99a6-080020736631" }, 180 { 0xEB, 0, "BeOS/i386 ", "42465331-3ba3-10f1-802a-4861696b7521" }, 181 { 0xEF, 0, "EFI Sys ", "c12a7328-f81f-11d2-ba4b-00a0c93ec93b" }, 182 }; 183 184 int 185 PRT_protected_guid(const struct uuid *uuid) 186 { 187 char *str = NULL; 188 int rslt = 0; 189 unsigned int i; 190 uint32_t status; 191 192 uuid_to_string(uuid, &str, &status); 193 if (status != uuid_s_ok) { 194 rslt = -1; 195 goto done; 196 } 197 198 for(i = 0; i < nitems(gpt_types); i++) { 199 if (strncmp(str, gpt_types[i].gt_guid, UUID_STR_LEN) == 0) { 200 if (gpt_types[i].gt_protected) 201 rslt = -1; 202 break; 203 } 204 } 205 206 done: 207 free(str); 208 return rslt; 209 } 210 211 void 212 PRT_print_mbrtypes(void) 213 { 214 unsigned int i, idrows; 215 216 idrows = (nitems(mbr_types) + 3) / 4; 217 218 printf("Choose from the following Partition id values:\n"); 219 for (i = 0; i < idrows; i++) { 220 printf("%02X %s %02X %s %02X %s", 221 mbr_types[i].mt_type, mbr_types[i].mt_sname, 222 mbr_types[i+idrows].mt_type, mbr_types[i+idrows].mt_sname, 223 mbr_types[i+idrows*2].mt_type, mbr_types[i+idrows*2].mt_sname); 224 if ((i+idrows*3) < nitems(mbr_types)) { 225 printf(" %02X %s\n", 226 mbr_types[i+idrows*3].mt_type, 227 mbr_types[i+idrows*3].mt_sname); 228 } else 229 printf( "\n" ); 230 } 231 } 232 233 void 234 PRT_print_gpttypes(void) 235 { 236 unsigned int i, idrows; 237 238 idrows = (nitems(gpt_types) + 3) / 4; 239 240 printf("Choose from the following Partition id values:\n"); 241 for (i = 0; i < idrows; i++) { 242 printf("%02X %s %02X %s %02X %s", 243 gpt_types[i].gt_type, gpt_types[i].gt_sname, 244 gpt_types[i+idrows].gt_type, gpt_types[i+idrows].gt_sname, 245 gpt_types[i+idrows*2].gt_type, gpt_types[i+idrows*2].gt_sname); 246 if ((i+idrows*3) < nitems(gpt_types)) { 247 printf(" %02X %s\n", 248 gpt_types[i+idrows*3].gt_type, 249 gpt_types[i+idrows*3].gt_sname); 250 } else 251 printf( "\n" ); 252 } 253 } 254 255 const char * 256 ascii_id(const int id) 257 { 258 static char unknown[] = "<Unknown ID>"; 259 int i; 260 261 for (i = 0; i < nitems(mbr_types); i++) { 262 if (mbr_types[i].mt_type == id) 263 return mbr_types[i].mt_sname; 264 } 265 266 return unknown; 267 } 268 269 void 270 PRT_parse(const struct dos_partition *dp, const uint64_t lba_self, 271 const uint64_t lba_firstembr, struct prt *prt) 272 { 273 off_t off; 274 uint32_t t; 275 276 prt->prt_flag = dp->dp_flag; 277 prt->prt_id = dp->dp_typ; 278 279 if ((prt->prt_id == DOSPTYP_EXTEND) || (prt->prt_id == DOSPTYP_EXTENDL)) 280 off = lba_firstembr; 281 else 282 off = lba_self; 283 284 memcpy(&t, &dp->dp_start, sizeof(uint32_t)); 285 prt->prt_bs = letoh32(t) + off; 286 memcpy(&t, &dp->dp_size, sizeof(uint32_t)); 287 prt->prt_ns = letoh32(t); 288 if (prt->prt_id == DOSPTYP_EFI && prt->prt_ns == UINT32_MAX) 289 prt->prt_ns = DL_GETDSIZE(&dl) - prt->prt_bs; 290 291 PRT_fix_CHS(prt); 292 } 293 294 int 295 check_chs(const struct prt *prt) 296 { 297 if ( (prt->prt_shead > 255) || 298 (prt->prt_ssect >63) || 299 (prt->prt_scyl > 1023) || 300 (prt->prt_ehead >255) || 301 (prt->prt_esect >63) || 302 (prt->prt_ecyl > 1023) ) 303 { 304 return -1; 305 } 306 return 0; 307 } 308 309 void 310 PRT_make(const struct prt *prt, const uint64_t lba_self, const uint64_t lba_firstembr, 311 struct dos_partition *dp) 312 { 313 uint64_t off, t; 314 uint32_t ecyl, scyl; 315 316 scyl = (prt->prt_scyl > 1023) ? 1023 : prt->prt_scyl; 317 ecyl = (prt->prt_ecyl > 1023) ? 1023 : prt->prt_ecyl; 318 319 if ((prt->prt_id == DOSPTYP_EXTEND) || (prt->prt_id == DOSPTYP_EXTENDL)) 320 off = lba_firstembr; 321 else 322 off = lba_self; 323 324 if (check_chs(prt) == 0) { 325 dp->dp_shd = prt->prt_shead & 0xFF; 326 dp->dp_ssect = (prt->prt_ssect & 0x3F) | ((scyl & 0x300) >> 2); 327 dp->dp_scyl = scyl & 0xFF; 328 dp->dp_ehd = prt->prt_ehead & 0xFF; 329 dp->dp_esect = (prt->prt_esect & 0x3F) | ((ecyl & 0x300) >> 2); 330 dp->dp_ecyl = ecyl & 0xFF; 331 } else { 332 memset(dp, 0xFF, sizeof(*dp)); 333 } 334 335 dp->dp_flag = prt->prt_flag & 0xFF; 336 dp->dp_typ = prt->prt_id & 0xFF; 337 338 t = htole64(prt->prt_bs - off); 339 memcpy(&dp->dp_start, &t, sizeof(uint32_t)); 340 if (prt->prt_id == DOSPTYP_EFI && (prt->prt_bs + prt->prt_ns) > 341 DL_GETDSIZE(&dl)) 342 t = htole64(UINT32_MAX); 343 else 344 t = htole64(prt->prt_ns); 345 memcpy(&dp->dp_size, &t, sizeof(uint32_t)); 346 } 347 348 void 349 PRT_print(const int num, const struct prt *prt, const char *units) 350 { 351 const struct unit_type *ut; 352 double size; 353 354 if (prt == NULL) { 355 printf(" Starting Ending " 356 " LBA Info:\n"); 357 printf(" #: id C H S - C H S " 358 "[ start: size ]\n"); 359 printf("---------------------------------------" 360 "----------------------------------------\n"); 361 } else { 362 size = units_size(units, prt->prt_ns, &ut); 363 printf("%c%1d: %.2X %6u %3u %3u - %6u %3u %3u " 364 "[%12llu:%12.0f%s] %s\n", 365 (prt->prt_flag == DOSACTIVE)?'*':' ', 366 num, prt->prt_id, 367 prt->prt_scyl, prt->prt_shead, prt->prt_ssect, 368 prt->prt_ecyl, prt->prt_ehead, prt->prt_esect, 369 prt->prt_bs, size, ut->ut_abbr, ascii_id(prt->prt_id)); 370 } 371 } 372 373 void 374 PRT_fix_BN(struct prt *prt, const int pn) 375 { 376 uint32_t spt, tpc, spc; 377 uint32_t start = 0; 378 uint32_t end = 0; 379 380 if (prt->prt_id == DOSPTYP_UNUSED) { 381 memset(prt, 0, sizeof(*prt)); 382 return; 383 } 384 385 spt = disk.dk_sectors; 386 tpc = disk.dk_heads; 387 spc = spt * tpc; 388 389 start += prt->prt_scyl * spc; 390 start += prt->prt_shead * spt; 391 start += prt->prt_ssect - 1; 392 393 end += prt->prt_ecyl * spc; 394 end += prt->prt_ehead * spt; 395 end += prt->prt_esect - 1; 396 397 /* XXX - Should handle this... */ 398 if (start > end) 399 warnx("Start of partition #%d after end!", pn); 400 401 prt->prt_bs = start; 402 prt->prt_ns = (end - start) + 1; 403 } 404 405 void 406 PRT_fix_CHS(struct prt *prt) 407 { 408 uint32_t spt, tpc, spc; 409 uint32_t start, end, size; 410 uint32_t cyl, head, sect; 411 412 if (prt->prt_id == DOSPTYP_UNUSED || prt->prt_ns == 0) { 413 memset(prt, 0, sizeof(*prt)); 414 return; 415 } 416 417 spt = disk.dk_sectors; 418 tpc = disk.dk_heads; 419 spc = spt * tpc; 420 421 start = prt->prt_bs; 422 size = prt->prt_ns; 423 end = (start + size) - 1; 424 425 cyl = (start / spc); 426 start -= (cyl * spc); 427 head = (start / spt); 428 start -= (head * spt); 429 sect = (start + 1); 430 431 prt->prt_scyl = cyl; 432 prt->prt_shead = head; 433 prt->prt_ssect = sect; 434 435 cyl = (end / spc); 436 end -= (cyl * spc); 437 head = (end / spt); 438 end -= (head * spt); 439 sect = (end + 1); 440 441 prt->prt_ecyl = cyl; 442 prt->prt_ehead = head; 443 prt->prt_esect = sect; 444 } 445 446 char * 447 PRT_uuid_to_typename(const struct uuid *uuid) 448 { 449 static char partition_type[UUID_STR_LEN + 1]; 450 char *uuidstr = NULL; 451 int i, entries, status; 452 453 memset(partition_type, 0, sizeof(partition_type)); 454 455 uuid_to_string(uuid, &uuidstr, &status); 456 if (status != uuid_s_ok) 457 goto done; 458 459 entries = nitems(gpt_types); 460 461 for (i = 0; i < entries; i++) { 462 if (memcmp(gpt_types[i].gt_guid, uuidstr, 463 sizeof(gpt_types[i].gt_guid)) == 0) 464 break; 465 } 466 467 if (i < entries) 468 strlcpy(partition_type, gpt_types[i].gt_sname, 469 sizeof(partition_type)); 470 else 471 strlcpy(partition_type, uuidstr, sizeof(partition_type)); 472 473 done: 474 free(uuidstr); 475 476 return partition_type; 477 } 478 479 int 480 PRT_uuid_to_type(const struct uuid *uuid) 481 { 482 char *uuidstr; 483 int i, status, type; 484 485 type = 0; 486 487 uuid_to_string(uuid, &uuidstr, &status); 488 if (status != uuid_s_ok) 489 goto done; 490 491 for (i = 0; i < nitems(gpt_types); i++) { 492 if (memcmp(gpt_types[i].gt_guid, uuidstr, 493 sizeof(gpt_types[i].gt_guid)) == 0) { 494 type = gpt_types[i].gt_type; 495 break; 496 } 497 } 498 499 done: 500 free(uuidstr); 501 return type; 502 } 503 504 struct uuid * 505 PRT_type_to_uuid(const int type) 506 { 507 static struct uuid guid; 508 int i, entries, status = uuid_s_ok; 509 510 memset(&guid, 0, sizeof(guid)); 511 512 entries = nitems(gpt_types); 513 514 for (i = 0; i < entries; i++) { 515 if (gpt_types[i].gt_type == type) 516 break; 517 } 518 if (i < entries) 519 uuid_from_string(gpt_types[i].gt_guid, &guid, &status); 520 if (i == entries || status != uuid_s_ok) 521 uuid_from_string(gpt_types[0].gt_guid, &guid, &status); 522 523 return &guid; 524 } 525