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.
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.
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]
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
35 #include <sys/types.h>
36 #include <sys/int_types.h>
41 #include <sys/param.h>
42 #include <sys/fs/udf_volume.h>
45 extern char *getfullrawname(char *);
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);
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);
63 ud_init(int fd
, ud_handle_t
*hp
)
67 if ((h
= calloc(1, sizeof (struct ud_handle
))) == NULL
) {
76 ud_fini(ud_handle_t h
)
83 ud_open_dev(ud_handle_t h
, char *special
, uint32_t flags
)
86 struct stat i_stat
, r_stat
;
88 (void) bzero(&i_stat
, sizeof (struct stat
));
89 (void) bzero(&r_stat
, sizeof (struct stat
));
92 * Get the stat structure
94 if (stat(special
, &i_stat
) < 0) {
98 if ((i_stat
.st_mode
& S_IFMT
) == S_IFCHR
) {
101 * If Raw deivce is given use it as it is
105 } else if ((i_stat
.st_mode
& S_IFMT
) == S_IFBLK
) {
108 * Block device try to convert to raw device
111 temp
= getfullrawname(special
);
114 * Stat the converted device name and verify
115 * both the raw and block device belong to
118 if (stat(temp
, &r_stat
) < 0) {
121 if (((r_stat
.st_mode
& S_IFMT
) == S_IFBLK
) ||
122 (r_stat
.st_rdev
!= i_stat
.st_rdev
)) {
130 * Now finally open the device
132 h
->fd
= open(temp
, flags
);
139 ud_close_dev(ud_handle_t h
)
142 * Too simple Just close it
148 ud_read_dev(ud_handle_t h
, uint64_t offset
, uint8_t *buf
, uint32_t count
)
151 * Seek to the given offset
153 if (lseek(h
->fd
, offset
, SEEK_SET
) == -1) {
158 * Read the required number of bytes
160 if (read(h
->fd
, buf
, count
) != count
) {
167 ud_write_dev(ud_handle_t h
, uint64_t offset
, uint8_t *buf
, uint32_t count
)
170 * Seek to the given offset
172 if (lseek(h
->fd
, offset
, SEEK_SET
) == -1) {
177 * Read the appropriate number of bytes
179 if (write(h
->fd
, buf
, count
) != count
) {
185 /* ----- BEGIN Read and translate the on disk VDS to IN CORE format -------- */
188 ud_fill_udfs_info(ud_handle_t h
)
190 struct anch_vol_desc_ptr
*avdp
= NULL
;
193 if (ioctl(h
->fd
, CDROMREADOFFSET
, &offset
) == -1) {
197 h
->udfs
.flags
= INVALID_UDFS
;
199 h
->udfs
.ecma_version
= ud_get_ecma_ver(h
, offset
);
200 if (h
->udfs
.ecma_version
== UD_ECMA_UNKN
) {
204 h
->udfs
.lbsize
= ud_get_fs_bsize(h
, offset
, &h
->udfs
.avdp_loc
);
205 if (h
->udfs
.lbsize
== 0) {
209 h
->udfs
.avdp_len
= lb_roundup(512, h
->udfs
.lbsize
);
212 if ((avdp
= (struct anch_vol_desc_ptr
*)
213 malloc(h
->udfs
.lbsize
)) == NULL
) {
216 if (ud_read_dev(h
, h
->udfs
.avdp_loc
* h
->udfs
.lbsize
,
217 (uint8_t *)avdp
, h
->udfs
.lbsize
) != 0) {
221 if (ud_verify_tag(h
, &avdp
->avd_tag
, UD_ANCH_VOL_DESC
,
222 h
->udfs
.avdp_loc
, 1, 0) != 0) {
227 h
->udfs
.mvds_loc
= SWAP_32(avdp
->avd_main_vdse
.ext_loc
);
228 h
->udfs
.mvds_len
= SWAP_32(avdp
->avd_main_vdse
.ext_len
);
230 h
->udfs
.rvds_loc
= SWAP_32(avdp
->avd_res_vdse
.ext_loc
);
231 h
->udfs
.rvds_len
= SWAP_32(avdp
->avd_res_vdse
.ext_len
);
236 * get information from mvds and rvds
238 if (ud_parse_fill_vds(h
, &h
->udfs
.mvds
,
239 h
->udfs
.mvds_loc
, h
->udfs
.mvds_len
) == 0) {
240 h
->udfs
.flags
|= VALID_MVDS
;
242 if (ud_parse_fill_vds(h
, &h
->udfs
.rvds
,
243 h
->udfs
.rvds_loc
, h
->udfs
.rvds_len
) == 0) {
244 h
->udfs
.flags
|= VALID_RVDS
;
247 if ((h
->udfs
.flags
& (VALID_MVDS
| VALID_RVDS
)) == 0) {
252 * If we are here we have
253 * a valid Volume Descriptor Seqence
254 * Read and understand lvd
256 if (h
->udfs
.flags
& VALID_MVDS
) {
257 if (ud_read_and_translate_lvd(h
, h
->udfs
.mvds
.lvd_loc
,
258 h
->udfs
.mvds
.lvd_len
) != 0) {
262 if (ud_read_and_translate_lvd(h
, h
->udfs
.rvds
.lvd_loc
,
263 h
->udfs
.rvds
.lvd_len
) != 0) {
268 h
->udfs
.flags
|= VALID_UDFS
;
274 ud_get_ecma_ver(ud_handle_t h
, uint32_t offset
)
279 struct nsr_desc
*ndsc
;
280 uint32_t ecma_ver
= UD_ECMA_UNKN
;
283 * Allocate a buffer of size UD_VOL_REC_BSZ
285 if ((buf
= (uint8_t *)malloc(UD_VOL_REC_BSZ
)) == NULL
) {
288 * Uh could not even allocate this much
294 * Start from 32k and keep reading 2k blocks we
295 * should be able to find NSR if we have one by 256 * 2k bytes
297 off
= offset
* 2048 + UD_VOL_REC_START
;
298 end_off
= offset
* 2048 + UD_VOL_REC_END
;
299 for (; off
< end_off
; off
+= UD_VOL_REC_BSZ
) {
301 if (ud_read_dev(h
, off
, buf
, UD_VOL_REC_BSZ
) == 0) {
303 ndsc
= (struct nsr_desc
*)buf
;
305 * Is this either NSR02 or NSR03
307 if ((ndsc
->nsr_str_type
== 0) &&
308 (ndsc
->nsr_ver
== 1) &&
309 (ndsc
->nsr_id
[0] == 'N') &&
310 (ndsc
->nsr_id
[1] == 'S') &&
311 (ndsc
->nsr_id
[2] == 'R') &&
312 (ndsc
->nsr_id
[3] == '0') &&
313 ((ndsc
->nsr_id
[4] == '2') ||
314 (ndsc
->nsr_id
[4] == '3'))) {
316 (void) strncpy((char *)h
->udfs
.ecma_id
,
317 (char *)ndsc
->nsr_id
, 5);
319 switch (ndsc
->nsr_id
[4]) {
325 ecma_ver
= UD_ECMA_VER2
;
332 ecma_ver
= UD_ECMA_VER3
;
347 static uint32_t last_block_index
[] = {0, 0, 256, 2, 2 + 256,
348 150, 150 + 256, 152, 152 + 256};
351 ud_get_fs_bsize(ud_handle_t h
, uint32_t offset
, uint32_t *avd_loc
)
354 int32_t index
, bsize
, shift
, end_index
;
355 uint32_t num_blocks
, sub_blk
;
357 struct anch_vol_desc_ptr
*avdp
;
359 if ((buf
= (uint8_t *)malloc(MAXBSIZE
)) == NULL
) {
364 * If we could figure out the last block
365 * search at 256, N, N - 256 blocks
366 * otherwise just check at 256
368 if (ud_get_num_blks(h
, &num_blocks
) != 0) {
372 end_index
= sizeof (last_block_index
) / 4;
375 for (index
= 0; index
< end_index
; index
++) {
376 sub_blk
= last_block_index
[index
];
379 * Start guessing from DEV_BSIZE to MAXBSIZE
381 for (bsize
= DEV_BSIZE
, shift
= 0;
382 bsize
<= MAXBSIZE
; bsize
<<= 1, shift
++) {
387 * Check if we atleast have 256 of bsize
388 * blocks on the device
390 if ((end_index
== 0) ||
391 (num_blocks
> (256 << shift
))) {
395 offset
* 2048 / bsize
;
398 offset
/ (bsize
/ 2048);
405 * Calculate the bsize avd block
408 (num_blocks
> (sub_blk
<< shift
))) {
409 *avd_loc
= (num_blocks
>> shift
) -
416 off
= (uint64_t)*avd_loc
* bsize
;
419 * Read bsize bytes at off
421 if (ud_read_dev(h
, off
, buf
, bsize
) != 0) {
426 * Check if we have a Anchor Volume Descriptor here
430 avdp
= (struct anch_vol_desc_ptr
*)buf
;
431 if (ud_verify_tag(h
, &avdp
->avd_tag
,
432 UD_ANCH_VOL_DESC
, *avd_loc
, 1, 0) != 0) {
440 if (bsize
> MAXBSIZE
) {
449 ud_parse_fill_vds(ud_handle_t h
, struct vds
*v
,
450 uint32_t vds_loc
, uint32_t vds_len
)
452 uint8_t *addr
, *taddr
, *eaddr
;
457 struct pri_vol_desc
*pvd
;
458 struct log_vol_desc
*lvd
;
459 struct vol_desc_ptr
*vds
;
460 struct unall_spc_desc
*usd
;
463 if ((addr
= (uint8_t *)malloc(vds_len
)) == NULL
) {
467 off
= vds_loc
* h
->udfs
.lbsize
;
468 if (ud_read_dev(h
, off
, addr
, vds_len
) != 0) {
472 for (taddr
= addr
, eaddr
= addr
+ h
->udfs
.mvds_len
; taddr
< eaddr
;
473 taddr
+= h
->udfs
.lbsize
, vds_loc
++) {
476 tag
= (struct tag
*)taddr
;
477 id
= SWAP_16(tag
->tag_id
);
479 * If you cannot verify the tag just skip it
480 * This is not a fatal error
482 if (ud_verify_tag(h
, tag
, id
, vds_loc
, 1, 0) != 0) {
486 case UD_PRI_VOL_DESC
:
489 * Primary Volume Descriptor
492 pvd
= (struct pri_vol_desc
*)taddr
;
493 if ((v
->pvd_len
== 0) ||
494 (SWAP_32(pvd
->pvd_vdsn
) > v
->pvd_vdsn
)) {
495 v
->pvd_vdsn
= SWAP_32(pvd
->pvd_vdsn
);
496 v
->pvd_loc
= vds_loc
;
497 v
->pvd_len
= h
->udfs
.lbsize
;
500 case UD_VOL_DESC_PTR
:
503 * Curent sequence is continued from
504 * the location pointed by vdp
507 vds
= (struct vol_desc_ptr
*)taddr
;
509 if (SWAP_32(vds
->vdp_nvdse
.ext_len
) != 0) {
510 vds_loc
= SWAP_32(vds
->vdp_nvdse
.ext_loc
);
511 vds_len
= SWAP_32(vds
->vdp_nvdse
.ext_len
);
516 case UD_IMPL_USE_DESC
:
519 * Implementation Use Volume Descriptor
521 v
->iud_loc
= vds_loc
;
522 v
->iud_len
= lb_roundup(512, h
->udfs
.lbsize
);
527 struct phdr_desc
*ph
;
528 struct part_desc
*pd
;
531 * Partition Descriptor
534 pd
= (struct part_desc
*)taddr
;
536 for (i
= 0; i
< h
->n_parts
; i
++) {
539 if ((SWAP_16(pd
->pd_pnum
) ==
541 (SWAP_32(pd
->pd_vdsn
) >
547 v
->part_loc
[i
] = vds_loc
;
549 lb_roundup(512, h
->udfs
.lbsize
);
552 p
->udp_number
= SWAP_16(pd
->pd_pnum
);
553 p
->udp_seqno
= SWAP_32(pd
->pd_vdsn
);
554 p
->udp_access
= SWAP_32(pd
->pd_acc_type
);
555 p
->udp_start
= SWAP_32(pd
->pd_part_start
);
556 p
->udp_length
= SWAP_32(pd
->pd_part_length
);
559 ph
= (struct phdr_desc
*)pd
->pd_pc_use
;
560 if (ph
->phdr_ust
.sad_ext_len
) {
561 p
->udp_flags
= UDP_SPACETBLS
;
562 p
->udp_unall_loc
= SWAP_32(ph
->phdr_ust
.sad_ext_loc
);
563 p
->udp_unall_len
= SWAP_32(ph
->phdr_ust
.sad_ext_len
);
564 p
->udp_freed_loc
= SWAP_32(ph
->phdr_fst
.sad_ext_loc
);
565 p
->udp_freed_len
= SWAP_32(ph
->phdr_fst
.sad_ext_len
);
567 p
->udp_flags
= UDP_BITMAPS
;
568 p
->udp_unall_loc
= SWAP_32(ph
->phdr_usb
.sad_ext_loc
);
569 p
->udp_unall_len
= SWAP_32(ph
->phdr_usb
.sad_ext_len
);
570 p
->udp_freed_loc
= SWAP_32(ph
->phdr_fsb
.sad_ext_loc
);
571 p
->udp_freed_len
= SWAP_32(ph
->phdr_fsb
.sad_ext_len
);
574 if (i
== h
->n_parts
) {
579 case UD_LOG_VOL_DESC
:
582 * Logical Volume Descriptor
585 lvd
= (struct log_vol_desc
*)taddr
;
586 if ((v
->lvd_len
== 0) ||
587 (SWAP_32(lvd
->lvd_vdsn
) > v
->lvd_vdsn
)) {
588 v
->lvd_vdsn
= SWAP_32(lvd
->lvd_vdsn
);
589 v
->lvd_loc
= vds_loc
;
590 v
->lvd_len
= ((uint32_t)
591 &((struct log_vol_desc
*)0)->lvd_pmaps
);
593 lb_roundup(v
->lvd_len
, h
->udfs
.lbsize
);
596 case UD_UNALL_SPA_DESC
:
599 * Unallocated Space Descriptor
602 usd
= (struct unall_spc_desc
*)taddr
;
603 v
->usd_loc
= vds_loc
;
604 v
->usd_len
= ((uint32_t)
605 &((unall_spc_desc_t
*)0)->ua_al_dsc
) +
606 SWAP_32(usd
->ua_nad
) *
607 sizeof (struct extent_ad
);
608 v
->usd_len
= lb_roundup(v
->usd_len
, h
->udfs
.lbsize
);
612 * Success fully completed
617 * If you donot undetstand any tag just skip
618 * it. This is not a fatal error
626 if ((v
->pvd_len
== 0) ||
627 (v
->part_len
[0] == 0) ||
636 ud_read_and_translate_lvd(ud_handle_t h
, uint32_t lvd_loc
, uint32_t lvd_len
)
640 uint32_t fsd_loc
, fsd_len
;
641 uint32_t lvds_loc
, lvds_len
;
643 struct log_vol_desc
*lvd
= NULL
;
645 int32_t max_maps
, i
, mp_sz
, index
;
648 struct pmap_typ1
*typ1
;
649 struct pmap_typ2
*typ2
;
655 if ((lvd
= (struct log_vol_desc
*)
656 malloc(lvd_len
)) == NULL
) {
660 off
= lvd_loc
* h
->udfs
.lbsize
;
661 if (ud_read_dev(h
, off
, (uint8_t *)lvd
, lvd_len
) != 0) {
666 if (ud_verify_tag(h
, &lvd
->lvd_tag
, UD_LOG_VOL_DESC
,
667 lvd_loc
, 1, 0) != 0) {
675 max_maps
= SWAP_32(lvd
->lvd_num_pmaps
);
676 ph
= (struct pmap_hdr
*)lvd
->lvd_pmaps
;
677 for (h
->n_maps
= index
= 0; index
< max_maps
; index
++) {
678 m
= &h
->maps
[h
->n_maps
];
679 switch (ph
->maph_type
) {
683 typ1
= (struct pmap_typ1
*)ph
;
685 m
->udm_flags
= UDM_MAP_NORM
;
686 m
->udm_vsn
= SWAP_16(typ1
->map1_vsn
);
687 m
->udm_pn
= SWAP_16(typ1
->map1_pn
);
694 typ2
= (struct pmap_typ2
*)ph
;
696 if (strncmp(typ2
->map2_pti
.reg_id
,
697 UDF_VIRT_PART
, 23) == 0) {
699 m
->udm_flags
= UDM_MAP_VPM
;
700 m
->udm_vsn
= SWAP_16(typ2
->map2_vsn
);
701 m
->udm_pn
= SWAP_16(typ2
->map2_pn
);
702 } else if (strncmp(typ2
->map2_pti
.reg_id
,
703 UDF_SPAR_PART
, 23) == 0) {
705 if ((SWAP_16(typ2
->map2_pl
) != 32) ||
706 (typ2
->map2_nst
< 1) ||
707 (typ2
->map2_nst
> 4)) {
710 m
->udm_flags
= UDM_MAP_SPM
;
711 m
->udm_vsn
= SWAP_16(typ2
->map2_vsn
);
712 m
->udm_pn
= SWAP_16(typ2
->map2_pn
);
714 m
->udm_plen
= SWAP_16(typ2
->map2_pl
);
715 m
->udm_nspm
= typ2
->map2_nst
;
716 m
->udm_spsz
= SWAP_32(typ2
->map2_sest
);
718 mp_sz
= lb_roundup(m
->udm_spsz
, h
->udfs
.lbsize
);
720 if ((addr
= malloc(mp_sz
* m
->udm_nspm
)) ==
725 for (i
= 0; i
< m
->udm_nspm
; i
++) {
727 SWAP_32(typ2
->map2_st
[index
]);
728 m
->udm_spaddr
[i
] = addr
+ i
* mp_sz
;
730 off
= m
->udm_loc
[i
] * h
->udfs
.lbsize
;
731 if (ud_read_dev(h
, off
,
732 (uint8_t *)m
->udm_spaddr
[i
],
734 m
->udm_spaddr
[i
] = NULL
;
743 ph
= (struct pmap_hdr
*)(((uint8_t *)h
) + ph
->maph_length
);
746 lvds_loc
= SWAP_32(lvd
->lvd_int_seq_ext
.ext_loc
);
747 lvds_len
= SWAP_32(lvd
->lvd_int_seq_ext
.ext_len
);
749 fsd_prn
= SWAP_16(lvd
->lvd_lvcu
.lad_ext_prn
);
750 fsd_loc
= SWAP_32(lvd
->lvd_lvcu
.lad_ext_loc
);
751 fsd_len
= SWAP_32(lvd
->lvd_lvcu
.lad_ext_len
);
756 * Get the latest LVID
758 if (ud_get_latest_lvid(h
, lvds_loc
, lvds_len
) != 0) {
762 if (ud_get_latest_fsd(h
, fsd_prn
, fsd_loc
, fsd_len
) != 0) {
770 ud_get_latest_lvid(ud_handle_t h
, uint32_t lvds_loc
, uint32_t lvds_len
)
772 uint8_t *addr
, *taddr
, *eaddr
;
776 struct log_vol_int_desc
*lvid
;
779 if ((addr
= (uint8_t *)malloc(lvds_len
)) == NULL
) {
783 off
= lvds_loc
* h
->udfs
.lbsize
;
784 if (ud_read_dev(h
, off
, addr
, lvds_len
) != 0) {
788 for (taddr
= addr
, eaddr
= addr
+ h
->udfs
.mvds_len
; taddr
< eaddr
;
789 taddr
+= h
->udfs
.lbsize
, lvds_loc
++) {
792 tag
= (struct tag
*)taddr
;
793 id
= SWAP_16(tag
->tag_id
);
795 * If you cannot verify the tag just skip it
796 * This is not a fatal error
798 if (ud_verify_tag(h
, tag
, id
, lvds_loc
, 1, 0) != 0) {
802 case UD_LOG_VOL_INT
:
805 * Logical Volume Integrity Descriptor
808 lvid
= (struct log_vol_int_desc
*)taddr
;
809 h
->udfs
.lvid_loc
= lvds_loc
;
810 h
->udfs
.lvid_len
= ((uint32_t)
811 &((struct log_vol_int_desc
*)0)->lvid_fst
) +
812 SWAP_32(lvid
->lvid_npart
) * 8 +
813 SWAP_32(lvid
->lvid_liu
);
814 h
->udfs
.lvid_len
= lb_roundup(h
->udfs
.lvid_len
,
818 * It seems we have a next integrity
821 if (SWAP_32(lvid
->lvid_nie
.ext_len
) != 0) {
823 lvds_loc
= SWAP_32(lvid
->lvid_nie
.ext_loc
);
824 lvds_len
= SWAP_32(lvid
->lvid_nie
.ext_len
);
831 * Success fully completed
836 * If you donot undetstand any tag just skip
837 * it. This is not a fatal error
844 if (h
->udfs
.lvid_len
== 0) {
851 ud_get_latest_fsd(ud_handle_t h
, uint16_t fsd_prn
,
852 uint32_t fsd_loc
, uint32_t fsd_len
)
854 uint8_t *addr
, *taddr
, *eaddr
;
857 uint32_t fsds_loc
, fsds_len
;
859 struct file_set_desc
*fsd
;
860 uint32_t old_fsn
= 0;
863 h
->udfs
.fsds_prn
= fsd_prn
;
864 h
->udfs
.fsds_loc
= fsd_loc
;
865 h
->udfs
.fsds_len
= fsd_len
;
867 fsds_loc
= ud_xlate_to_daddr(h
, fsd_prn
, fsd_loc
);
868 fsds_len
= lb_roundup(fsd_len
, h
->udfs
.lbsize
);
870 if ((addr
= (uint8_t *)malloc(fsds_len
)) == NULL
) {
874 off
= fsds_loc
* h
->udfs
.lbsize
;
875 if (ud_read_dev(h
, off
, addr
, fsds_len
) != 0) {
879 for (taddr
= addr
, eaddr
= addr
+ h
->udfs
.mvds_len
; taddr
< eaddr
;
880 taddr
+= h
->udfs
.lbsize
, fsds_loc
++) {
883 tag
= (struct tag
*)taddr
;
884 id
= SWAP_16(tag
->tag_id
);
886 * If you cannot verify the tag just skip it
887 * This is not a fatal error
889 if (ud_verify_tag(h
, tag
, id
, fsds_loc
, 1, 0) != 0) {
893 case UD_FILE_SET_DESC
:
895 fsd
= (struct file_set_desc
*)taddr
;
896 if ((h
->udfs
.fsd_len
== 0) ||
897 (SWAP_32(fsd
->fsd_fs_no
) > old_fsn
)) {
898 old_fsn
= SWAP_32(fsd
->fsd_fs_no
);
899 h
->udfs
.fsd_loc
= fsds_loc
;
900 h
->udfs
.fsd_len
= lb_roundup(512,
903 SWAP_16(fsd
->fsd_root_icb
.lad_ext_prn
);
905 SWAP_32(fsd
->fsd_root_icb
.lad_ext_loc
);
907 SWAP_32(fsd
->fsd_root_icb
.lad_ext_len
);
909 if (SWAP_32(fsd
->fsd_next
.lad_ext_len
) != 0) {
910 fsd_prn
= SWAP_16(fsd
->fsd_next
.lad_ext_prn
);
911 fsd_loc
= SWAP_32(fsd
->fsd_next
.lad_ext_loc
);
912 fsd_len
= SWAP_32(fsd
->fsd_next
.lad_ext_len
);
919 * Success fully completed
924 * If you donot undetstand any tag just skip
925 * it. This is not a fatal error
933 if (h
->udfs
.fsd_len
== 0) {
940 ud_get_num_blks(ud_handle_t h
, uint32_t *blkno
)
943 struct dk_cinfo dki_info
;
947 * Get VTOC from driver
949 if ((error
= ioctl(h
->fd
, DKIOCGVTOC
, (intptr_t)&vtoc
)) != 0) {
954 * Verify if is proper
956 if (vtoc
.v_sanity
!= VTOC_SANE
) {
961 * Get dk_cinfo from driver
963 if ((error
= ioctl(h
->fd
, DKIOCINFO
, (intptr_t)&dki_info
)) != 0) {
967 if (dki_info
.dki_partition
>= V_NUMPAR
) {
972 * Return the size of the partition
974 *blkno
= vtoc
.v_part
[dki_info
.dki_partition
].p_size
;
980 ud_xlate_to_daddr(ud_handle_t h
, uint16_t prn
, uint32_t blkno
)
987 if (prn
< h
->n_maps
) {
989 for (i
= 0; i
< h
->n_parts
; i
++) {
991 if (m
->udm_pn
== p
->udp_number
) {
992 return (p
->udp_start
+ blkno
);
999 /* ------ END Read and translate the on disk VDS to IN CORE format -------- */
1002 ud_verify_tag(ud_handle_t h
, struct tag
*tag
, uint16_t id
,
1003 uint32_t blockno
, int32_t do_crc
, int32_t print_msg
)
1006 uint8_t *addr
, cksum
= 0;
1011 * Verify Tag Identifier
1013 if (tag
->tag_id
!= SWAP_16(id
)) {
1014 if (print_msg
!= 0) {
1015 (void) fprintf(stderr
,
1016 gettext("tag does not verify tag %x req %x\n"),
1017 SWAP_16(tag
->tag_id
), id
);
1023 * Verify Tag Descriptor Version
1025 if (SWAP_16(tag
->tag_desc_ver
) != h
->udfs
.ecma_version
) {
1026 if (print_msg
!= 0) {
1027 (void) fprintf(stderr
,
1028 gettext("tag version does not match with "
1029 "NSR descriptor version TAG %x NSR %x\n"),
1030 SWAP_16(tag
->tag_desc_ver
),
1031 h
->udfs
.ecma_version
);
1037 * Caliculate Tag Checksum
1039 addr
= (uint8_t *)tag
;
1040 for (i
= 0; i
<= 15; i
++) {
1047 * Verify Tag Checksum
1049 if (cksum
!= tag
->tag_cksum
) {
1050 if (print_msg
!= 0) {
1051 (void) fprintf(stderr
,
1052 gettext("Checksum Does not Verify TAG"
1053 " %x CALC %x\n"), tag
->tag_cksum
, cksum
);
1060 * Do we want to do crc
1063 if (tag
->tag_crc_len
) {
1066 * Caliculate CRC for the descriptor
1068 crc
= ud_crc(addr
+ 0x10, SWAP_16(tag
->tag_crc_len
));
1073 if (crc
!= SWAP_16(tag
->tag_crc
)) {
1074 if (print_msg
!= 0) {
1075 (void) fprintf(stderr
,
1076 gettext("CRC Does not verify"
1077 " TAG %x CALC %x %x\n"),
1078 SWAP_16(tag
->tag_crc
),
1085 * Verify Tag Location
1087 if (SWAP_32(blockno
) != tag
->tag_loc
) {
1088 if (print_msg
!= 0) {
1089 (void) fprintf(stderr
,
1090 gettext("Tag Location Does not verify"
1091 " blockno %x tag_blockno %x\n"),
1092 blockno
, SWAP_32(tag
->tag_loc
));
1103 ud_make_tag(ud_handle_t h
, struct tag
*tag
, uint16_t tag_id
,
1104 uint32_t blkno
, uint16_t crc_len
)
1108 uint8_t *addr
, cksum
= 0;
1110 tag
->tag_id
= SWAP_16(tag_id
);
1111 tag
->tag_desc_ver
= SWAP_16(h
->udfs
.ecma_version
);
1116 * Calicualte and assign CRC, CRC_LEN
1118 addr
= (uint8_t *)tag
;
1119 crc
= ud_crc(addr
+ 0x10, crc_len
);
1120 tag
->tag_crc
= SWAP_16(crc
);
1121 tag
->tag_crc_len
= SWAP_16(crc_len
);
1122 tag
->tag_loc
= SWAP_32(blkno
);
1125 * Caliculate Checksum
1127 for (i
= 0; i
<= 15; i
++) {
1134 tag
->tag_cksum
= cksum
;
1137 /* **************** udf specific subroutines *********************** */
1139 static uint16_t ud_crc_table
[256] = {
1140 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
1141 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
1142 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
1143 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
1144 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
1145 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
1146 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
1147 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
1148 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
1149 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
1150 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
1151 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
1152 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
1153 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
1154 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
1155 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
1156 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
1157 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
1158 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
1159 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
1160 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
1161 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
1162 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
1163 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
1164 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
1165 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
1166 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
1167 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
1168 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
1169 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
1170 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
1171 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
1175 ud_crc(uint8_t *addr
, int32_t len
)
1180 crc
= ud_crc_table
[(crc
>> 8 ^ *addr
++) & 0xff] ^ (crc
<<8);
1186 #define MAXNAMLEN 0x200
1189 #define POUND 0x0023
1191 #define SLASH 0x002F
1192 #define UNDERBAR 0x005F
1195 static uint16_t htoc
[16] = {'0', '1', '2', '3',
1196 '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
1198 * unicode is the string of 16-bot characters
1199 * length is the number of 16-bit characters
1202 UdfTxName(uint16_t *unicode
, int32_t count
)
1204 int32_t i
, j
, k
, lic
, make_crc
, dot_loc
;
1207 if ((unicode
[0] == DOT
) &&
1208 ((count
== 1) || ((count
== 2) && (unicode
[1] == DOT
)))) {
1213 unicode
[0] = UNDERBAR
;
1215 unicode
[2] = htoc
[(uint16_t)(crc
& 0xf000) >> 12];
1216 unicode
[3] = htoc
[(uint16_t)(crc
& 0xf00) >> 8];
1217 unicode
[4] = htoc
[(uint16_t)(crc
& 0xf0) >> 4];
1218 unicode
[5] = htoc
[crc
& 0xf];
1224 for (i
= 0; i
< count
; i
++) {
1228 if (unicode
[i
] == DOT
) {
1231 if ((unicode
[i
] == SLASH
) ||
1232 (unicode
[i
] == 0)) {
1233 if (make_crc
== 0) {
1234 for (k
= 0; k
<= i
; k
++) {
1239 if (lic
!= (i
- 1)) {
1240 unicode
[j
++] = UNDERBAR
;
1244 unicode
[j
++] = unicode
[i
];
1249 if (dot_loc
!= -1) {
1250 if ((j
+ 5) > MAXNAMLEN
) {
1251 if ((j
- dot_loc
+ 5) > MAXNAMLEN
) {
1252 j
= MAXNAMLEN
- 5 + dot_loc
;
1254 j
>= dot_loc
; k
--, j
--) {
1255 unicode
[k
] = unicode
[j
];
1260 j
>= dot_loc
; k
--, j
--) {
1261 unicode
[k
] = unicode
[j
];
1267 for (k
= j
; k
>= dot_loc
; k
--) {
1268 unicode
[k
+ 5] = unicode
[k
];
1274 if ((j
+ 5) > MAXNAMLEN
) {
1282 unicode
[k
++] = POUND
;
1283 unicode
[k
++] = htoc
[(uint16_t)(crc
& 0xf000) >> 12];
1284 unicode
[k
++] = htoc
[(uint16_t)(crc
& 0xf00) >> 8];
1285 unicode
[k
++] = htoc
[(uint16_t)(crc
& 0xf0) >> 4];
1286 unicode
[k
++] = htoc
[crc
& 0xf];
1292 * Assumes the output buffer is large
1293 * enough to hold the uncompressed
1298 int32_t numberOfBytes
, /* (Input) number of bytes read from media. */
1299 uint8_t *UDFCompressed
, /* (Input) bytes read from media. */
1300 uint16_t *unicode
) /* (Output) uncompressed unicode characters. */
1303 int32_t returnValue
, unicodeIndex
, byteIndex
;
1307 * Use UDFCompressed to store current byte being read.
1309 compID
= UDFCompressed
[0];
1311 /* First check for valid compID. */
1312 if (compID
!= 8 && compID
!= 16) {
1318 /* Loop through all the bytes. */
1319 while (byteIndex
< numberOfBytes
) {
1322 * Move the first byte to the
1323 * high bits of the unicode char.
1325 unicode
[unicodeIndex
] =
1326 UDFCompressed
[byteIndex
++] << 8;
1328 unicode
[unicodeIndex
] = 0;
1330 if (byteIndex
< numberOfBytes
) {
1332 * Then the next byte to the low bits.
1334 unicode
[unicodeIndex
] |=
1335 UDFCompressed
[byteIndex
++];
1339 returnValue
= unicodeIndex
;
1341 return (returnValue
);
1350 int32_t numberOfChars
, /* (Input) number of unicode characters. */
1351 int32_t compID
, /* (Input) compression ID to be used. */
1352 uint16_t *unicode
, /* (Input) unicode characters to compress. */
1353 uint8_t *UDFCompressed
) /* (Output) compressed string, as bytes. */
1357 if (compID
!= 8 && compID
!= 16) {
1359 * Unsupported compression ID !
1364 * Place compression code in first byte.
1366 UDFCompressed
[0] = (uint8_t)compID
;
1367 (void) strncpy((caddr_t
)&UDFCompressed
[1],
1368 (caddr_t
)unicode
, numberOfChars
);
1369 byteIndex
= numberOfChars
+ 1;
1376 ud_convert2utf8(uint8_t *ibuf
, uint8_t *obuf
, int32_t length
)
1382 buf
= (uint16_t *)obuf
;
1384 size
= UncompressUnicode(length
, ibuf
, buf
);
1386 size
= UdfTxName(buf
, size
);
1388 for (i
= 0; i
< size
; i
++) {
1389 obuf
[i
] = (uint8_t)buf
[i
];
1397 ud_convert2utf16(uint8_t *ibuf
, uint8_t *obuf
, int32_t length
)
1403 ptr
= (uint16_t *)ibuf
;
1404 comp_len
= ud_compressunicode(length
, 8, ptr
, obuf
);
1410 * Assumption code set is zero in udfs
1413 ud_convert2local(int8_t *ibuf
, int8_t *obuf
, int32_t length
)
1416 int32_t i
, comp
, index
;
1419 * Special uncompress code
1420 * written to accomodate solaris wchar_t
1423 for (i
= 0, index
= 1; i
< length
; i
++) {
1425 buf4c
[i
] = ibuf
[index
++] << 8;
1429 if (index
< length
) {
1430 buf4c
[i
] |= ibuf
[index
++];
1433 (void) wcstombs((char *)obuf
, buf4c
, 128);
1437 /* ------------ Routines to print basic structures Part 1 ---------------- */
1442 print_charspec(FILE *fout
, char *name
, struct charspec
*cspec
)
1446 (void) fprintf(fout
,
1447 "%s : %x - \"", name
, cspec
->cs_type
);
1448 for (i
= 0; i
< 63; i
++) {
1449 (void) fprintf(fout
,
1450 "%c", cspec
->cs_info
[i
]);
1452 (void) fprintf(fout
, "\n");
1457 print_dstring(FILE *fout
, char *name
, uint16_t cset
, char *bufc
, uint8_t length
)
1461 ud_convert2local(bufc
, bufmb
, length
);
1463 (void) fprintf(fout
,
1464 "%s %s\n", name
, bufmb
);
1468 set_dstring(dstring_t
*dp
, char *cp
, int32_t len
)
1473 length
= strlen(cp
);
1474 if (length
> len
- 1) {
1477 (void) strncpy(dp
, cp
, length
);
1478 dp
[len
- 1] = length
;
1482 print_tstamp(FILE *fout
, char *name
, tstamp_t
*ts
)
1484 (void) fprintf(fout
, "%s tz : %d yr : %d mo : %d da : %d "
1485 "Time : %d : %d : %d : %d : %d : %d\n", name
,
1486 SWAP_16(ts
->ts_tzone
), SWAP_16(ts
->ts_year
), ts
->ts_month
,
1487 ts
->ts_day
, ts
->ts_hour
, ts
->ts_min
, ts
->ts_sec
, ts
->ts_csec
,
1488 ts
->ts_husec
, ts
->ts_usec
);
1494 make_regid(ud_handle_t h
, struct regid
*reg
, char *id
, int32_t type
)
1497 (void) strncpy(reg
->reg_id
, id
, 23);
1499 if (type
== REG_DOM_ID
) {
1500 struct dom_id_suffix
*dis
;
1503 dis
= (struct dom_id_suffix
*)reg
->reg_ids
;
1504 dis
->dis_udf_revison
= SWAP_16(h
->udfs
.ma_write
);
1505 dis
->dis_domain_flags
= 0;
1507 } else if (type
== REG_UDF_ID
) {
1508 struct udf_id_suffix
*uis
;
1511 uis
= (struct udf_id_suffix
*)reg
->reg_ids
;
1512 uis
->uis_udf_revision
= SWAP_16(h
->udfs
.ma_write
);
1513 uis
->uis_os_class
= OS_CLASS_UNIX
;
1514 uis
->uis_os_identifier
= OS_IDENTIFIER_SOLARIS
;
1515 } else if (type
== REG_UDF_II
) {
1516 struct impl_id_suffix
*iis
;
1518 iis
= (struct impl_id_suffix
*)reg
->reg_ids
;
1519 iis
->iis_os_class
= OS_CLASS_UNIX
;
1520 iis
->iis_os_identifier
= OS_IDENTIFIER_SOLARIS
;
1525 print_regid(FILE *fout
, char *name
, struct regid
*reg
, int32_t type
)
1527 (void) fprintf(fout
, "%s : 0x%x : \"%s\" :",
1528 name
, reg
->reg_flags
, reg
->reg_id
);
1530 if (type
== REG_DOM_ID
) {
1531 struct dom_id_suffix
*dis
;
1534 dis
= (struct dom_id_suffix
*)reg
->reg_ids
;
1535 (void) fprintf(fout
, " 0x%x : %s : %s\n",
1536 SWAP_16(dis
->dis_udf_revison
),
1537 (dis
->dis_domain_flags
& PROTECT_SOFT_WRITE
) ?
1538 "HW Protect" : "No HW Write Protect",
1539 (dis
->dis_domain_flags
& PROTECT_HARD_WRITE
) ?
1540 "SW Protect" : "No SW Protect");
1541 } else if (type
== REG_UDF_ID
) {
1542 struct udf_id_suffix
*uis
;
1545 uis
= (struct udf_id_suffix
*)reg
->reg_ids
;
1546 (void) fprintf(fout
,
1547 " 0x%x : OS Class 0x%x : OS Identifier 0x%x\n",
1548 SWAP_16(uis
->uis_udf_revision
),
1549 uis
->uis_os_class
, uis
->uis_os_identifier
);
1551 struct impl_id_suffix
*iis
;
1553 iis
= (struct impl_id_suffix
*)reg
->reg_ids
;
1554 (void) fprintf(fout
,
1555 " OS Class 0x%x : OS Identifier 0x%x\n",
1556 iis
->iis_os_class
, iis
->iis_os_identifier
);
1562 print_regid(FILE *fout
, char *name
, struct regid
*reg
)
1564 (void) fprintf(fout
, "%s : 0x%x : \"%s\" :",
1565 name
, reg
->reg_flags
, reg
->reg_id
);
1567 if (strncmp(reg
->reg_id
, "*OSTA UDF Compliant", 19) == 0) {
1568 (void) fprintf(fout
, " 0x%x : %s : %s\n",
1569 reg
->reg_ids
[0] | (reg
->reg_ids
[1] << 8),
1570 (reg
->reg_ids
[2] & 1) ?
1571 "HW Protect" : "No HW Write Protect",
1572 (reg
->reg_ids
[2] & 2) ?
1573 "SW Protect" : "No SW Protect");
1574 } else if ((strncmp(reg
->reg_id
, "*UDF Virtual Partition", 22) == 0) ||
1575 (strncmp(reg
->reg_id
, "*UDF Sparable Partition", 23) == 0) ||
1576 (strncmp(reg
->reg_id
, "*UDF Virtual Alloc Tbl", 22) == 0) ||
1577 (strncmp(reg
->reg_id
, "*UDF Sparing Table", 18) == 0)) {
1578 (void) fprintf(fout
,
1579 " 0x%x : OS Class 0x%x : OS Identifier 0x%x\n",
1580 reg
->reg_ids
[0] | (reg
->reg_ids
[1] << 8),
1581 reg
->reg_ids
[2], reg
->reg_ids
[3]);
1583 (void) fprintf(fout
,
1584 " OS Class 0x%x : OS Identifier 0x%x\n",
1585 reg
->reg_ids
[0], reg
->reg_ids
[1]);
1591 /* ------------ Routines to print basic structures Part 2 ---------------- */
1594 * This part is OS specific and is currently
1598 /* ------------ Routines to print basic structures Part 3 ---------------- */
1601 print_ext_ad(FILE *fout
, char *name
, struct extent_ad
*ead
)
1603 (void) fprintf(fout
,
1604 "%s EAD Len %x Loc %x\n",
1605 name
, SWAP_32(ead
->ext_len
), SWAP_32(ead
->ext_loc
));
1609 print_tag(FILE *fout
, struct tag
*tag
)
1611 (void) fprintf(fout
,
1612 "tag_id : %x ver : %x cksum : %x "
1613 "sno : %x crc : %x crc_len : %x loc : %x\n",
1614 SWAP_16(tag
->tag_id
), SWAP_16(tag
->tag_desc_ver
),
1615 tag
->tag_cksum
, SWAP_16(tag
->tag_sno
),
1616 SWAP_16(tag
->tag_crc
), SWAP_16(tag
->tag_crc_len
),
1617 SWAP_32(tag
->tag_loc
));
1622 print_pvd(FILE *fout
, struct pri_vol_desc
*pvd
)
1624 (void) fprintf(fout
,
1625 "\n\t\t\tPrimary Volume Descriptor\n");
1626 print_tag(fout
, &pvd
->pvd_tag
);
1627 (void) fprintf(fout
, "vdsn : %x vdn : %x\n",
1628 SWAP_32(pvd
->pvd_vdsn
), SWAP_32(pvd
->pvd_pvdn
));
1629 print_dstring(fout
, "volid : ", pvd
->pvd_desc_cs
.cs_type
,
1630 pvd
->pvd_vol_id
, 32);
1631 (void) fprintf(fout
,
1632 "vsn : %x mvsn : %x il : %x mil :"
1633 " %x csl : %x mcsl %x\n",
1634 SWAP_16(pvd
->pvd_vsn
), SWAP_16(pvd
->pvd_mvsn
),
1635 SWAP_16(pvd
->pvd_il
), SWAP_16(pvd
->pvd_mil
),
1636 SWAP_32(pvd
->pvd_csl
), SWAP_32(pvd
->pvd_mcsl
));
1637 print_dstring(fout
, "vsid :", pvd
->pvd_desc_cs
.cs_type
,
1639 print_charspec(fout
, "desc_cs", &pvd
->pvd_desc_cs
);
1640 print_charspec(fout
, "exp_cs", &pvd
->pvd_exp_cs
);
1641 print_ext_ad(fout
, "val ", &pvd
->pvd_vol_abs
);
1642 print_ext_ad(fout
, "vcnl ", &pvd
->pvd_vcn
);
1643 print_regid(fout
, "ai", &pvd
->pvd_appl_id
, REG_UDF_II
);
1644 print_regid(fout
, "ii", &pvd
->pvd_ii
, REG_UDF_II
);
1645 (void) fprintf(fout
, "pvdsl : %x flags : %x\n",
1646 SWAP_32(pvd
->pvd_pvdsl
),
1647 SWAP_16(pvd
->pvd_flags
));
1651 print_avd(FILE *fout
, struct anch_vol_desc_ptr
*avdp
)
1653 (void) fprintf(fout
,
1654 "\n\t\t\tAnchor Volume Descriptor\n");
1655 print_tag(fout
, &avdp
->avd_tag
);
1656 print_ext_ad(fout
, "Main Volume Descriptor Sequence : ",
1657 &avdp
->avd_main_vdse
);
1658 print_ext_ad(fout
, "Reserve Volume Descriptor Sequence : ",
1659 &avdp
->avd_res_vdse
);
1663 print_vdp(FILE *fout
, struct vol_desc_ptr
*vdp
)
1665 (void) fprintf(fout
,
1666 "\n\t\t\tVolume Descriptor Pointer\n");
1667 print_tag(fout
, &vdp
->vdp_tag
);
1668 (void) fprintf(fout
, "vdsn : %x ",
1669 SWAP_32(vdp
->vdp_vdsn
));
1670 print_ext_ad(fout
, "vdse ", &vdp
->vdp_nvdse
);
1674 print_iuvd(FILE *fout
, struct iuvd_desc
*iuvd
)
1676 (void) fprintf(fout
,
1677 "\n\t\t\tImplementation Use Volume Descriptor\n");
1678 print_tag(fout
, &iuvd
->iuvd_tag
);
1679 (void) fprintf(fout
,
1680 "vdsn : %x ", SWAP_32(iuvd
->iuvd_vdsn
));
1681 print_regid(fout
, "Impl Id : ", &iuvd
->iuvd_ii
, REG_UDF_ID
);
1682 print_charspec(fout
, "cset ", &iuvd
->iuvd_cset
);
1683 print_dstring(fout
, "lvi : ", iuvd
->iuvd_cset
.cs_type
,
1684 iuvd
->iuvd_lvi
, 128);
1685 print_dstring(fout
, "ifo1 : ", iuvd
->iuvd_cset
.cs_type
,
1686 iuvd
->iuvd_ifo1
, 36);
1687 print_dstring(fout
, "ifo2 : ", iuvd
->iuvd_cset
.cs_type
,
1688 iuvd
->iuvd_ifo2
, 36);
1689 print_dstring(fout
, "ifo3 : ", iuvd
->iuvd_cset
.cs_type
,
1690 iuvd
->iuvd_ifo3
, 36);
1692 print_regid(fout
, "iid ", &iuvd
->iuvd_iid
, REG_UDF_II
);
1696 print_part(FILE *fout
, struct part_desc
*pd
)
1698 (void) fprintf(fout
,
1699 "\n\t\t\tPartition Descriptor\n");
1700 print_tag(fout
, &pd
->pd_tag
);
1701 (void) fprintf(fout
,
1702 "vdsn : %x flags : %x num : %x ",
1703 SWAP_32(pd
->pd_vdsn
),
1704 SWAP_16(pd
->pd_pflags
),
1705 SWAP_16(pd
->pd_pnum
));
1706 print_regid(fout
, "contents ", &pd
->pd_pcontents
, REG_UDF_II
);
1708 print_phdr(fout
, (struct phdr_desc
*)(&pd
->pd_pc_use
));
1709 (void) fprintf(fout
,
1710 "acc : %x start : %x length : %x ",
1711 SWAP_32(pd
->pd_acc_type
),
1712 SWAP_32(pd
->pd_part_start
),
1713 SWAP_32(pd
->pd_part_length
));
1714 print_regid(fout
, "Impl Id : ", &pd
->pd_ii
, REG_UDF_II
);
1718 print_lvd(FILE *fout
, struct log_vol_desc
*lvd
)
1720 (void) fprintf(fout
,
1721 "\n\t\t\tLogical Volume Descriptor\n");
1722 print_tag(fout
, &lvd
->lvd_tag
);
1723 (void) fprintf(fout
,
1724 "vdsn : %x ", SWAP_32(lvd
->lvd_vdsn
));
1725 print_charspec(fout
, "Desc Char Set ", &lvd
->lvd_desc_cs
);
1726 print_dstring(fout
, "lvid : ", lvd
->lvd_desc_cs
.cs_type
,
1728 (void) fprintf(fout
,
1730 SWAP_32(lvd
->lvd_log_bsize
));
1731 print_regid(fout
, "Dom Id", &lvd
->lvd_dom_id
, REG_DOM_ID
);
1732 print_long_ad(fout
, "lvcu", &lvd
->lvd_lvcu
);
1733 (void) fprintf(fout
,
1734 "mtlen : %x nmaps : %x ",
1735 SWAP_32(lvd
->lvd_mtbl_len
),
1736 SWAP_32(lvd
->lvd_num_pmaps
));
1737 print_regid(fout
, "Impl Id : ", &lvd
->lvd_ii
, REG_UDF_II
);
1738 print_ext_ad(fout
, "Int Seq", &lvd
->lvd_int_seq_ext
);
1739 print_pmaps(fout
, lvd
->lvd_pmaps
, SWAP_32(lvd
->lvd_num_pmaps
));
1743 print_usd(FILE *fout
, struct unall_spc_desc
*ua
)
1747 (void) fprintf(fout
,
1748 "\n\t\t\tUnallocated Space Descriptor\n");
1749 print_tag(fout
, &ua
->ua_tag
);
1750 count
= SWAP_32(ua
->ua_nad
);
1751 (void) fprintf(fout
,
1752 "vdsn : %x nad : %x\n",
1753 SWAP_32(ua
->ua_vdsn
), count
);
1754 for (i
= 0; i
< count
; i
++) {
1755 (void) fprintf(fout
,
1756 "loc : %x len : %x\n",
1757 SWAP_32(ua
->ua_al_dsc
[i
* 2]),
1758 SWAP_32(ua
->ua_al_dsc
[i
* 2 + 1]));
1763 print_lvid(FILE *fout
, struct log_vol_int_desc
*lvid
)
1767 struct lvid_iu
*liu
;
1769 (void) fprintf(fout
,
1770 "\n\t\t\tLogical Volume Integrity Descriptor\n");
1771 print_tag(fout
, &lvid
->lvid_tag
);
1772 print_tstamp(fout
, "Rec TM ", &lvid
->lvid_tstamp
);
1773 if (SWAP_32(lvid
->lvid_int_type
) == 0) {
1774 (void) fprintf(fout
,
1775 "int_typ : Open\n");
1776 } else if (SWAP_32(lvid
->lvid_int_type
) == 1) {
1777 (void) fprintf(fout
, "int_typ : Closed\n");
1779 (void) fprintf(fout
, "int_typ : Unknown\n");
1781 print_ext_ad(fout
, "Nie ", &lvid
->lvid_nie
);
1782 count
= SWAP_32(lvid
->lvid_npart
);
1783 (void) fprintf(fout
,
1784 "Uniq : %llx npart : %x liu : %x\n",
1785 SWAP_64(lvid
->lvid_lvcu
.lvhd_uniqid
),
1786 count
, SWAP_32(lvid
->lvid_liu
));
1787 for (i
= 0; i
< count
; i
++) {
1788 (void) fprintf(fout
,
1789 "Part : %x Free : %x Size : %x\n",
1790 i
, SWAP_32(lvid
->lvid_fst
[i
]),
1791 SWAP_32(lvid
->lvid_fst
[count
+ i
]));
1794 addr
= (caddr_t
)lvid
->lvid_fst
;
1796 liu
= (struct lvid_iu
*)(addr
+ 2 * count
* 4);
1797 print_regid(fout
, "Impl Id :", &liu
->lvidiu_regid
, REG_UDF_II
);
1798 (void) fprintf(fout
,
1799 "nfiles : %x ndirs : %x miread : %x"
1800 " miwrite : %x mawrite : %x\n",
1801 SWAP_32(liu
->lvidiu_nfiles
), SWAP_32(liu
->lvidiu_ndirs
),
1802 SWAP_16(liu
->lvidiu_mread
), SWAP_16(liu
->lvidiu_mwrite
),
1803 SWAP_16(liu
->lvidiu_maxwr
));
1807 /* ------------ Routines to print basic structures Part 4 ---------------- */
1810 print_fsd(FILE *fout
, ud_handle_t h
, struct file_set_desc
*fsd
)
1812 (void) fprintf(fout
,
1813 "\n\t\t\tFile Set Descriptor\n");
1815 print_tag(fout
, &fsd
->fsd_tag
);
1816 print_tstamp(fout
, "Rec TM ", &fsd
->fsd_time
);
1817 (void) fprintf(fout
,
1818 "ilvl : %x milvl : %x csl : %x"
1819 " mcsl : %x fsn : %x fsdn : %x\n",
1820 SWAP_16(fsd
->fsd_ilevel
), SWAP_16(fsd
->fsd_mi_level
),
1821 SWAP_32(fsd
->fsd_cs_list
), SWAP_32(fsd
->fsd_mcs_list
),
1822 SWAP_32(fsd
->fsd_fs_no
), SWAP_32(fsd
->fsd_fsd_no
));
1823 print_charspec(fout
, "ID CS ", &fsd
->fsd_lvidcs
);
1824 print_dstring(fout
, "lvi : ", fsd
->fsd_lvidcs
.cs_type
,
1825 fsd
->fsd_lvid
, 128);
1826 print_charspec(fout
, "ID CS ", &fsd
->fsd_fscs
);
1827 print_dstring(fout
, "fsi : ", fsd
->fsd_lvidcs
.cs_type
,
1829 print_dstring(fout
, "cfi : ", fsd
->fsd_lvidcs
.cs_type
,
1831 print_dstring(fout
, "afi : ", fsd
->fsd_lvidcs
.cs_type
,
1833 print_long_ad(fout
, "Ricb ", &fsd
->fsd_root_icb
);
1834 print_regid(fout
, "DI ", &fsd
->fsd_did
, REG_DOM_ID
);
1835 print_long_ad(fout
, "Next Fsd ", &fsd
->fsd_next
);
1836 if (h
->udfs
.ecma_version
== UD_ECMA_VER3
) {
1837 print_long_ad(fout
, "System Stream Directory ICB ",
1843 print_phdr(FILE *fout
, struct phdr_desc
*ph
)
1845 print_short_ad(fout
, "ust ", &ph
->phdr_ust
);
1846 print_short_ad(fout
, "usb ", &ph
->phdr_usb
);
1847 print_short_ad(fout
, "int ", &ph
->phdr_it
);
1848 print_short_ad(fout
, "fst ", &ph
->phdr_fst
);
1849 print_short_ad(fout
, "fsh ", &ph
->phdr_fsb
);
1853 print_fid(FILE *fout
, struct file_id
*fid
)
1858 (void) fprintf(fout
,
1859 "File Identifier Descriptor\n");
1860 print_tag(fout
, &fid
->fid_tag
);
1861 (void) fprintf(fout
, "fvn : %x fc : %x length : %x ",
1862 fid
->fid_ver
, fid
->fid_flags
, fid
->fid_idlen
);
1863 print_long_ad(fout
, "ICB", &fid
->fid_icb
);
1864 addr
= &fid
->fid_spec
[SWAP_16(fid
->fid_iulen
)];
1865 (void) fprintf(fout
, "iulen : %x comp : %x name : ",
1866 SWAP_16(fid
->fid_iulen
), *addr
);
1868 for (i
= 0; i
< fid
->fid_idlen
; i
++) {
1869 (void) fprintf(fout
, "%c", *addr
++);
1871 (void) fprintf(fout
, "\n");
1875 print_aed(FILE *fout
, struct alloc_ext_desc
*aed
)
1877 (void) fprintf(fout
,
1878 "Allocation Extent Descriptor\n");
1879 print_tag(fout
, &aed
->aed_tag
);
1880 (void) fprintf(fout
, "prev ael loc : %x laed : %x\n",
1881 SWAP_32(aed
->aed_rev_ael
), SWAP_32(aed
->aed_len_aed
));
1884 static char *ftype
[] = {
1885 "NON", "USE", "PIE", "IE",
1886 "DIR", "REG", "BDEV", "CDEV",
1887 "EATT", "FIFO", "SOCK", "TERM",
1892 print_icb_tag(FILE *fout
, struct icb_tag
*itag
)
1894 (void) fprintf(fout
,
1895 "prnde : %x strat : %x param : %x max_ent %x\n",
1896 SWAP_32(itag
->itag_prnde
), SWAP_16(itag
->itag_strategy
),
1897 SWAP_16(itag
->itag_param
), SWAP_16(itag
->itag_max_ent
));
1898 (void) fprintf(fout
,
1899 "ftype : %s prn : %x loc : %x flags : %x\n",
1900 (itag
->itag_ftype
>= 14) ? ftype
[0] : ftype
[itag
->itag_ftype
],
1901 SWAP_16(itag
->itag_lb_prn
),
1902 SWAP_32(itag
->itag_lb_loc
), SWAP_16(itag
->itag_flags
));
1907 print_ie(FILE *fout
, struct indirect_entry
*ie
)
1909 (void) fprintf(fout
,
1910 "Indirect Entry\n");
1911 print_tag(fout
, &ie
->ie_tag
);
1912 print_icb_tag(fout
, &ie
->ie_icb_tag
);
1913 print_long_ad(fout
, "ICB", &ie
->ie_indirecticb
);
1917 print_td(FILE *fout
, struct term_desc
*td
)
1919 (void) fprintf(fout
,
1920 "Terminating Descriptor\n");
1921 print_tag(fout
, &td
->td_tag
);
1925 print_fe(FILE *fout
, struct file_entry
*fe
)
1927 (void) fprintf(fout
,
1929 print_tag(fout
, &fe
->fe_tag
);
1930 print_icb_tag(fout
, &fe
->fe_icb_tag
);
1931 (void) fprintf(fout
,
1932 "uid : %x gid : %x perms : %x nlnk : %x\n",
1933 SWAP_32(fe
->fe_uid
), SWAP_32(fe
->fe_gid
),
1934 SWAP_32(fe
->fe_perms
), SWAP_16(fe
->fe_lcount
));
1935 (void) fprintf(fout
,
1936 "rec_for : %x rec_dis : %x rec_len : %x "
1937 "sz : %llx blks : %llx\n",
1938 fe
->fe_rec_for
, fe
->fe_rec_dis
, SWAP_32(fe
->fe_rec_len
),
1939 SWAP_64(fe
->fe_info_len
), SWAP_64(fe
->fe_lbr
));
1940 print_tstamp(fout
, "ctime ", &fe
->fe_acc_time
);
1941 print_tstamp(fout
, "mtime ", &fe
->fe_mod_time
);
1942 print_tstamp(fout
, "atime ", &fe
->fe_attr_time
);
1943 (void) fprintf(fout
,
1944 "ckpoint : %x ", SWAP_32(fe
->fe_ckpoint
));
1945 print_long_ad(fout
, "ICB", &fe
->fe_ea_icb
);
1946 print_regid(fout
, "impl", &fe
->fe_impl_id
, REG_UDF_II
);
1947 (void) fprintf(fout
,
1948 "uniq_id : %llx len_ear : %x len_adesc %x\n",
1949 SWAP_64(fe
->fe_uniq_id
), SWAP_32(fe
->fe_len_ear
),
1950 SWAP_32(fe
->fe_len_adesc
));
1954 print_pmaps(FILE *fout
, uint8_t *addr
, int32_t count
)
1956 struct pmap_hdr
*hdr
;
1957 struct pmap_typ1
*map1
;
1958 struct pmap_typ2
*map2
;
1961 hdr
= (struct pmap_hdr
*)addr
;
1962 switch (hdr
->maph_type
) {
1965 map1
= (struct pmap_typ1
*)hdr
;
1966 (void) fprintf(fout
, "Map type 1 ");
1967 (void) fprintf(fout
, "VSN %x prn %x\n",
1968 SWAP_16(map1
->map1_vsn
),
1969 SWAP_16(map1
->map1_pn
));
1973 map2
= (struct pmap_typ2
*)hdr
;
1974 (void) fprintf(fout
, "Map type 2 ");
1975 (void) fprintf(fout
, "VSN %x prn %x\n",
1976 SWAP_16(map2
->map2_vsn
),
1977 SWAP_16(map2
->map2_pn
));
1978 print_regid(fout
, "Partition Type Identifier",
1979 &map2
->map2_pti
, REG_UDF_ID
);
1982 (void) fprintf(fout
, "unknown map type\n");
1984 addr
+= hdr
->maph_length
;
1991 print_short_ad(FILE *fout
, char *name
, struct short_ad
*sad
)
1993 (void) fprintf(fout
,
1994 "%s loc : %x len : %x\n", name
,
1995 SWAP_32(sad
->sad_ext_loc
), SWAP_32(sad
->sad_ext_len
));
1999 print_long_ad(FILE *fout
, char *name
, struct long_ad
*lad
)
2001 (void) fprintf(fout
,
2002 "%s prn : %x loc : %x len : %x\n", name
,
2003 SWAP_16(lad
->lad_ext_prn
), SWAP_32(lad
->lad_ext_loc
),
2004 SWAP_32(lad
->lad_ext_len
));