1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <malloc.h> 29 #include <unistd.h> 30 #include <strings.h> 31 #include <errno.h> 32 #include <libintl.h> 33 #include <libgen.h> 34 #include <fcntl.h> 35 #include <sys/types.h> 36 #include <sys/int_types.h> 37 #include <sys/dkio.h> 38 #include <sys/cdio.h> 39 #include <sys/vtoc.h> 40 #include <sys/stat.h> 41 #include <sys/param.h> 42 #include <sys/fs/udf_volume.h> 43 #include "ud_lib.h" 44 45 extern char *getfullrawname(char *); 46 47 static int32_t ud_get_ecma_ver(ud_handle_t, uint32_t); 48 static int32_t ud_get_fs_bsize(ud_handle_t, uint32_t, uint32_t *); 49 static int32_t ud_parse_fill_vds(ud_handle_t, struct vds *, uint32_t, uint32_t); 50 static int32_t ud_read_and_translate_lvd(ud_handle_t, uint32_t, uint32_t); 51 static int32_t ud_get_latest_lvid(ud_handle_t, uint32_t, uint32_t); 52 static int32_t ud_get_latest_fsd(ud_handle_t, uint16_t, uint32_t, uint32_t); 53 54 static uint16_t ud_crc(uint8_t *, int32_t); 55 static int32_t UdfTxName(uint16_t *, int32_t); 56 static int32_t UncompressUnicode(int32_t, uint8_t *, uint16_t *); 57 static int32_t ud_compressunicode(int32_t, int32_t, uint16_t *, uint8_t *); 58 static int32_t ud_convert2utf8(uint8_t *, uint8_t *, int32_t); 59 static int32_t ud_convert2utf16(uint8_t *, uint8_t *, int32_t); 60 61 62 int 63 ud_init(int fd, ud_handle_t *hp) 64 { 65 struct ud_handle *h; 66 67 if ((h = calloc(1, sizeof (struct ud_handle))) == NULL) { 68 return (ENOMEM); 69 } 70 h->fd = fd; 71 *hp = h; 72 return (0); 73 } 74 75 void 76 ud_fini(ud_handle_t h) 77 { 78 free(h); 79 } 80 81 /* ARGSUSED */ 82 int32_t 83 ud_open_dev(ud_handle_t h, char *special, uint32_t flags) 84 { 85 char *temp; 86 struct stat i_stat, r_stat; 87 88 (void) bzero(&i_stat, sizeof (struct stat)); 89 (void) bzero(&r_stat, sizeof (struct stat)); 90 91 temp = special; 92 /* 93 * Get the stat structure 94 */ 95 if (stat(special, &i_stat) == 0) { 96 if ((i_stat.st_mode & S_IFMT) == S_IFBLK) { 97 98 /* 99 * Block device try to convert to raw device 100 */ 101 102 temp = getfullrawname(special); 103 104 /* 105 * Stat the converted device name and verify 106 * both the raw and block device belong to 107 * the same device 108 */ 109 if (stat(temp, &r_stat) < 0) { 110 temp = special; 111 } else { 112 if (((r_stat.st_mode & S_IFMT) == S_IFBLK) || 113 (r_stat.st_rdev != i_stat.st_rdev)) { 114 temp = special; 115 } 116 } 117 } 118 } 119 120 /* 121 * Now finally open the device 122 */ 123 h->fd = open(temp, flags); 124 125 return (h->fd); 126 } 127 128 /* ARGSUSED */ 129 void 130 ud_close_dev(ud_handle_t h) 131 { 132 /* 133 * Too simple Just close it 134 */ 135 (void) close(h->fd); 136 } 137 138 int32_t 139 ud_read_dev(ud_handle_t h, uint64_t offset, uint8_t *buf, uint32_t count) 140 { 141 /* 142 * Seek to the given offset 143 */ 144 if (lseek(h->fd, offset, SEEK_SET) == -1) { 145 return (1); 146 } 147 148 /* 149 * Read the required number of bytes 150 */ 151 if (read(h->fd, buf, count) != count) { 152 return (1); 153 } 154 return (0); 155 } 156 157 int32_t 158 ud_write_dev(ud_handle_t h, uint64_t offset, uint8_t *buf, uint32_t count) 159 { 160 /* 161 * Seek to the given offset 162 */ 163 if (lseek(h->fd, offset, SEEK_SET) == -1) { 164 return (1); 165 } 166 167 /* 168 * Read the appropriate number of bytes 169 */ 170 if (write(h->fd, buf, count) != count) { 171 return (1); 172 } 173 return (0); 174 } 175 176 /* ----- BEGIN Read and translate the on disk VDS to IN CORE format -------- */ 177 178 int32_t 179 ud_fill_udfs_info(ud_handle_t h) 180 { 181 struct anch_vol_desc_ptr *avdp = NULL; 182 uint32_t offset = 0; 183 184 if (ioctl(h->fd, CDROMREADOFFSET, &offset) == -1) { 185 offset = 0; 186 } 187 188 h->udfs.flags = INVALID_UDFS; 189 190 h->udfs.ecma_version = ud_get_ecma_ver(h, offset); 191 if (h->udfs.ecma_version == UD_ECMA_UNKN) { 192 return (1); 193 } 194 195 h->udfs.lbsize = ud_get_fs_bsize(h, offset, &h->udfs.avdp_loc); 196 if (h->udfs.lbsize == 0) { 197 return (2); 198 } 199 200 h->udfs.avdp_len = lb_roundup(512, h->udfs.lbsize); 201 202 203 if ((avdp = (struct anch_vol_desc_ptr *) 204 malloc(h->udfs.lbsize)) == NULL) { 205 return (3); 206 } 207 if (ud_read_dev(h, h->udfs.avdp_loc * h->udfs.lbsize, 208 (uint8_t *)avdp, h->udfs.lbsize) != 0) { 209 free(avdp); 210 return (4); 211 } 212 if (ud_verify_tag(h, &avdp->avd_tag, UD_ANCH_VOL_DESC, 213 h->udfs.avdp_loc, 1, 0) != 0) { 214 free(avdp); 215 return (5); 216 } 217 218 h->udfs.mvds_loc = SWAP_32(avdp->avd_main_vdse.ext_loc); 219 h->udfs.mvds_len = SWAP_32(avdp->avd_main_vdse.ext_len); 220 221 h->udfs.rvds_loc = SWAP_32(avdp->avd_res_vdse.ext_loc); 222 h->udfs.rvds_len = SWAP_32(avdp->avd_res_vdse.ext_len); 223 224 free(avdp); 225 226 /* 227 * get information from mvds and rvds 228 */ 229 if (ud_parse_fill_vds(h, &h->udfs.mvds, 230 h->udfs.mvds_loc, h->udfs.mvds_len) == 0) { 231 h->udfs.flags |= VALID_MVDS; 232 } 233 if (ud_parse_fill_vds(h, &h->udfs.rvds, 234 h->udfs.rvds_loc, h->udfs.rvds_len) == 0) { 235 h->udfs.flags |= VALID_RVDS; 236 } 237 238 if ((h->udfs.flags & (VALID_MVDS | VALID_RVDS)) == 0) { 239 return (6); 240 } 241 242 /* 243 * If we are here we have 244 * a valid Volume Descriptor Seqence 245 * Read and understand lvd 246 */ 247 if (h->udfs.flags & VALID_MVDS) { 248 if (ud_read_and_translate_lvd(h, h->udfs.mvds.lvd_loc, 249 h->udfs.mvds.lvd_len) != 0) { 250 return (7); 251 } 252 } else { 253 if (ud_read_and_translate_lvd(h, h->udfs.rvds.lvd_loc, 254 h->udfs.rvds.lvd_len) != 0) { 255 return (8); 256 } 257 } 258 259 h->udfs.flags |= VALID_UDFS; 260 261 return (0); 262 } 263 264 static int32_t 265 ud_get_ecma_ver(ud_handle_t h, uint32_t offset) 266 { 267 uint8_t *buf; 268 uint64_t off; 269 uint64_t end_off; 270 struct nsr_desc *ndsc; 271 uint32_t ecma_ver = UD_ECMA_UNKN; 272 273 /* 274 * Allocate a buffer of size UD_VOL_REC_BSZ 275 */ 276 if ((buf = (uint8_t *)malloc(UD_VOL_REC_BSZ)) == NULL) { 277 278 /* 279 * Uh could not even allocate this much 280 */ 281 goto end; 282 } 283 284 /* 285 * Start from 32k and keep reading 2k blocks we 286 * should be able to find NSR if we have one by 256 * 2k bytes 287 */ 288 off = offset * 2048 + UD_VOL_REC_START; 289 end_off = offset * 2048 + UD_VOL_REC_END; 290 for (; off < end_off; off += UD_VOL_REC_BSZ) { 291 292 if (ud_read_dev(h, off, buf, UD_VOL_REC_BSZ) == 0) { 293 294 ndsc = (struct nsr_desc *)buf; 295 /* 296 * Is this either NSR02 or NSR03 297 */ 298 if ((ndsc->nsr_str_type == 0) && 299 (ndsc->nsr_ver == 1) && 300 (ndsc->nsr_id[0] == 'N') && 301 (ndsc->nsr_id[1] == 'S') && 302 (ndsc->nsr_id[2] == 'R') && 303 (ndsc->nsr_id[3] == '0') && 304 ((ndsc->nsr_id[4] == '2') || 305 (ndsc->nsr_id[4] == '3'))) { 306 307 (void) strncpy((char *)h->udfs.ecma_id, 308 (char *)ndsc->nsr_id, 5); 309 310 switch (ndsc->nsr_id[4]) { 311 case '2' : 312 313 /* 314 * ECMA 167/2 315 */ 316 ecma_ver = UD_ECMA_VER2; 317 goto end; 318 case '3' : 319 320 /* 321 * ECMA 167/3 322 */ 323 ecma_ver = UD_ECMA_VER3; 324 goto end; 325 } 326 } 327 } 328 } 329 330 end: 331 /* 332 * Cleanup 333 */ 334 free(buf); 335 return (ecma_ver); 336 } 337 338 static uint32_t last_block_index[] = {0, 0, 256, 2, 2 + 256, 339 150, 150 + 256, 152, 152 + 256}; 340 341 static int32_t 342 ud_get_fs_bsize(ud_handle_t h, uint32_t offset, uint32_t *avd_loc) 343 { 344 uint64_t off; 345 int32_t index, bsize, shift, end_index; 346 uint32_t num_blocks, sub_blk; 347 uint8_t *buf = NULL; 348 struct anch_vol_desc_ptr *avdp; 349 350 if ((buf = (uint8_t *)malloc(MAXBSIZE)) == NULL) { 351 return (0); 352 } 353 354 /* 355 * If we could figure out the last block 356 * search at 256, N, N - 256 blocks 357 * otherwise just check at 256 358 */ 359 if (ud_get_num_blks(h, &num_blocks) != 0) { 360 end_index = 1; 361 num_blocks = 0; 362 } else { 363 end_index = sizeof (last_block_index) / 4; 364 } 365 366 for (index = 0; index < end_index; index++) { 367 sub_blk = last_block_index[index]; 368 369 /* 370 * Start guessing from DEV_BSIZE to MAXBSIZE 371 */ 372 for (bsize = DEV_BSIZE, shift = 0; 373 bsize <= MAXBSIZE; bsize <<= 1, shift++) { 374 375 if (index == 0) { 376 377 /* 378 * Check if we atleast have 256 of bsize 379 * blocks on the device 380 */ 381 if ((end_index == 0) || 382 (num_blocks > (256 << shift))) { 383 *avd_loc = 256; 384 if (bsize <= 2048) { 385 *avd_loc += 386 offset * 2048 / bsize; 387 } else { 388 *avd_loc += 389 offset / (bsize / 2048); 390 } 391 } else { 392 continue; 393 } 394 } else { 395 /* 396 * Calculate the bsize avd block 397 */ 398 if ((num_blocks) && 399 (num_blocks > (sub_blk << shift))) { 400 *avd_loc = (num_blocks >> shift) - 401 sub_blk; 402 } else { 403 continue; 404 } 405 } 406 407 off = (uint64_t)*avd_loc * bsize; 408 409 /* 410 * Read bsize bytes at off 411 */ 412 if (ud_read_dev(h, off, buf, bsize) != 0) { 413 continue; 414 } 415 416 /* 417 * Check if we have a Anchor Volume Descriptor here 418 */ 419 420 /* LINTED */ 421 avdp = (struct anch_vol_desc_ptr *)buf; 422 if (ud_verify_tag(h, &avdp->avd_tag, 423 UD_ANCH_VOL_DESC, *avd_loc, 1, 0) != 0) { 424 continue; 425 } 426 goto end; 427 } 428 } 429 430 end: 431 if (bsize > MAXBSIZE) { 432 bsize = 0; 433 *avd_loc = 0; 434 } 435 free(buf); 436 return (bsize); 437 } 438 439 static int32_t 440 ud_parse_fill_vds(ud_handle_t h, struct vds *v, 441 uint32_t vds_loc, uint32_t vds_len) 442 { 443 uint8_t *addr, *taddr, *eaddr; 444 uint16_t id; 445 int32_t i; 446 uint64_t off; 447 struct tag *tag; 448 struct pri_vol_desc *pvd; 449 struct log_vol_desc *lvd; 450 struct vol_desc_ptr *vds; 451 struct unall_spc_desc *usd; 452 453 begin: 454 if ((addr = (uint8_t *)malloc(vds_len)) == NULL) { 455 return (1); 456 } 457 458 off = vds_loc * h->udfs.lbsize; 459 if (ud_read_dev(h, off, addr, vds_len) != 0) { 460 goto end; 461 } 462 463 for (taddr = addr, eaddr = addr + h->udfs.mvds_len; taddr < eaddr; 464 taddr += h->udfs.lbsize, vds_loc ++) { 465 466 /* LINTED */ 467 tag = (struct tag *)taddr; 468 id = SWAP_16(tag->tag_id); 469 /* 470 * If you cannot verify the tag just skip it 471 * This is not a fatal error 472 */ 473 if (ud_verify_tag(h, tag, id, vds_loc, 1, 0) != 0) { 474 continue; 475 } 476 switch (id) { 477 case UD_PRI_VOL_DESC : 478 479 /* 480 * Primary Volume Descriptor 481 */ 482 /* LINTED */ 483 pvd = (struct pri_vol_desc *)taddr; 484 if ((v->pvd_len == 0) || 485 (SWAP_32(pvd->pvd_vdsn) > v->pvd_vdsn)) { 486 v->pvd_vdsn = SWAP_32(pvd->pvd_vdsn); 487 v->pvd_loc = vds_loc; 488 v->pvd_len = h->udfs.lbsize; 489 } 490 break; 491 case UD_VOL_DESC_PTR : 492 493 /* 494 * Curent sequence is continued from 495 * the location pointed by vdp 496 */ 497 /* LINTED */ 498 vds = (struct vol_desc_ptr *)taddr; 499 500 if (SWAP_32(vds->vdp_nvdse.ext_len) != 0) { 501 vds_loc = SWAP_32(vds->vdp_nvdse.ext_loc); 502 vds_len = SWAP_32(vds->vdp_nvdse.ext_len); 503 free(addr); 504 goto begin; 505 } 506 break; 507 case UD_IMPL_USE_DESC : 508 509 /* 510 * Implementation Use Volume Descriptor 511 */ 512 v->iud_loc = vds_loc; 513 v->iud_len = lb_roundup(512, h->udfs.lbsize); 514 break; 515 case UD_PART_DESC : 516 { 517 struct ud_part *p; 518 struct phdr_desc *ph; 519 struct part_desc *pd; 520 521 /* 522 * Partition Descriptor 523 */ 524 /* LINTED */ 525 pd = (struct part_desc *)taddr; 526 527 for (i = 0; i < h->n_parts; i++) { 528 p = &h->part[i]; 529 530 if ((SWAP_16(pd->pd_pnum) == 531 p->udp_number) && 532 (SWAP_32(pd->pd_vdsn) > 533 p->udp_seqno)) { 534 break; 535 } 536 } 537 538 v->part_loc[i] = vds_loc; 539 v->part_len[i] = 540 lb_roundup(512, h->udfs.lbsize); 541 542 p = &h->part[i]; 543 p->udp_number = SWAP_16(pd->pd_pnum); 544 p->udp_seqno = SWAP_32(pd->pd_vdsn); 545 p->udp_access = SWAP_32(pd->pd_acc_type); 546 p->udp_start = SWAP_32(pd->pd_part_start); 547 p->udp_length = SWAP_32(pd->pd_part_length); 548 549 /* LINTED */ 550 ph = (struct phdr_desc *)pd->pd_pc_use; 551 if (ph->phdr_ust.sad_ext_len) { 552 p->udp_flags = UDP_SPACETBLS; 553 p->udp_unall_loc = SWAP_32(ph->phdr_ust.sad_ext_loc); 554 p->udp_unall_len = SWAP_32(ph->phdr_ust.sad_ext_len); 555 p->udp_freed_loc = SWAP_32(ph->phdr_fst.sad_ext_loc); 556 p->udp_freed_len = SWAP_32(ph->phdr_fst.sad_ext_len); 557 } else { 558 p->udp_flags = UDP_BITMAPS; 559 p->udp_unall_loc = SWAP_32(ph->phdr_usb.sad_ext_loc); 560 p->udp_unall_len = SWAP_32(ph->phdr_usb.sad_ext_len); 561 p->udp_freed_loc = SWAP_32(ph->phdr_fsb.sad_ext_loc); 562 p->udp_freed_len = SWAP_32(ph->phdr_fsb.sad_ext_len); 563 } 564 565 if (i == h->n_parts) { 566 h->n_parts ++; 567 } 568 } 569 break; 570 case UD_LOG_VOL_DESC : 571 572 /* 573 * Logical Volume Descriptor 574 */ 575 /* LINTED */ 576 lvd = (struct log_vol_desc *)taddr; 577 if ((v->lvd_len == 0) || 578 (SWAP_32(lvd->lvd_vdsn) > v->lvd_vdsn)) { 579 v->lvd_vdsn = SWAP_32(lvd->lvd_vdsn); 580 v->lvd_loc = vds_loc; 581 v->lvd_len = ((uint32_t) 582 &((struct log_vol_desc *)0)->lvd_pmaps); 583 v->lvd_len = 584 lb_roundup(v->lvd_len, h->udfs.lbsize); 585 } 586 break; 587 case UD_UNALL_SPA_DESC : 588 589 /* 590 * Unallocated Space Descriptor 591 */ 592 /* LINTED */ 593 usd = (struct unall_spc_desc *)taddr; 594 v->usd_loc = vds_loc; 595 v->usd_len = ((uint32_t) 596 &((unall_spc_desc_t *)0)->ua_al_dsc) + 597 SWAP_32(usd->ua_nad) * 598 sizeof (struct extent_ad); 599 v->usd_len = lb_roundup(v->usd_len, h->udfs.lbsize); 600 break; 601 case UD_TERM_DESC : 602 /* 603 * Success fully completed 604 */ 605 goto end; 606 default : 607 /* 608 * If you donot undetstand any tag just skip 609 * it. This is not a fatal error 610 */ 611 break; 612 } 613 } 614 615 end: 616 free(addr); 617 if ((v->pvd_len == 0) || 618 (v->part_len[0] == 0) || 619 (v->lvd_len == 0)) { 620 return (1); 621 } 622 623 return (0); 624 } 625 626 static int32_t 627 ud_read_and_translate_lvd(ud_handle_t h, uint32_t lvd_loc, uint32_t lvd_len) 628 { 629 caddr_t addr; 630 uint16_t fsd_prn; 631 uint32_t fsd_loc, fsd_len; 632 uint32_t lvds_loc, lvds_len; 633 uint64_t off; 634 struct log_vol_desc *lvd = NULL; 635 636 int32_t max_maps, i, mp_sz, index; 637 struct ud_map *m; 638 struct pmap_hdr *ph; 639 struct pmap_typ1 *typ1; 640 struct pmap_typ2 *typ2; 641 642 if (lvd_len == 0) { 643 return (1); 644 } 645 646 if ((lvd = (struct log_vol_desc *) 647 malloc(lvd_len)) == NULL) { 648 return (1); 649 } 650 651 off = lvd_loc * h->udfs.lbsize; 652 if (ud_read_dev(h, off, (uint8_t *)lvd, lvd_len) != 0) { 653 free(lvd); 654 return (1); 655 } 656 657 if (ud_verify_tag(h, &lvd->lvd_tag, UD_LOG_VOL_DESC, 658 lvd_loc, 1, 0) != 0) { 659 free(lvd); 660 return (1); 661 } 662 663 /* 664 * Take care of maps 665 */ 666 max_maps = SWAP_32(lvd->lvd_num_pmaps); 667 ph = (struct pmap_hdr *)lvd->lvd_pmaps; 668 for (h->n_maps = index = 0; index < max_maps; index++) { 669 m = &h->maps[h->n_maps]; 670 switch (ph->maph_type) { 671 case MAP_TYPE1 : 672 673 /* LINTED */ 674 typ1 = (struct pmap_typ1 *)ph; 675 676 m->udm_flags = UDM_MAP_NORM; 677 m->udm_vsn = SWAP_16(typ1->map1_vsn); 678 m->udm_pn = SWAP_16(typ1->map1_pn); 679 h->n_maps++; 680 break; 681 682 case MAP_TYPE2 : 683 684 /* LINTED */ 685 typ2 = (struct pmap_typ2 *)ph; 686 687 if (strncmp(typ2->map2_pti.reg_id, 688 UDF_VIRT_PART, 23) == 0) { 689 690 m->udm_flags = UDM_MAP_VPM; 691 m->udm_vsn = SWAP_16(typ2->map2_vsn); 692 m->udm_pn = SWAP_16(typ2->map2_pn); 693 } else if (strncmp(typ2->map2_pti.reg_id, 694 UDF_SPAR_PART, 23) == 0) { 695 696 if ((SWAP_16(typ2->map2_pl) != 32) || 697 (typ2->map2_nst < 1) || 698 (typ2->map2_nst > 4)) { 699 break; 700 } 701 m->udm_flags = UDM_MAP_SPM; 702 m->udm_vsn = SWAP_16(typ2->map2_vsn); 703 m->udm_pn = SWAP_16(typ2->map2_pn); 704 705 m->udm_plen = SWAP_16(typ2->map2_pl); 706 m->udm_nspm = typ2->map2_nst; 707 m->udm_spsz = SWAP_32(typ2->map2_sest); 708 709 mp_sz = lb_roundup(m->udm_spsz, h->udfs.lbsize); 710 711 if ((addr = malloc(mp_sz * m->udm_nspm)) == 712 NULL) { 713 break; 714 } 715 716 for (i = 0; i < m->udm_nspm; i++) { 717 m->udm_loc[i] = 718 SWAP_32(typ2->map2_st[index]); 719 m->udm_spaddr[i] = addr + i * mp_sz; 720 721 off = m->udm_loc[i] * h->udfs.lbsize; 722 if (ud_read_dev(h, off, 723 (uint8_t *)m->udm_spaddr[i], 724 mp_sz) != 0) { 725 m->udm_spaddr[i] = NULL; 726 continue; 727 } 728 } 729 } 730 h->n_maps++; 731 default : 732 break; 733 } 734 ph = (struct pmap_hdr *)(((uint8_t *)h) + ph->maph_length); 735 } 736 737 lvds_loc = SWAP_32(lvd->lvd_int_seq_ext.ext_loc); 738 lvds_len = SWAP_32(lvd->lvd_int_seq_ext.ext_len); 739 740 fsd_prn = SWAP_16(lvd->lvd_lvcu.lad_ext_prn); 741 fsd_loc = SWAP_32(lvd->lvd_lvcu.lad_ext_loc); 742 fsd_len = SWAP_32(lvd->lvd_lvcu.lad_ext_len); 743 744 free(lvd); 745 746 /* 747 * Get the latest LVID 748 */ 749 if (ud_get_latest_lvid(h, lvds_loc, lvds_len) != 0) { 750 return (1); 751 } 752 753 if (ud_get_latest_fsd(h, fsd_prn, fsd_loc, fsd_len) != 0) { 754 return (1); 755 } 756 757 return (0); 758 } 759 760 static int32_t 761 ud_get_latest_lvid(ud_handle_t h, uint32_t lvds_loc, uint32_t lvds_len) 762 { 763 uint8_t *addr, *taddr, *eaddr; 764 uint16_t id; 765 uint64_t off; 766 struct tag *tag; 767 struct log_vol_int_desc *lvid; 768 769 begin: 770 if ((addr = (uint8_t *)malloc(lvds_len)) == NULL) { 771 return (1); 772 } 773 774 off = lvds_loc * h->udfs.lbsize; 775 if (ud_read_dev(h, off, addr, lvds_len) != 0) { 776 goto end; 777 } 778 779 for (taddr = addr, eaddr = addr + h->udfs.mvds_len; taddr < eaddr; 780 taddr += h->udfs.lbsize, lvds_loc ++) { 781 782 /* LINTED */ 783 tag = (struct tag *)taddr; 784 id = SWAP_16(tag->tag_id); 785 /* 786 * If you cannot verify the tag just skip it 787 * This is not a fatal error 788 */ 789 if (ud_verify_tag(h, tag, id, lvds_loc, 1, 0) != 0) { 790 continue; 791 } 792 switch (id) { 793 case UD_LOG_VOL_INT : 794 795 /* 796 * Logical Volume Integrity Descriptor 797 */ 798 /* LINTED */ 799 lvid = (struct log_vol_int_desc *)taddr; 800 h->udfs.lvid_loc = lvds_loc; 801 h->udfs.lvid_len = ((uint32_t) 802 &((struct log_vol_int_desc *)0)->lvid_fst) + 803 SWAP_32(lvid->lvid_npart) * 8 + 804 SWAP_32(lvid->lvid_liu); 805 h->udfs.lvid_len = lb_roundup(h->udfs.lvid_len, 806 h->udfs.lbsize); 807 808 /* 809 * It seems we have a next integrity 810 * sequence 811 */ 812 if (SWAP_32(lvid->lvid_nie.ext_len) != 0) { 813 free(addr); 814 lvds_loc = SWAP_32(lvid->lvid_nie.ext_loc); 815 lvds_len = SWAP_32(lvid->lvid_nie.ext_len); 816 goto begin; 817 } 818 goto end; 819 case UD_TERM_DESC : 820 821 /* 822 * Success fully completed 823 */ 824 goto end; 825 default : 826 /* 827 * If you donot undetstand any tag just skip 828 * it. This is not a fatal error 829 */ 830 break; 831 } 832 } 833 end: 834 free(addr); 835 if (h->udfs.lvid_len == 0) { 836 return (1); 837 } 838 return (0); 839 } 840 841 static int32_t 842 ud_get_latest_fsd(ud_handle_t h, uint16_t fsd_prn, 843 uint32_t fsd_loc, uint32_t fsd_len) 844 { 845 uint8_t *addr, *taddr, *eaddr; 846 uint16_t id; 847 uint64_t off; 848 uint32_t fsds_loc, fsds_len; 849 struct tag *tag; 850 struct file_set_desc *fsd; 851 uint32_t old_fsn = 0; 852 853 begin: 854 h->udfs.fsds_prn = fsd_prn; 855 h->udfs.fsds_loc = fsd_loc; 856 h->udfs.fsds_len = fsd_len; 857 858 fsds_loc = ud_xlate_to_daddr(h, fsd_prn, fsd_loc); 859 fsds_len = lb_roundup(fsd_len, h->udfs.lbsize); 860 861 if ((addr = (uint8_t *)malloc(fsds_len)) == NULL) { 862 return (1); 863 } 864 865 off = fsds_loc * h->udfs.lbsize; 866 if (ud_read_dev(h, off, addr, fsds_len) != 0) { 867 goto end; 868 } 869 870 for (taddr = addr, eaddr = addr + h->udfs.mvds_len; taddr < eaddr; 871 taddr += h->udfs.lbsize, fsds_loc ++) { 872 873 /* LINTED */ 874 tag = (struct tag *)taddr; 875 id = SWAP_16(tag->tag_id); 876 /* 877 * If you cannot verify the tag just skip it 878 * This is not a fatal error 879 */ 880 if (ud_verify_tag(h, tag, id, fsds_loc, 1, 0) != 0) { 881 continue; 882 } 883 switch (id) { 884 case UD_FILE_SET_DESC : 885 /* LINTED */ 886 fsd = (struct file_set_desc *)taddr; 887 if ((h->udfs.fsd_len == 0) || 888 (SWAP_32(fsd->fsd_fs_no) > old_fsn)) { 889 old_fsn = SWAP_32(fsd->fsd_fs_no); 890 h->udfs.fsd_loc = fsds_loc; 891 h->udfs.fsd_len = lb_roundup(512, 892 h->udfs.lbsize); 893 h->udfs.ricb_prn = 894 SWAP_16(fsd->fsd_root_icb.lad_ext_prn); 895 h->udfs.ricb_loc = 896 SWAP_32(fsd->fsd_root_icb.lad_ext_loc); 897 h->udfs.ricb_len = 898 SWAP_32(fsd->fsd_root_icb.lad_ext_len); 899 } 900 if (SWAP_32(fsd->fsd_next.lad_ext_len) != 0) { 901 fsd_prn = SWAP_16(fsd->fsd_next.lad_ext_prn); 902 fsd_loc = SWAP_32(fsd->fsd_next.lad_ext_loc); 903 fsd_len = SWAP_32(fsd->fsd_next.lad_ext_len); 904 goto begin; 905 } 906 break; 907 case UD_TERM_DESC : 908 909 /* 910 * Success fully completed 911 */ 912 goto end; 913 default : 914 /* 915 * If you donot undetstand any tag just skip 916 * it. This is not a fatal error 917 */ 918 break; 919 } 920 } 921 922 end: 923 free(addr); 924 if (h->udfs.fsd_len == 0) { 925 return (1); 926 } 927 return (0); 928 } 929 930 int32_t 931 ud_get_num_blks(ud_handle_t h, uint32_t *blkno) 932 { 933 struct vtoc vtoc; 934 struct dk_cinfo dki_info; 935 int32_t error; 936 937 /* 938 * Get VTOC from driver 939 */ 940 if ((error = ioctl(h->fd, DKIOCGVTOC, (intptr_t)&vtoc)) != 0) { 941 return (error); 942 } 943 944 /* 945 * Verify if is proper 946 */ 947 if (vtoc.v_sanity != VTOC_SANE) { 948 return (EINVAL); 949 } 950 951 /* 952 * Get dk_cinfo from driver 953 */ 954 if ((error = ioctl(h->fd, DKIOCINFO, (intptr_t)&dki_info)) != 0) { 955 return (error); 956 } 957 958 if (dki_info.dki_partition >= V_NUMPAR) { 959 return (EINVAL); 960 } 961 962 /* 963 * Return the size of the partition 964 */ 965 *blkno = vtoc.v_part[dki_info.dki_partition].p_size; 966 967 return (0); 968 } 969 970 uint32_t 971 ud_xlate_to_daddr(ud_handle_t h, uint16_t prn, uint32_t blkno) 972 { 973 int32_t i; 974 struct ud_map *m; 975 struct ud_part *p; 976 977 978 if (prn < h->n_maps) { 979 m = &h->maps[prn]; 980 for (i = 0; i < h->n_parts; i++) { 981 p = &h->part[i]; 982 if (m->udm_pn == p->udp_number) { 983 return (p->udp_start + blkno); 984 } 985 } 986 } 987 return (0); 988 } 989 990 /* ------ END Read and translate the on disk VDS to IN CORE format -------- */ 991 992 int32_t 993 ud_verify_tag(ud_handle_t h, struct tag *tag, uint16_t id, 994 uint32_t blockno, int32_t do_crc, int32_t print_msg) 995 { 996 int32_t i; 997 uint8_t *addr, cksum = 0; 998 uint16_t crc; 999 1000 1001 /* 1002 * Verify Tag Identifier 1003 */ 1004 if (tag->tag_id != SWAP_16(id)) { 1005 if (print_msg != 0) { 1006 (void) fprintf(stderr, 1007 gettext("tag does not verify tag %x req %x\n"), 1008 SWAP_16(tag->tag_id), id); 1009 } 1010 return (1); 1011 } 1012 1013 /* 1014 * Verify Tag Descriptor Version 1015 */ 1016 if (SWAP_16(tag->tag_desc_ver) != h->udfs.ecma_version) { 1017 if (print_msg != 0) { 1018 (void) fprintf(stderr, 1019 gettext("tag version does not match with " 1020 "NSR descriptor version TAG %x NSR %x\n"), 1021 SWAP_16(tag->tag_desc_ver), 1022 h->udfs.ecma_version); 1023 } 1024 return (1); 1025 } 1026 1027 /* 1028 * Caliculate Tag Checksum 1029 */ 1030 addr = (uint8_t *)tag; 1031 for (i = 0; i <= 15; i++) { 1032 if (i != 4) { 1033 cksum += addr[i]; 1034 } 1035 } 1036 1037 /* 1038 * Verify Tag Checksum 1039 */ 1040 if (cksum != tag->tag_cksum) { 1041 if (print_msg != 0) { 1042 (void) fprintf(stderr, 1043 gettext("Checksum Does not Verify TAG" 1044 " %x CALC %x\n"), tag->tag_cksum, cksum); 1045 } 1046 return (1); 1047 } 1048 1049 1050 /* 1051 * Do we want to do crc 1052 */ 1053 if (do_crc) { 1054 if (tag->tag_crc_len) { 1055 1056 /* 1057 * Caliculate CRC for the descriptor 1058 */ 1059 crc = ud_crc(addr + 0x10, SWAP_16(tag->tag_crc_len)); 1060 1061 /* 1062 * Verify CRC 1063 */ 1064 if (crc != SWAP_16(tag->tag_crc)) { 1065 if (print_msg != 0) { 1066 (void) fprintf(stderr, 1067 gettext("CRC Does not verify" 1068 " TAG %x CALC %x %x\n"), 1069 SWAP_16(tag->tag_crc), 1070 crc, addr); 1071 } 1072 } 1073 } 1074 1075 /* 1076 * Verify Tag Location 1077 */ 1078 if (SWAP_32(blockno) != tag->tag_loc) { 1079 if (print_msg != 0) { 1080 (void) fprintf(stderr, 1081 gettext("Tag Location Does not verify" 1082 " blockno %x tag_blockno %x\n"), 1083 blockno, SWAP_32(tag->tag_loc)); 1084 } 1085 } 1086 } 1087 1088 return (0); 1089 } 1090 1091 1092 /* ARGSUSED1 */ 1093 void 1094 ud_make_tag(ud_handle_t h, struct tag *tag, uint16_t tag_id, 1095 uint32_t blkno, uint16_t crc_len) 1096 { 1097 int32_t i; 1098 uint16_t crc; 1099 uint8_t *addr, cksum = 0; 1100 1101 tag->tag_id = SWAP_16(tag_id); 1102 tag->tag_desc_ver = SWAP_16(h->udfs.ecma_version); 1103 tag->tag_cksum = 0; 1104 tag->tag_res = 0; 1105 1106 /* 1107 * Calicualte and assign CRC, CRC_LEN 1108 */ 1109 addr = (uint8_t *)tag; 1110 crc = ud_crc(addr + 0x10, crc_len); 1111 tag->tag_crc = SWAP_16(crc); 1112 tag->tag_crc_len = SWAP_16(crc_len); 1113 tag->tag_loc = SWAP_32(blkno); 1114 1115 /* 1116 * Caliculate Checksum 1117 */ 1118 for (i = 0; i <= 15; i++) { 1119 cksum += addr[i]; 1120 } 1121 1122 /* 1123 * Assign Checksum 1124 */ 1125 tag->tag_cksum = cksum; 1126 } 1127 1128 /* **************** udf specific subroutines *********************** */ 1129 1130 static uint16_t ud_crc_table[256] = { 1131 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 1132 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, 1133 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, 1134 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, 1135 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, 1136 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, 1137 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, 1138 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, 1139 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, 1140 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, 1141 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, 1142 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, 1143 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, 1144 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, 1145 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, 1146 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, 1147 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, 1148 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, 1149 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, 1150 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, 1151 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, 1152 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 1153 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, 1154 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, 1155 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, 1156 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, 1157 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, 1158 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, 1159 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, 1160 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, 1161 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, 1162 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 1163 }; 1164 1165 static uint16_t 1166 ud_crc(uint8_t *addr, int32_t len) 1167 { 1168 uint16_t crc = 0; 1169 1170 while (len-- > 0) { 1171 crc = ud_crc_table[(crc >> 8 ^ *addr++) & 0xff] ^ (crc<<8); 1172 } 1173 1174 return (crc); 1175 } 1176 1177 #define MAXNAMLEN 0x200 1178 1179 1180 #define POUND 0x0023 1181 #define DOT 0x002E 1182 #define SLASH 0x002F 1183 #define UNDERBAR 0x005F 1184 1185 1186 static uint16_t htoc[16] = {'0', '1', '2', '3', 1187 '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; 1188 /* 1189 * unicode is the string of 16-bot characters 1190 * length is the number of 16-bit characters 1191 */ 1192 static int32_t 1193 UdfTxName(uint16_t *unicode, int32_t count) 1194 { 1195 int32_t i, j, k, lic, make_crc, dot_loc; 1196 uint16_t crc; 1197 1198 if ((unicode[0] == DOT) && 1199 ((count == 1) || ((count == 2) && (unicode[1] == DOT)))) { 1200 crc = DOT; 1201 if (count == 2) { 1202 crc += DOT; 1203 } 1204 unicode[0] = UNDERBAR; 1205 unicode[1] = POUND; 1206 unicode[2] = htoc[(uint16_t)(crc & 0xf000) >> 12]; 1207 unicode[3] = htoc[(uint16_t)(crc & 0xf00) >> 8]; 1208 unicode[4] = htoc[(uint16_t)(crc & 0xf0) >> 4]; 1209 unicode[5] = htoc[crc & 0xf]; 1210 return (6); 1211 } 1212 crc = 0; 1213 j = make_crc = 0; 1214 lic = dot_loc = -1; 1215 for (i = 0; i < count; i++) { 1216 if (make_crc) { 1217 crc += unicode[i]; 1218 } 1219 if (unicode[i] == DOT) { 1220 dot_loc = j; 1221 } 1222 if ((unicode[i] == SLASH) || 1223 (unicode[i] == 0)) { 1224 if (make_crc == 0) { 1225 for (k = 0; k <= i; k++) { 1226 crc += unicode[k]; 1227 } 1228 make_crc = 1; 1229 } 1230 if (lic != (i - 1)) { 1231 unicode[j++] = UNDERBAR; 1232 } 1233 lic = i; 1234 } else { 1235 unicode[j++] = unicode[i]; 1236 } 1237 } 1238 1239 if (make_crc) { 1240 if (dot_loc != -1) { 1241 if ((j + 5) > MAXNAMLEN) { 1242 if ((j - dot_loc + 5) > MAXNAMLEN) { 1243 j = MAXNAMLEN - 5 + dot_loc; 1244 for (k = MAXNAMLEN; 1245 j >= dot_loc; k --, j--) { 1246 unicode[k] = unicode[j]; 1247 } 1248 k = 0; 1249 } else { 1250 for (k = MAXNAMLEN; 1251 j >= dot_loc; k--, j--) { 1252 unicode[k] = unicode[j]; 1253 } 1254 k -= 4; 1255 } 1256 j = MAXNAMLEN; 1257 } else { 1258 for (k = j; k >= dot_loc; k--) { 1259 unicode[k + 5] = unicode[k]; 1260 } 1261 k = dot_loc; 1262 j += 5; 1263 } 1264 } else { 1265 if ((j + 5) > MAXNAMLEN) { 1266 j = MAXNAMLEN; 1267 k = MAXNAMLEN - 5; 1268 } else { 1269 k = j; 1270 j += 5; 1271 } 1272 } 1273 unicode[k++] = POUND; 1274 unicode[k++] = htoc[(uint16_t)(crc & 0xf000) >> 12]; 1275 unicode[k++] = htoc[(uint16_t)(crc & 0xf00) >> 8]; 1276 unicode[k++] = htoc[(uint16_t)(crc & 0xf0) >> 4]; 1277 unicode[k++] = htoc[crc & 0xf]; 1278 } 1279 return (j); 1280 } 1281 1282 /* 1283 * Assumes the output buffer is large 1284 * enough to hold the uncompressed 1285 * code 1286 */ 1287 static int32_t 1288 UncompressUnicode( 1289 int32_t numberOfBytes, /* (Input) number of bytes read from media. */ 1290 uint8_t *UDFCompressed, /* (Input) bytes read from media. */ 1291 uint16_t *unicode) /* (Output) uncompressed unicode characters. */ 1292 { 1293 int32_t compID; 1294 int32_t returnValue, unicodeIndex, byteIndex; 1295 1296 1297 /* 1298 * Use UDFCompressed to store current byte being read. 1299 */ 1300 compID = UDFCompressed[0]; 1301 1302 /* First check for valid compID. */ 1303 if (compID != 8 && compID != 16) { 1304 returnValue = -1; 1305 } else { 1306 unicodeIndex = 0; 1307 byteIndex = 1; 1308 1309 /* Loop through all the bytes. */ 1310 while (byteIndex < numberOfBytes) { 1311 if (compID == 16) { 1312 /* 1313 * Move the first byte to the 1314 * high bits of the unicode char. 1315 */ 1316 unicode[unicodeIndex] = 1317 UDFCompressed[byteIndex++] << 8; 1318 } else { 1319 unicode[unicodeIndex] = 0; 1320 } 1321 if (byteIndex < numberOfBytes) { 1322 /* 1323 * Then the next byte to the low bits. 1324 */ 1325 unicode[unicodeIndex] |= 1326 UDFCompressed[byteIndex++]; 1327 } 1328 unicodeIndex++; 1329 } 1330 returnValue = unicodeIndex; 1331 } 1332 return (returnValue); 1333 } 1334 1335 1336 1337 1338 1339 static int32_t 1340 ud_compressunicode( 1341 int32_t numberOfChars, /* (Input) number of unicode characters. */ 1342 int32_t compID, /* (Input) compression ID to be used. */ 1343 uint16_t *unicode, /* (Input) unicode characters to compress. */ 1344 uint8_t *UDFCompressed) /* (Output) compressed string, as bytes. */ 1345 { 1346 int32_t byteIndex; 1347 1348 if (compID != 8 && compID != 16) { 1349 /* 1350 * Unsupported compression ID ! 1351 */ 1352 byteIndex = -1; 1353 } else { 1354 /* 1355 * Place compression code in first byte. 1356 */ 1357 UDFCompressed[0] = (uint8_t)compID; 1358 (void) strncpy((caddr_t)&UDFCompressed[1], 1359 (caddr_t)unicode, numberOfChars); 1360 byteIndex = numberOfChars + 1; 1361 } 1362 return (byteIndex); 1363 } 1364 1365 1366 static int32_t 1367 ud_convert2utf8(uint8_t *ibuf, uint8_t *obuf, int32_t length) 1368 { 1369 int i, size; 1370 uint16_t *buf; 1371 1372 /* LINTED */ 1373 buf = (uint16_t *)obuf; 1374 1375 size = UncompressUnicode(length, ibuf, buf); 1376 1377 size = UdfTxName(buf, size); 1378 1379 for (i = 0; i < size; i++) { 1380 obuf[i] = (uint8_t)buf[i]; 1381 } 1382 obuf[i] = '\0'; 1383 1384 return (size); 1385 } 1386 1387 static int32_t 1388 ud_convert2utf16(uint8_t *ibuf, uint8_t *obuf, int32_t length) 1389 { 1390 int32_t comp_len; 1391 uint16_t *ptr; 1392 1393 /* LINTED */ 1394 ptr = (uint16_t *)ibuf; 1395 comp_len = ud_compressunicode(length, 8, ptr, obuf); 1396 1397 return (comp_len); 1398 } 1399 1400 /* 1401 * Assumption code set is zero in udfs 1402 */ 1403 void 1404 ud_convert2local(int8_t *ibuf, int8_t *obuf, int32_t length) 1405 { 1406 wchar_t buf4c[128]; 1407 int32_t i, comp, index; 1408 1409 /* 1410 * Special uncompress code 1411 * written to accomodate solaris wchar_t 1412 */ 1413 comp = ibuf[0]; 1414 for (i = 0, index = 1; i < length; i++) { 1415 if (comp == 16) { 1416 buf4c[i] = ibuf[index++] << 8; 1417 } else { 1418 buf4c[i] = 0; 1419 } 1420 if (index < length) { 1421 buf4c[i] |= ibuf[index++]; 1422 } 1423 } 1424 (void) wcstombs((char *)obuf, buf4c, 128); 1425 } 1426 1427 1428 /* ------------ Routines to print basic structures Part 1 ---------------- */ 1429 1430 1431 1432 void 1433 print_charspec(FILE *fout, char *name, struct charspec *cspec) 1434 { 1435 int i = 0; 1436 1437 (void) fprintf(fout, 1438 "%s : %x - \"", name, cspec->cs_type); 1439 for (i = 0; i < 63; i++) { 1440 (void) fprintf(fout, 1441 "%c", cspec->cs_info[i]); 1442 } 1443 (void) fprintf(fout, "\n"); 1444 } 1445 1446 /* ARGSUSED */ 1447 void 1448 print_dstring(FILE *fout, char *name, uint16_t cset, char *bufc, uint8_t length) 1449 { 1450 int8_t bufmb[1024]; 1451 1452 ud_convert2local(bufc, bufmb, length); 1453 1454 (void) fprintf(fout, 1455 "%s %s\n", name, bufmb); 1456 } 1457 1458 void 1459 set_dstring(dstring_t *dp, char *cp, int32_t len) 1460 { 1461 int32_t length; 1462 1463 bzero(dp, len); 1464 length = strlen(cp); 1465 if (length > len - 1) { 1466 length = len - 1; 1467 } 1468 (void) strncpy(dp, cp, length); 1469 dp[len - 1] = length; 1470 } 1471 1472 void 1473 print_tstamp(FILE *fout, char *name, tstamp_t *ts) 1474 { 1475 (void) fprintf(fout, "%s tz : %d yr : %d mo : %d da : %d " 1476 "Time : %d : %d : %d : %d : %d : %d\n", name, 1477 SWAP_16(ts->ts_tzone), SWAP_16(ts->ts_year), ts->ts_month, 1478 ts->ts_day, ts->ts_hour, ts->ts_min, ts->ts_sec, ts->ts_csec, 1479 ts->ts_husec, ts->ts_usec); 1480 } 1481 1482 1483 1484 void 1485 make_regid(ud_handle_t h, struct regid *reg, char *id, int32_t type) 1486 { 1487 reg->reg_flags = 0; 1488 (void) strncpy(reg->reg_id, id, 23); 1489 1490 if (type == REG_DOM_ID) { 1491 struct dom_id_suffix *dis; 1492 1493 /* LINTED */ 1494 dis = (struct dom_id_suffix *)reg->reg_ids; 1495 dis->dis_udf_revison = SWAP_16(h->udfs.ma_write); 1496 dis->dis_domain_flags = 0; 1497 1498 } else if (type == REG_UDF_ID) { 1499 struct udf_id_suffix *uis; 1500 1501 /* LINTED */ 1502 uis = (struct udf_id_suffix *)reg->reg_ids; 1503 uis->uis_udf_revision = SWAP_16(h->udfs.ma_write); 1504 uis->uis_os_class = OS_CLASS_UNIX; 1505 uis->uis_os_identifier = OS_IDENTIFIER_SOLARIS; 1506 } else if (type == REG_UDF_II) { 1507 struct impl_id_suffix *iis; 1508 1509 iis = (struct impl_id_suffix *)reg->reg_ids; 1510 iis->iis_os_class = OS_CLASS_UNIX; 1511 iis->iis_os_identifier = OS_IDENTIFIER_SOLARIS; 1512 } 1513 } 1514 1515 void 1516 print_regid(FILE *fout, char *name, struct regid *reg, int32_t type) 1517 { 1518 (void) fprintf(fout, "%s : 0x%x : \"%s\" :", 1519 name, reg->reg_flags, reg->reg_id); 1520 1521 if (type == REG_DOM_ID) { 1522 struct dom_id_suffix *dis; 1523 1524 /* LINTED */ 1525 dis = (struct dom_id_suffix *)reg->reg_ids; 1526 (void) fprintf(fout, " 0x%x : %s : %s\n", 1527 SWAP_16(dis->dis_udf_revison), 1528 (dis->dis_domain_flags & PROTECT_SOFT_WRITE) ? 1529 "HW Protect" : "No HW Write Protect", 1530 (dis->dis_domain_flags & PROTECT_HARD_WRITE) ? 1531 "SW Protect" : "No SW Protect"); 1532 } else if (type == REG_UDF_ID) { 1533 struct udf_id_suffix *uis; 1534 1535 /* LINTED */ 1536 uis = (struct udf_id_suffix *)reg->reg_ids; 1537 (void) fprintf(fout, 1538 " 0x%x : OS Class 0x%x : OS Identifier 0x%x\n", 1539 SWAP_16(uis->uis_udf_revision), 1540 uis->uis_os_class, uis->uis_os_identifier); 1541 } else { 1542 struct impl_id_suffix *iis; 1543 1544 iis = (struct impl_id_suffix *)reg->reg_ids; 1545 (void) fprintf(fout, 1546 " OS Class 0x%x : OS Identifier 0x%x\n", 1547 iis->iis_os_class, iis->iis_os_identifier); 1548 } 1549 } 1550 1551 #ifdef OLD 1552 void 1553 print_regid(FILE *fout, char *name, struct regid *reg) 1554 { 1555 (void) fprintf(fout, "%s : 0x%x : \"%s\" :", 1556 name, reg->reg_flags, reg->reg_id); 1557 1558 if (strncmp(reg->reg_id, "*OSTA UDF Compliant", 19) == 0) { 1559 (void) fprintf(fout, " 0x%x : %s : %s\n", 1560 reg->reg_ids[0] | (reg->reg_ids[1] << 8), 1561 (reg->reg_ids[2] & 1) ? 1562 "HW Protect" : "No HW Write Protect", 1563 (reg->reg_ids[2] & 2) ? 1564 "SW Protect" : "No SW Protect"); 1565 } else if ((strncmp(reg->reg_id, "*UDF Virtual Partition", 22) == 0) || 1566 (strncmp(reg->reg_id, "*UDF Sparable Partition", 23) == 0) || 1567 (strncmp(reg->reg_id, "*UDF Virtual Alloc Tbl", 22) == 0) || 1568 (strncmp(reg->reg_id, "*UDF Sparing Table", 18) == 0)) { 1569 (void) fprintf(fout, 1570 " 0x%x : OS Class 0x%x : OS Identifier 0x%x\n", 1571 reg->reg_ids[0] | (reg->reg_ids[1] << 8), 1572 reg->reg_ids[2], reg->reg_ids[3]); 1573 } else { 1574 (void) fprintf(fout, 1575 " OS Class 0x%x : OS Identifier 0x%x\n", 1576 reg->reg_ids[0], reg->reg_ids[1]); 1577 } 1578 } 1579 #endif 1580 1581 1582 /* ------------ Routines to print basic structures Part 2 ---------------- */ 1583 /* 1584 * Part 2 1585 * This part is OS specific and is currently 1586 * not supported 1587 */ 1588 1589 /* ------------ Routines to print basic structures Part 3 ---------------- */ 1590 1591 void 1592 print_ext_ad(FILE *fout, char *name, struct extent_ad *ead) 1593 { 1594 (void) fprintf(fout, 1595 "%s EAD Len %x Loc %x\n", 1596 name, SWAP_32(ead->ext_len), SWAP_32(ead->ext_loc)); 1597 } 1598 1599 void 1600 print_tag(FILE *fout, struct tag *tag) 1601 { 1602 (void) fprintf(fout, 1603 "tag_id : %x ver : %x cksum : %x " 1604 "sno : %x crc : %x crc_len : %x loc : %x\n", 1605 SWAP_16(tag->tag_id), SWAP_16(tag->tag_desc_ver), 1606 tag->tag_cksum, SWAP_16(tag->tag_sno), 1607 SWAP_16(tag->tag_crc), SWAP_16(tag->tag_crc_len), 1608 SWAP_32(tag->tag_loc)); 1609 } 1610 1611 1612 void 1613 print_pvd(FILE *fout, struct pri_vol_desc *pvd) 1614 { 1615 (void) fprintf(fout, 1616 "\n\t\t\tPrimary Volume Descriptor\n"); 1617 print_tag(fout, &pvd->pvd_tag); 1618 (void) fprintf(fout, "vdsn : %x vdn : %x\n", 1619 SWAP_32(pvd->pvd_vdsn), SWAP_32(pvd->pvd_pvdn)); 1620 print_dstring(fout, "volid : ", pvd->pvd_desc_cs.cs_type, 1621 pvd->pvd_vol_id, 32); 1622 (void) fprintf(fout, 1623 "vsn : %x mvsn : %x il : %x mil :" 1624 " %x csl : %x mcsl %x\n", 1625 SWAP_16(pvd->pvd_vsn), SWAP_16(pvd->pvd_mvsn), 1626 SWAP_16(pvd->pvd_il), SWAP_16(pvd->pvd_mil), 1627 SWAP_32(pvd->pvd_csl), SWAP_32(pvd->pvd_mcsl)); 1628 print_dstring(fout, "vsid :", pvd->pvd_desc_cs.cs_type, 1629 pvd->pvd_vsi, 128); 1630 print_charspec(fout, "desc_cs", &pvd->pvd_desc_cs); 1631 print_charspec(fout, "exp_cs", &pvd->pvd_exp_cs); 1632 print_ext_ad(fout, "val ", &pvd->pvd_vol_abs); 1633 print_ext_ad(fout, "vcnl ", &pvd->pvd_vcn); 1634 print_regid(fout, "ai", &pvd->pvd_appl_id, REG_UDF_II); 1635 print_regid(fout, "ii", &pvd->pvd_ii, REG_UDF_II); 1636 (void) fprintf(fout, "pvdsl : %x flags : %x\n", 1637 SWAP_32(pvd->pvd_pvdsl), 1638 SWAP_16(pvd->pvd_flags)); 1639 } 1640 1641 void 1642 print_avd(FILE *fout, struct anch_vol_desc_ptr *avdp) 1643 { 1644 (void) fprintf(fout, 1645 "\n\t\t\tAnchor Volume Descriptor\n"); 1646 print_tag(fout, &avdp->avd_tag); 1647 print_ext_ad(fout, "Main Volume Descriptor Sequence : ", 1648 &avdp->avd_main_vdse); 1649 print_ext_ad(fout, "Reserve Volume Descriptor Sequence : ", 1650 &avdp->avd_res_vdse); 1651 } 1652 1653 void 1654 print_vdp(FILE *fout, struct vol_desc_ptr *vdp) 1655 { 1656 (void) fprintf(fout, 1657 "\n\t\t\tVolume Descriptor Pointer\n"); 1658 print_tag(fout, &vdp->vdp_tag); 1659 (void) fprintf(fout, "vdsn : %x ", 1660 SWAP_32(vdp->vdp_vdsn)); 1661 print_ext_ad(fout, "vdse ", &vdp->vdp_nvdse); 1662 } 1663 1664 void 1665 print_iuvd(FILE *fout, struct iuvd_desc *iuvd) 1666 { 1667 (void) fprintf(fout, 1668 "\n\t\t\tImplementation Use Volume Descriptor\n"); 1669 print_tag(fout, &iuvd->iuvd_tag); 1670 (void) fprintf(fout, 1671 "vdsn : %x ", SWAP_32(iuvd->iuvd_vdsn)); 1672 print_regid(fout, "Impl Id : ", &iuvd->iuvd_ii, REG_UDF_ID); 1673 print_charspec(fout, "cset ", &iuvd->iuvd_cset); 1674 print_dstring(fout, "lvi : ", iuvd->iuvd_cset.cs_type, 1675 iuvd->iuvd_lvi, 128); 1676 print_dstring(fout, "ifo1 : ", iuvd->iuvd_cset.cs_type, 1677 iuvd->iuvd_ifo1, 36); 1678 print_dstring(fout, "ifo2 : ", iuvd->iuvd_cset.cs_type, 1679 iuvd->iuvd_ifo2, 36); 1680 print_dstring(fout, "ifo3 : ", iuvd->iuvd_cset.cs_type, 1681 iuvd->iuvd_ifo3, 36); 1682 1683 print_regid(fout, "iid ", &iuvd->iuvd_iid, REG_UDF_II); 1684 } 1685 1686 void 1687 print_part(FILE *fout, struct part_desc *pd) 1688 { 1689 (void) fprintf(fout, 1690 "\n\t\t\tPartition Descriptor\n"); 1691 print_tag(fout, &pd->pd_tag); 1692 (void) fprintf(fout, 1693 "vdsn : %x flags : %x num : %x ", 1694 SWAP_32(pd->pd_vdsn), 1695 SWAP_16(pd->pd_pflags), 1696 SWAP_16(pd->pd_pnum)); 1697 print_regid(fout, "contents ", &pd->pd_pcontents, REG_UDF_II); 1698 /* LINTED */ 1699 print_phdr(fout, (struct phdr_desc *)(&pd->pd_pc_use)); 1700 (void) fprintf(fout, 1701 "acc : %x start : %x length : %x ", 1702 SWAP_32(pd->pd_acc_type), 1703 SWAP_32(pd->pd_part_start), 1704 SWAP_32(pd->pd_part_length)); 1705 print_regid(fout, "Impl Id : ", &pd->pd_ii, REG_UDF_II); 1706 } 1707 1708 void 1709 print_lvd(FILE *fout, struct log_vol_desc *lvd) 1710 { 1711 (void) fprintf(fout, 1712 "\n\t\t\tLogical Volume Descriptor\n"); 1713 print_tag(fout, &lvd->lvd_tag); 1714 (void) fprintf(fout, 1715 "vdsn : %x ", SWAP_32(lvd->lvd_vdsn)); 1716 print_charspec(fout, "Desc Char Set ", &lvd->lvd_desc_cs); 1717 print_dstring(fout, "lvid : ", lvd->lvd_desc_cs.cs_type, 1718 lvd->lvd_lvid, 28); 1719 (void) fprintf(fout, 1720 "lbsize : %x ", 1721 SWAP_32(lvd->lvd_log_bsize)); 1722 print_regid(fout, "Dom Id", &lvd->lvd_dom_id, REG_DOM_ID); 1723 print_long_ad(fout, "lvcu", &lvd->lvd_lvcu); 1724 (void) fprintf(fout, 1725 "mtlen : %x nmaps : %x ", 1726 SWAP_32(lvd->lvd_mtbl_len), 1727 SWAP_32(lvd->lvd_num_pmaps)); 1728 print_regid(fout, "Impl Id : ", &lvd->lvd_ii, REG_UDF_II); 1729 print_ext_ad(fout, "Int Seq", &lvd->lvd_int_seq_ext); 1730 print_pmaps(fout, lvd->lvd_pmaps, SWAP_32(lvd->lvd_num_pmaps)); 1731 } 1732 1733 void 1734 print_usd(FILE *fout, struct unall_spc_desc *ua) 1735 { 1736 int32_t i, count; 1737 1738 (void) fprintf(fout, 1739 "\n\t\t\tUnallocated Space Descriptor\n"); 1740 print_tag(fout, &ua->ua_tag); 1741 count = SWAP_32(ua->ua_nad); 1742 (void) fprintf(fout, 1743 "vdsn : %x nad : %x\n", 1744 SWAP_32(ua->ua_vdsn), count); 1745 for (i = 0; i < count; i++) { 1746 (void) fprintf(fout, 1747 "loc : %x len : %x\n", 1748 SWAP_32(ua->ua_al_dsc[i * 2]), 1749 SWAP_32(ua->ua_al_dsc[i * 2 + 1])); 1750 } 1751 } 1752 1753 void 1754 print_lvid(FILE *fout, struct log_vol_int_desc *lvid) 1755 { 1756 int32_t i, count; 1757 caddr_t addr; 1758 struct lvid_iu *liu; 1759 1760 (void) fprintf(fout, 1761 "\n\t\t\tLogical Volume Integrity Descriptor\n"); 1762 print_tag(fout, &lvid->lvid_tag); 1763 print_tstamp(fout, "Rec TM ", &lvid->lvid_tstamp); 1764 if (SWAP_32(lvid->lvid_int_type) == 0) { 1765 (void) fprintf(fout, 1766 "int_typ : Open\n"); 1767 } else if (SWAP_32(lvid->lvid_int_type) == 1) { 1768 (void) fprintf(fout, "int_typ : Closed\n"); 1769 } else { 1770 (void) fprintf(fout, "int_typ : Unknown\n"); 1771 } 1772 print_ext_ad(fout, "Nie ", &lvid->lvid_nie); 1773 count = SWAP_32(lvid->lvid_npart); 1774 (void) fprintf(fout, 1775 "Uniq : %llx npart : %x liu : %x\n", 1776 SWAP_64(lvid->lvid_lvcu.lvhd_uniqid), 1777 count, SWAP_32(lvid->lvid_liu)); 1778 for (i = 0; i < count; i++) { 1779 (void) fprintf(fout, 1780 "Part : %x Free : %x Size : %x\n", 1781 i, SWAP_32(lvid->lvid_fst[i]), 1782 SWAP_32(lvid->lvid_fst[count + i])); 1783 } 1784 1785 addr = (caddr_t)lvid->lvid_fst; 1786 /* LINTED */ 1787 liu = (struct lvid_iu *)(addr + 2 * count * 4); 1788 print_regid(fout, "Impl Id :", &liu->lvidiu_regid, REG_UDF_II); 1789 (void) fprintf(fout, 1790 "nfiles : %x ndirs : %x miread : %x" 1791 " miwrite : %x mawrite : %x\n", 1792 SWAP_32(liu->lvidiu_nfiles), SWAP_32(liu->lvidiu_ndirs), 1793 SWAP_16(liu->lvidiu_mread), SWAP_16(liu->lvidiu_mwrite), 1794 SWAP_16(liu->lvidiu_maxwr)); 1795 } 1796 1797 1798 /* ------------ Routines to print basic structures Part 4 ---------------- */ 1799 1800 void 1801 print_fsd(FILE *fout, ud_handle_t h, struct file_set_desc *fsd) 1802 { 1803 (void) fprintf(fout, 1804 "\n\t\t\tFile Set Descriptor\n"); 1805 1806 print_tag(fout, &fsd->fsd_tag); 1807 print_tstamp(fout, "Rec TM ", &fsd->fsd_time); 1808 (void) fprintf(fout, 1809 "ilvl : %x milvl : %x csl : %x" 1810 " mcsl : %x fsn : %x fsdn : %x\n", 1811 SWAP_16(fsd->fsd_ilevel), SWAP_16(fsd->fsd_mi_level), 1812 SWAP_32(fsd->fsd_cs_list), SWAP_32(fsd->fsd_mcs_list), 1813 SWAP_32(fsd->fsd_fs_no), SWAP_32(fsd->fsd_fsd_no)); 1814 print_charspec(fout, "ID CS ", &fsd->fsd_lvidcs); 1815 print_dstring(fout, "lvi : ", fsd->fsd_lvidcs.cs_type, 1816 fsd->fsd_lvid, 128); 1817 print_charspec(fout, "ID CS ", &fsd->fsd_fscs); 1818 print_dstring(fout, "fsi : ", fsd->fsd_lvidcs.cs_type, 1819 fsd->fsd_fsi, 32); 1820 print_dstring(fout, "cfi : ", fsd->fsd_lvidcs.cs_type, 1821 fsd->fsd_cfi, 32); 1822 print_dstring(fout, "afi : ", fsd->fsd_lvidcs.cs_type, 1823 fsd->fsd_afi, 32); 1824 print_long_ad(fout, "Ricb ", &fsd->fsd_root_icb); 1825 print_regid(fout, "DI ", &fsd->fsd_did, REG_DOM_ID); 1826 print_long_ad(fout, "Next Fsd ", &fsd->fsd_next); 1827 if (h->udfs.ecma_version == UD_ECMA_VER3) { 1828 print_long_ad(fout, "System Stream Directory ICB ", 1829 &fsd->fsd_next); 1830 } 1831 } 1832 1833 void 1834 print_phdr(FILE *fout, struct phdr_desc *ph) 1835 { 1836 print_short_ad(fout, "ust ", &ph->phdr_ust); 1837 print_short_ad(fout, "usb ", &ph->phdr_usb); 1838 print_short_ad(fout, "int ", &ph->phdr_it); 1839 print_short_ad(fout, "fst ", &ph->phdr_fst); 1840 print_short_ad(fout, "fsh ", &ph->phdr_fsb); 1841 } 1842 1843 void 1844 print_fid(FILE *fout, struct file_id *fid) 1845 { 1846 int32_t i; 1847 uint8_t *addr; 1848 1849 (void) fprintf(fout, 1850 "File Identifier Descriptor\n"); 1851 print_tag(fout, &fid->fid_tag); 1852 (void) fprintf(fout, "fvn : %x fc : %x length : %x ", 1853 fid->fid_ver, fid->fid_flags, fid->fid_idlen); 1854 print_long_ad(fout, "ICB", &fid->fid_icb); 1855 addr = &fid->fid_spec[SWAP_16(fid->fid_iulen)]; 1856 (void) fprintf(fout, "iulen : %x comp : %x name : ", 1857 SWAP_16(fid->fid_iulen), *addr); 1858 addr++; 1859 for (i = 0; i < fid->fid_idlen; i++) { 1860 (void) fprintf(fout, "%c", *addr++); 1861 } 1862 (void) fprintf(fout, "\n"); 1863 } 1864 1865 void 1866 print_aed(FILE *fout, struct alloc_ext_desc *aed) 1867 { 1868 (void) fprintf(fout, 1869 "Allocation Extent Descriptor\n"); 1870 print_tag(fout, &aed->aed_tag); 1871 (void) fprintf(fout, "prev ael loc : %x laed : %x\n", 1872 SWAP_32(aed->aed_rev_ael), SWAP_32(aed->aed_len_aed)); 1873 } 1874 1875 static char *ftype[] = { 1876 "NON", "USE", "PIE", "IE", 1877 "DIR", "REG", "BDEV", "CDEV", 1878 "EATT", "FIFO", "SOCK", "TERM", 1879 "SYML", "SDIR" 1880 }; 1881 1882 void 1883 print_icb_tag(FILE *fout, struct icb_tag *itag) 1884 { 1885 (void) fprintf(fout, 1886 "prnde : %x strat : %x param : %x max_ent %x\n", 1887 SWAP_32(itag->itag_prnde), SWAP_16(itag->itag_strategy), 1888 SWAP_16(itag->itag_param), SWAP_16(itag->itag_max_ent)); 1889 (void) fprintf(fout, 1890 "ftype : %s prn : %x loc : %x flags : %x\n", 1891 (itag->itag_ftype >= 14) ? ftype[0] : ftype[itag->itag_ftype], 1892 SWAP_16(itag->itag_lb_prn), 1893 SWAP_32(itag->itag_lb_loc), SWAP_16(itag->itag_flags)); 1894 } 1895 1896 1897 void 1898 print_ie(FILE *fout, struct indirect_entry *ie) 1899 { 1900 (void) fprintf(fout, 1901 "Indirect Entry\n"); 1902 print_tag(fout, &ie->ie_tag); 1903 print_icb_tag(fout, &ie->ie_icb_tag); 1904 print_long_ad(fout, "ICB", &ie->ie_indirecticb); 1905 } 1906 1907 void 1908 print_td(FILE *fout, struct term_desc *td) 1909 { 1910 (void) fprintf(fout, 1911 "Terminating Descriptor\n"); 1912 print_tag(fout, &td->td_tag); 1913 } 1914 1915 void 1916 print_fe(FILE *fout, struct file_entry *fe) 1917 { 1918 (void) fprintf(fout, 1919 "File Entry\n"); 1920 print_tag(fout, &fe->fe_tag); 1921 print_icb_tag(fout, &fe->fe_icb_tag); 1922 (void) fprintf(fout, 1923 "uid : %x gid : %x perms : %x nlnk : %x\n", 1924 SWAP_32(fe->fe_uid), SWAP_32(fe->fe_gid), 1925 SWAP_32(fe->fe_perms), SWAP_16(fe->fe_lcount)); 1926 (void) fprintf(fout, 1927 "rec_for : %x rec_dis : %x rec_len : %x " 1928 "sz : %llx blks : %llx\n", 1929 fe->fe_rec_for, fe->fe_rec_dis, SWAP_32(fe->fe_rec_len), 1930 SWAP_64(fe->fe_info_len), SWAP_64(fe->fe_lbr)); 1931 print_tstamp(fout, "ctime ", &fe->fe_acc_time); 1932 print_tstamp(fout, "mtime ", &fe->fe_mod_time); 1933 print_tstamp(fout, "atime ", &fe->fe_attr_time); 1934 (void) fprintf(fout, 1935 "ckpoint : %x ", SWAP_32(fe->fe_ckpoint)); 1936 print_long_ad(fout, "ICB", &fe->fe_ea_icb); 1937 print_regid(fout, "impl", &fe->fe_impl_id, REG_UDF_II); 1938 (void) fprintf(fout, 1939 "uniq_id : %llx len_ear : %x len_adesc %x\n", 1940 SWAP_64(fe->fe_uniq_id), SWAP_32(fe->fe_len_ear), 1941 SWAP_32(fe->fe_len_adesc)); 1942 } 1943 1944 void 1945 print_pmaps(FILE *fout, uint8_t *addr, int32_t count) 1946 { 1947 struct pmap_hdr *hdr; 1948 struct pmap_typ1 *map1; 1949 struct pmap_typ2 *map2; 1950 1951 while (count--) { 1952 hdr = (struct pmap_hdr *)addr; 1953 switch (hdr->maph_type) { 1954 case 1 : 1955 /* LINTED */ 1956 map1 = (struct pmap_typ1 *)hdr; 1957 (void) fprintf(fout, "Map type 1 "); 1958 (void) fprintf(fout, "VSN %x prn %x\n", 1959 SWAP_16(map1->map1_vsn), 1960 SWAP_16(map1->map1_pn)); 1961 break; 1962 case 2 : 1963 /* LINTED */ 1964 map2 = (struct pmap_typ2 *)hdr; 1965 (void) fprintf(fout, "Map type 2 "); 1966 (void) fprintf(fout, "VSN %x prn %x\n", 1967 SWAP_16(map2->map2_vsn), 1968 SWAP_16(map2->map2_pn)); 1969 print_regid(fout, "Partition Type Identifier", 1970 &map2->map2_pti, REG_UDF_ID); 1971 break; 1972 default : 1973 (void) fprintf(fout, "unknown map type\n"); 1974 } 1975 addr += hdr->maph_length; 1976 } 1977 } 1978 1979 1980 1981 void 1982 print_short_ad(FILE *fout, char *name, struct short_ad *sad) 1983 { 1984 (void) fprintf(fout, 1985 "%s loc : %x len : %x\n", name, 1986 SWAP_32(sad->sad_ext_loc), SWAP_32(sad->sad_ext_len)); 1987 } 1988 1989 void 1990 print_long_ad(FILE *fout, char *name, struct long_ad *lad) 1991 { 1992 (void) fprintf(fout, 1993 "%s prn : %x loc : %x len : %x\n", name, 1994 SWAP_16(lad->lad_ext_prn), SWAP_32(lad->lad_ext_loc), 1995 SWAP_32(lad->lad_ext_len)); 1996 } 1997