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.
26 #pragma ident "%Z%%M% %I% %E% SMI"
37 #include <sys/types.h>
38 #include <sys/int_types.h>
43 #include <sys/param.h>
44 #include <sys/fs/udf_volume.h>
47 extern char *getfullrawname(char *);
49 static int32_t ud_get_ecma_ver(ud_handle_t
, uint32_t);
50 static int32_t ud_get_fs_bsize(ud_handle_t
, uint32_t, uint32_t *);
51 static int32_t ud_parse_fill_vds(ud_handle_t
, struct vds
*, uint32_t, uint32_t);
52 static int32_t ud_read_and_translate_lvd(ud_handle_t
, uint32_t, uint32_t);
53 static int32_t ud_get_latest_lvid(ud_handle_t
, uint32_t, uint32_t);
54 static int32_t ud_get_latest_fsd(ud_handle_t
, uint16_t, uint32_t, uint32_t);
56 static uint16_t ud_crc(uint8_t *, int32_t);
57 static int32_t UdfTxName(uint16_t *, int32_t);
58 static int32_t UncompressUnicode(int32_t, uint8_t *, uint16_t *);
59 static int32_t ud_compressunicode(int32_t, int32_t, uint16_t *, uint8_t *);
60 static int32_t ud_convert2utf8(uint8_t *, uint8_t *, int32_t);
61 static int32_t ud_convert2utf16(uint8_t *, uint8_t *, int32_t);
65 ud_init(int fd
, ud_handle_t
*hp
)
69 if ((h
= calloc(1, sizeof (struct ud_handle
))) == NULL
) {
78 ud_fini(ud_handle_t h
)
85 ud_open_dev(ud_handle_t h
, char *special
, uint32_t flags
)
88 struct stat i_stat
, r_stat
;
90 (void) bzero(&i_stat
, sizeof (struct stat
));
91 (void) bzero(&r_stat
, sizeof (struct stat
));
94 * Get the stat structure
96 if (stat(special
, &i_stat
) < 0) {
100 if ((i_stat
.st_mode
& S_IFMT
) == S_IFCHR
) {
103 * If Raw deivce is given use it as it is
107 } else if ((i_stat
.st_mode
& S_IFMT
) == S_IFBLK
) {
110 * Block device try to convert to raw device
113 temp
= getfullrawname(special
);
116 * Stat the converted device name and verify
117 * both the raw and block device belong to
120 if (stat(temp
, &r_stat
) < 0) {
123 if (((r_stat
.st_mode
& S_IFMT
) == S_IFBLK
) ||
124 (r_stat
.st_rdev
!= i_stat
.st_rdev
)) {
132 * Now finally open the device
134 h
->fd
= open(temp
, flags
);
141 ud_close_dev(ud_handle_t h
)
144 * Too simple Just close it
150 ud_read_dev(ud_handle_t h
, uint64_t offset
, uint8_t *buf
, uint32_t count
)
153 * Seek to the given offset
155 if (lseek(h
->fd
, offset
, SEEK_SET
) == -1) {
160 * Read the required number of bytes
162 if (read(h
->fd
, buf
, count
) != count
) {
169 ud_write_dev(ud_handle_t h
, uint64_t offset
, uint8_t *buf
, uint32_t count
)
172 * Seek to the given offset
174 if (lseek(h
->fd
, offset
, SEEK_SET
) == -1) {
179 * Read the appropriate number of bytes
181 if (write(h
->fd
, buf
, count
) != count
) {
187 /* ----- BEGIN Read and translate the on disk VDS to IN CORE format -------- */
190 ud_fill_udfs_info(ud_handle_t h
)
192 struct anch_vol_desc_ptr
*avdp
= NULL
;
195 if (ioctl(h
->fd
, CDROMREADOFFSET
, &offset
) == -1) {
199 h
->udfs
.flags
= INVALID_UDFS
;
201 h
->udfs
.ecma_version
= ud_get_ecma_ver(h
, offset
);
202 if (h
->udfs
.ecma_version
== UD_ECMA_UNKN
) {
206 h
->udfs
.lbsize
= ud_get_fs_bsize(h
, offset
, &h
->udfs
.avdp_loc
);
207 if (h
->udfs
.lbsize
== 0) {
211 h
->udfs
.avdp_len
= lb_roundup(512, h
->udfs
.lbsize
);
214 if ((avdp
= (struct anch_vol_desc_ptr
*)
215 malloc(h
->udfs
.lbsize
)) == NULL
) {
218 if (ud_read_dev(h
, h
->udfs
.avdp_loc
* h
->udfs
.lbsize
,
219 (uint8_t *)avdp
, h
->udfs
.lbsize
) != 0) {
223 if (ud_verify_tag(h
, &avdp
->avd_tag
, UD_ANCH_VOL_DESC
,
224 h
->udfs
.avdp_loc
, 1, 0) != 0) {
229 h
->udfs
.mvds_loc
= SWAP_32(avdp
->avd_main_vdse
.ext_loc
);
230 h
->udfs
.mvds_len
= SWAP_32(avdp
->avd_main_vdse
.ext_len
);
232 h
->udfs
.rvds_loc
= SWAP_32(avdp
->avd_res_vdse
.ext_loc
);
233 h
->udfs
.rvds_len
= SWAP_32(avdp
->avd_res_vdse
.ext_len
);
238 * get information from mvds and rvds
240 if (ud_parse_fill_vds(h
, &h
->udfs
.mvds
,
241 h
->udfs
.mvds_loc
, h
->udfs
.mvds_len
) == 0) {
242 h
->udfs
.flags
|= VALID_MVDS
;
244 if (ud_parse_fill_vds(h
, &h
->udfs
.rvds
,
245 h
->udfs
.rvds_loc
, h
->udfs
.rvds_len
) == 0) {
246 h
->udfs
.flags
|= VALID_RVDS
;
249 if ((h
->udfs
.flags
& (VALID_MVDS
| VALID_RVDS
)) == 0) {
254 * If we are here we have
255 * a valid Volume Descriptor Seqence
256 * Read and understand lvd
258 if (h
->udfs
.flags
& VALID_MVDS
) {
259 if (ud_read_and_translate_lvd(h
, h
->udfs
.mvds
.lvd_loc
,
260 h
->udfs
.mvds
.lvd_len
) != 0) {
264 if (ud_read_and_translate_lvd(h
, h
->udfs
.rvds
.lvd_loc
,
265 h
->udfs
.rvds
.lvd_len
) != 0) {
270 h
->udfs
.flags
|= VALID_UDFS
;
276 ud_get_ecma_ver(ud_handle_t h
, uint32_t offset
)
281 struct nsr_desc
*ndsc
;
282 uint32_t ecma_ver
= UD_ECMA_UNKN
;
285 * Allocate a buffer of size UD_VOL_REC_BSZ
287 if ((buf
= (uint8_t *)malloc(UD_VOL_REC_BSZ
)) == NULL
) {
290 * Uh could not even allocate this much
296 * Start from 32k and keep reading 2k blocks we
297 * should be able to find NSR if we have one by 256 * 2k bytes
299 off
= offset
* 2048 + UD_VOL_REC_START
;
300 end_off
= offset
* 2048 + UD_VOL_REC_END
;
301 for (; off
< end_off
; off
+= UD_VOL_REC_BSZ
) {
303 if (ud_read_dev(h
, off
, buf
, UD_VOL_REC_BSZ
) == 0) {
305 ndsc
= (struct nsr_desc
*)buf
;
307 * Is this either NSR02 or NSR03
309 if ((ndsc
->nsr_str_type
== 0) &&
310 (ndsc
->nsr_ver
== 1) &&
311 (ndsc
->nsr_id
[0] == 'N') &&
312 (ndsc
->nsr_id
[1] == 'S') &&
313 (ndsc
->nsr_id
[2] == 'R') &&
314 (ndsc
->nsr_id
[3] == '0') &&
315 ((ndsc
->nsr_id
[4] == '2') ||
316 (ndsc
->nsr_id
[4] == '3'))) {
318 (void) strncpy((char *)h
->udfs
.ecma_id
,
319 (char *)ndsc
->nsr_id
, 5);
321 switch (ndsc
->nsr_id
[4]) {
327 ecma_ver
= UD_ECMA_VER2
;
334 ecma_ver
= UD_ECMA_VER3
;
349 static uint32_t last_block_index
[] = {0, 0, 256, 2, 2 + 256,
350 150, 150 + 256, 152, 152 + 256};
353 ud_get_fs_bsize(ud_handle_t h
, uint32_t offset
, uint32_t *avd_loc
)
356 int32_t index
, bsize
, shift
, end_index
;
357 uint32_t num_blocks
, sub_blk
;
359 struct anch_vol_desc_ptr
*avdp
;
361 if ((buf
= (uint8_t *)malloc(MAXBSIZE
)) == NULL
) {
366 * If we could figure out the last block
367 * search at 256, N, N - 256 blocks
368 * otherwise just check at 256
370 if (ud_get_num_blks(h
, &num_blocks
) != 0) {
374 end_index
= sizeof (last_block_index
) / 4;
377 for (index
= 0; index
< end_index
; index
++) {
378 sub_blk
= last_block_index
[index
];
381 * Start guessing from DEV_BSIZE to MAXBSIZE
383 for (bsize
= DEV_BSIZE
, shift
= 0;
384 bsize
<= MAXBSIZE
; bsize
<<= 1, shift
++) {
389 * Check if we atleast have 256 of bsize
390 * blocks on the device
392 if ((end_index
== 0) ||
393 (num_blocks
> (256 << shift
))) {
397 offset
* 2048 / bsize
;
400 offset
/ (bsize
/ 2048);
407 * Calculate the bsize avd block
410 (num_blocks
> (sub_blk
<< shift
))) {
411 *avd_loc
= (num_blocks
>> shift
) -
418 off
= (uint64_t)*avd_loc
* bsize
;
421 * Read bsize bytes at off
423 if (ud_read_dev(h
, off
, buf
, bsize
) != 0) {
428 * Check if we have a Anchor Volume Descriptor here
432 avdp
= (struct anch_vol_desc_ptr
*)buf
;
433 if (ud_verify_tag(h
, &avdp
->avd_tag
,
434 UD_ANCH_VOL_DESC
, *avd_loc
, 1, 0) != 0) {
442 if (bsize
> MAXBSIZE
) {
451 ud_parse_fill_vds(ud_handle_t h
, struct vds
*v
,
452 uint32_t vds_loc
, uint32_t vds_len
)
454 uint8_t *addr
, *taddr
, *eaddr
;
459 struct pri_vol_desc
*pvd
;
460 struct log_vol_desc
*lvd
;
461 struct vol_desc_ptr
*vds
;
462 struct unall_spc_desc
*usd
;
465 if ((addr
= (uint8_t *)malloc(vds_len
)) == NULL
) {
469 off
= vds_loc
* h
->udfs
.lbsize
;
470 if (ud_read_dev(h
, off
, addr
, vds_len
) != 0) {
474 for (taddr
= addr
, eaddr
= addr
+ h
->udfs
.mvds_len
; taddr
< eaddr
;
475 taddr
+= h
->udfs
.lbsize
, vds_loc
++) {
478 tag
= (struct tag
*)taddr
;
479 id
= SWAP_16(tag
->tag_id
);
481 * If you cannot verify the tag just skip it
482 * This is not a fatal error
484 if (ud_verify_tag(h
, tag
, id
, vds_loc
, 1, 0) != 0) {
488 case UD_PRI_VOL_DESC
:
491 * Primary Volume Descriptor
494 pvd
= (struct pri_vol_desc
*)taddr
;
495 if ((v
->pvd_len
== 0) ||
496 (SWAP_32(pvd
->pvd_vdsn
) > v
->pvd_vdsn
)) {
497 v
->pvd_vdsn
= SWAP_32(pvd
->pvd_vdsn
);
498 v
->pvd_loc
= vds_loc
;
499 v
->pvd_len
= h
->udfs
.lbsize
;
502 case UD_VOL_DESC_PTR
:
505 * Curent sequence is continued from
506 * the location pointed by vdp
509 vds
= (struct vol_desc_ptr
*)taddr
;
511 if (SWAP_32(vds
->vdp_nvdse
.ext_len
) != 0) {
512 vds_loc
= SWAP_32(vds
->vdp_nvdse
.ext_loc
);
513 vds_len
= SWAP_32(vds
->vdp_nvdse
.ext_len
);
518 case UD_IMPL_USE_DESC
:
521 * Implementation Use Volume Descriptor
523 v
->iud_loc
= vds_loc
;
524 v
->iud_len
= lb_roundup(512, h
->udfs
.lbsize
);
529 struct phdr_desc
*ph
;
530 struct part_desc
*pd
;
533 * Partition Descriptor
536 pd
= (struct part_desc
*)taddr
;
538 for (i
= 0; i
< h
->n_parts
; i
++) {
541 if ((SWAP_16(pd
->pd_pnum
) ==
543 (SWAP_32(pd
->pd_vdsn
) >
549 v
->part_loc
[i
] = vds_loc
;
551 lb_roundup(512, h
->udfs
.lbsize
);
554 p
->udp_number
= SWAP_16(pd
->pd_pnum
);
555 p
->udp_seqno
= SWAP_32(pd
->pd_vdsn
);
556 p
->udp_access
= SWAP_32(pd
->pd_acc_type
);
557 p
->udp_start
= SWAP_32(pd
->pd_part_start
);
558 p
->udp_length
= SWAP_32(pd
->pd_part_length
);
561 ph
= (struct phdr_desc
*)pd
->pd_pc_use
;
562 if (ph
->phdr_ust
.sad_ext_len
) {
563 p
->udp_flags
= UDP_SPACETBLS
;
564 p
->udp_unall_loc
= SWAP_32(ph
->phdr_ust
.sad_ext_loc
);
565 p
->udp_unall_len
= SWAP_32(ph
->phdr_ust
.sad_ext_len
);
566 p
->udp_freed_loc
= SWAP_32(ph
->phdr_fst
.sad_ext_loc
);
567 p
->udp_freed_len
= SWAP_32(ph
->phdr_fst
.sad_ext_len
);
569 p
->udp_flags
= UDP_BITMAPS
;
570 p
->udp_unall_loc
= SWAP_32(ph
->phdr_usb
.sad_ext_loc
);
571 p
->udp_unall_len
= SWAP_32(ph
->phdr_usb
.sad_ext_len
);
572 p
->udp_freed_loc
= SWAP_32(ph
->phdr_fsb
.sad_ext_loc
);
573 p
->udp_freed_len
= SWAP_32(ph
->phdr_fsb
.sad_ext_len
);
576 if (i
== h
->n_parts
) {
581 case UD_LOG_VOL_DESC
:
584 * Logical Volume Descriptor
587 lvd
= (struct log_vol_desc
*)taddr
;
588 if ((v
->lvd_len
== 0) ||
589 (SWAP_32(lvd
->lvd_vdsn
) > v
->lvd_vdsn
)) {
590 v
->lvd_vdsn
= SWAP_32(lvd
->lvd_vdsn
);
591 v
->lvd_loc
= vds_loc
;
592 v
->lvd_len
= ((uint32_t)
593 &((struct log_vol_desc
*)0)->lvd_pmaps
);
595 lb_roundup(v
->lvd_len
, h
->udfs
.lbsize
);
598 case UD_UNALL_SPA_DESC
:
601 * Unallocated Space Descriptor
604 usd
= (struct unall_spc_desc
*)taddr
;
605 v
->usd_loc
= vds_loc
;
606 v
->usd_len
= ((uint32_t)
607 &((unall_spc_desc_t
*)0)->ua_al_dsc
) +
608 SWAP_32(usd
->ua_nad
) *
609 sizeof (struct extent_ad
);
610 v
->usd_len
= lb_roundup(v
->usd_len
, h
->udfs
.lbsize
);
614 * Success fully completed
619 * If you donot undetstand any tag just skip
620 * it. This is not a fatal error
628 if ((v
->pvd_len
== 0) ||
629 (v
->part_len
[0] == 0) ||
638 ud_read_and_translate_lvd(ud_handle_t h
, uint32_t lvd_loc
, uint32_t lvd_len
)
642 uint32_t fsd_loc
, fsd_len
;
643 uint32_t lvds_loc
, lvds_len
;
645 struct log_vol_desc
*lvd
= NULL
;
647 int32_t max_maps
, i
, mp_sz
, index
;
650 struct pmap_typ1
*typ1
;
651 struct pmap_typ2
*typ2
;
657 if ((lvd
= (struct log_vol_desc
*)
658 malloc(lvd_len
)) == NULL
) {
662 off
= lvd_loc
* h
->udfs
.lbsize
;
663 if (ud_read_dev(h
, off
, (uint8_t *)lvd
, lvd_len
) != 0) {
668 if (ud_verify_tag(h
, &lvd
->lvd_tag
, UD_LOG_VOL_DESC
,
669 lvd_loc
, 1, 0) != 0) {
677 max_maps
= SWAP_32(lvd
->lvd_num_pmaps
);
678 ph
= (struct pmap_hdr
*)lvd
->lvd_pmaps
;
679 for (h
->n_maps
= index
= 0; index
< max_maps
; index
++) {
680 m
= &h
->maps
[h
->n_maps
];
681 switch (ph
->maph_type
) {
685 typ1
= (struct pmap_typ1
*)ph
;
687 m
->udm_flags
= UDM_MAP_NORM
;
688 m
->udm_vsn
= SWAP_16(typ1
->map1_vsn
);
689 m
->udm_pn
= SWAP_16(typ1
->map1_pn
);
696 typ2
= (struct pmap_typ2
*)ph
;
698 if (strncmp(typ2
->map2_pti
.reg_id
,
699 UDF_VIRT_PART
, 23) == 0) {
701 m
->udm_flags
= UDM_MAP_VPM
;
702 m
->udm_vsn
= SWAP_16(typ2
->map2_vsn
);
703 m
->udm_pn
= SWAP_16(typ2
->map2_pn
);
704 } else if (strncmp(typ2
->map2_pti
.reg_id
,
705 UDF_SPAR_PART
, 23) == 0) {
707 if ((SWAP_16(typ2
->map2_pl
) != 32) ||
708 (typ2
->map2_nst
< 1) ||
709 (typ2
->map2_nst
> 4)) {
712 m
->udm_flags
= UDM_MAP_SPM
;
713 m
->udm_vsn
= SWAP_16(typ2
->map2_vsn
);
714 m
->udm_pn
= SWAP_16(typ2
->map2_pn
);
716 m
->udm_plen
= SWAP_16(typ2
->map2_pl
);
717 m
->udm_nspm
= typ2
->map2_nst
;
718 m
->udm_spsz
= SWAP_32(typ2
->map2_sest
);
720 mp_sz
= lb_roundup(m
->udm_spsz
, h
->udfs
.lbsize
);
722 if ((addr
= malloc(mp_sz
* m
->udm_nspm
)) ==
727 for (i
= 0; i
< m
->udm_nspm
; i
++) {
729 SWAP_32(typ2
->map2_st
[index
]);
730 m
->udm_spaddr
[i
] = addr
+ i
* mp_sz
;
732 off
= m
->udm_loc
[i
] * h
->udfs
.lbsize
;
733 if (ud_read_dev(h
, off
,
734 (uint8_t *)m
->udm_spaddr
[i
],
736 m
->udm_spaddr
[i
] = NULL
;
745 ph
= (struct pmap_hdr
*)(((uint8_t *)h
) + ph
->maph_length
);
748 lvds_loc
= SWAP_32(lvd
->lvd_int_seq_ext
.ext_loc
);
749 lvds_len
= SWAP_32(lvd
->lvd_int_seq_ext
.ext_len
);
751 fsd_prn
= SWAP_16(lvd
->lvd_lvcu
.lad_ext_prn
);
752 fsd_loc
= SWAP_32(lvd
->lvd_lvcu
.lad_ext_loc
);
753 fsd_len
= SWAP_32(lvd
->lvd_lvcu
.lad_ext_len
);
758 * Get the latest LVID
760 if (ud_get_latest_lvid(h
, lvds_loc
, lvds_len
) != 0) {
764 if (ud_get_latest_fsd(h
, fsd_prn
, fsd_loc
, fsd_len
) != 0) {
772 ud_get_latest_lvid(ud_handle_t h
, uint32_t lvds_loc
, uint32_t lvds_len
)
774 uint8_t *addr
, *taddr
, *eaddr
;
778 struct log_vol_int_desc
*lvid
;
781 if ((addr
= (uint8_t *)malloc(lvds_len
)) == NULL
) {
785 off
= lvds_loc
* h
->udfs
.lbsize
;
786 if (ud_read_dev(h
, off
, addr
, lvds_len
) != 0) {
790 for (taddr
= addr
, eaddr
= addr
+ h
->udfs
.mvds_len
; taddr
< eaddr
;
791 taddr
+= h
->udfs
.lbsize
, lvds_loc
++) {
794 tag
= (struct tag
*)taddr
;
795 id
= SWAP_16(tag
->tag_id
);
797 * If you cannot verify the tag just skip it
798 * This is not a fatal error
800 if (ud_verify_tag(h
, tag
, id
, lvds_loc
, 1, 0) != 0) {
804 case UD_LOG_VOL_INT
:
807 * Logical Volume Integrity Descriptor
810 lvid
= (struct log_vol_int_desc
*)taddr
;
811 h
->udfs
.lvid_loc
= lvds_loc
;
812 h
->udfs
.lvid_len
= ((uint32_t)
813 &((struct log_vol_int_desc
*)0)->lvid_fst
) +
814 SWAP_32(lvid
->lvid_npart
) * 8 +
815 SWAP_32(lvid
->lvid_liu
);
816 h
->udfs
.lvid_len
= lb_roundup(h
->udfs
.lvid_len
,
820 * It seems we have a next integrity
823 if (SWAP_32(lvid
->lvid_nie
.ext_len
) != 0) {
825 lvds_loc
= SWAP_32(lvid
->lvid_nie
.ext_loc
);
826 lvds_len
= SWAP_32(lvid
->lvid_nie
.ext_len
);
833 * Success fully completed
838 * If you donot undetstand any tag just skip
839 * it. This is not a fatal error
846 if (h
->udfs
.lvid_len
== 0) {
853 ud_get_latest_fsd(ud_handle_t h
, uint16_t fsd_prn
,
854 uint32_t fsd_loc
, uint32_t fsd_len
)
856 uint8_t *addr
, *taddr
, *eaddr
;
859 uint32_t fsds_loc
, fsds_len
;
861 struct file_set_desc
*fsd
;
862 uint32_t old_fsn
= 0;
865 h
->udfs
.fsds_prn
= fsd_prn
;
866 h
->udfs
.fsds_loc
= fsd_loc
;
867 h
->udfs
.fsds_len
= fsd_len
;
869 fsds_loc
= ud_xlate_to_daddr(h
, fsd_prn
, fsd_loc
);
870 fsds_len
= lb_roundup(fsd_len
, h
->udfs
.lbsize
);
872 if ((addr
= (uint8_t *)malloc(fsds_len
)) == NULL
) {
876 off
= fsds_loc
* h
->udfs
.lbsize
;
877 if (ud_read_dev(h
, off
, addr
, fsds_len
) != 0) {
881 for (taddr
= addr
, eaddr
= addr
+ h
->udfs
.mvds_len
; taddr
< eaddr
;
882 taddr
+= h
->udfs
.lbsize
, fsds_loc
++) {
885 tag
= (struct tag
*)taddr
;
886 id
= SWAP_16(tag
->tag_id
);
888 * If you cannot verify the tag just skip it
889 * This is not a fatal error
891 if (ud_verify_tag(h
, tag
, id
, fsds_loc
, 1, 0) != 0) {
895 case UD_FILE_SET_DESC
:
897 fsd
= (struct file_set_desc
*)taddr
;
898 if ((h
->udfs
.fsd_len
== 0) ||
899 (SWAP_32(fsd
->fsd_fs_no
) > old_fsn
)) {
900 old_fsn
= SWAP_32(fsd
->fsd_fs_no
);
901 h
->udfs
.fsd_loc
= fsds_loc
;
902 h
->udfs
.fsd_len
= lb_roundup(512,
905 SWAP_16(fsd
->fsd_root_icb
.lad_ext_prn
);
907 SWAP_32(fsd
->fsd_root_icb
.lad_ext_loc
);
909 SWAP_32(fsd
->fsd_root_icb
.lad_ext_len
);
911 if (SWAP_32(fsd
->fsd_next
.lad_ext_len
) != 0) {
912 fsd_prn
= SWAP_16(fsd
->fsd_next
.lad_ext_prn
);
913 fsd_loc
= SWAP_32(fsd
->fsd_next
.lad_ext_loc
);
914 fsd_len
= SWAP_32(fsd
->fsd_next
.lad_ext_len
);
921 * Success fully completed
926 * If you donot undetstand any tag just skip
927 * it. This is not a fatal error
935 if (h
->udfs
.fsd_len
== 0) {
942 ud_get_num_blks(ud_handle_t h
, uint32_t *blkno
)
945 struct dk_cinfo dki_info
;
949 * Get VTOC from driver
951 if ((error
= ioctl(h
->fd
, DKIOCGVTOC
, (intptr_t)&vtoc
)) != 0) {
956 * Verify if is proper
958 if (vtoc
.v_sanity
!= VTOC_SANE
) {
963 * Get dk_cinfo from driver
965 if ((error
= ioctl(h
->fd
, DKIOCINFO
, (intptr_t)&dki_info
)) != 0) {
969 if (dki_info
.dki_partition
>= V_NUMPAR
) {
974 * Return the size of the partition
976 *blkno
= vtoc
.v_part
[dki_info
.dki_partition
].p_size
;
982 ud_xlate_to_daddr(ud_handle_t h
, uint16_t prn
, uint32_t blkno
)
989 if (prn
< h
->n_maps
) {
991 for (i
= 0; i
< h
->n_parts
; i
++) {
993 if (m
->udm_pn
== p
->udp_number
) {
994 return (p
->udp_start
+ blkno
);
1001 /* ------ END Read and translate the on disk VDS to IN CORE format -------- */
1004 ud_verify_tag(ud_handle_t h
, struct tag
*tag
, uint16_t id
,
1005 uint32_t blockno
, int32_t do_crc
, int32_t print_msg
)
1008 uint8_t *addr
, cksum
= 0;
1013 * Verify Tag Identifier
1015 if (tag
->tag_id
!= SWAP_16(id
)) {
1016 if (print_msg
!= 0) {
1017 (void) fprintf(stderr
,
1018 gettext("tag does not verify tag %x req %x\n"),
1019 SWAP_16(tag
->tag_id
), id
);
1025 * Verify Tag Descriptor Version
1027 if (SWAP_16(tag
->tag_desc_ver
) != h
->udfs
.ecma_version
) {
1028 if (print_msg
!= 0) {
1029 (void) fprintf(stderr
,
1030 gettext("tag version does not match with "
1031 "NSR descriptor version TAG %x NSR %x\n"),
1032 SWAP_16(tag
->tag_desc_ver
),
1033 h
->udfs
.ecma_version
);
1039 * Caliculate Tag Checksum
1041 addr
= (uint8_t *)tag
;
1042 for (i
= 0; i
<= 15; i
++) {
1049 * Verify Tag Checksum
1051 if (cksum
!= tag
->tag_cksum
) {
1052 if (print_msg
!= 0) {
1053 (void) fprintf(stderr
,
1054 gettext("Checksum Does not Verify TAG"
1055 " %x CALC %x\n"), tag
->tag_cksum
, cksum
);
1062 * Do we want to do crc
1065 if (tag
->tag_crc_len
) {
1068 * Caliculate CRC for the descriptor
1070 crc
= ud_crc(addr
+ 0x10, SWAP_16(tag
->tag_crc_len
));
1075 if (crc
!= SWAP_16(tag
->tag_crc
)) {
1076 if (print_msg
!= 0) {
1077 (void) fprintf(stderr
,
1078 gettext("CRC Does not verify"
1079 " TAG %x CALC %x %x\n"),
1080 SWAP_16(tag
->tag_crc
),
1087 * Verify Tag Location
1089 if (SWAP_32(blockno
) != tag
->tag_loc
) {
1090 if (print_msg
!= 0) {
1091 (void) fprintf(stderr
,
1092 gettext("Tag Location Does not verify"
1093 " blockno %x tag_blockno %x\n"),
1094 blockno
, SWAP_32(tag
->tag_loc
));
1105 ud_make_tag(ud_handle_t h
, struct tag
*tag
, uint16_t tag_id
,
1106 uint32_t blkno
, uint16_t crc_len
)
1110 uint8_t *addr
, cksum
= 0;
1112 tag
->tag_id
= SWAP_16(tag_id
);
1113 tag
->tag_desc_ver
= SWAP_16(h
->udfs
.ecma_version
);
1118 * Calicualte and assign CRC, CRC_LEN
1120 addr
= (uint8_t *)tag
;
1121 crc
= ud_crc(addr
+ 0x10, crc_len
);
1122 tag
->tag_crc
= SWAP_16(crc
);
1123 tag
->tag_crc_len
= SWAP_16(crc_len
);
1124 tag
->tag_loc
= SWAP_32(blkno
);
1127 * Caliculate Checksum
1129 for (i
= 0; i
<= 15; i
++) {
1136 tag
->tag_cksum
= cksum
;
1139 /* **************** udf specific subroutines *********************** */
1141 static uint16_t ud_crc_table
[256] = {
1142 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
1143 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
1144 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
1145 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
1146 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
1147 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
1148 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
1149 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
1150 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
1151 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
1152 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
1153 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
1154 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
1155 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
1156 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
1157 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
1158 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
1159 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
1160 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
1161 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
1162 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
1163 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
1164 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
1165 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
1166 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
1167 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
1168 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
1169 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
1170 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
1171 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
1172 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
1173 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
1177 ud_crc(uint8_t *addr
, int32_t len
)
1182 crc
= ud_crc_table
[(crc
>> 8 ^ *addr
++) & 0xff] ^ (crc
<<8);
1188 #define MAXNAMLEN 0x200
1191 #define POUND 0x0023
1193 #define SLASH 0x002F
1194 #define UNDERBAR 0x005F
1197 static uint16_t htoc
[16] = {'0', '1', '2', '3',
1198 '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
1200 * unicode is the string of 16-bot characters
1201 * length is the number of 16-bit characters
1204 UdfTxName(uint16_t *unicode
, int32_t count
)
1206 int32_t i
, j
, k
, lic
, make_crc
, dot_loc
;
1209 if ((unicode
[0] == DOT
) &&
1210 ((count
== 1) || ((count
== 2) && (unicode
[1] == DOT
)))) {
1215 unicode
[0] = UNDERBAR
;
1217 unicode
[2] = htoc
[(uint16_t)(crc
& 0xf000) >> 12];
1218 unicode
[3] = htoc
[(uint16_t)(crc
& 0xf00) >> 8];
1219 unicode
[4] = htoc
[(uint16_t)(crc
& 0xf0) >> 4];
1220 unicode
[5] = htoc
[crc
& 0xf];
1226 for (i
= 0; i
< count
; i
++) {
1230 if (unicode
[i
] == DOT
) {
1233 if ((unicode
[i
] == SLASH
) ||
1234 (unicode
[i
] == NULL
)) {
1235 if (make_crc
== 0) {
1236 for (k
= 0; k
<= i
; k
++) {
1241 if (lic
!= (i
- 1)) {
1242 unicode
[j
++] = UNDERBAR
;
1246 unicode
[j
++] = unicode
[i
];
1251 if (dot_loc
!= -1) {
1252 if ((j
+ 5) > MAXNAMLEN
) {
1253 if ((j
- dot_loc
+ 5) > MAXNAMLEN
) {
1254 j
= MAXNAMLEN
- 5 + dot_loc
;
1256 j
>= dot_loc
; k
--, j
--) {
1257 unicode
[k
] = unicode
[j
];
1262 j
>= dot_loc
; k
--, j
--) {
1263 unicode
[k
] = unicode
[j
];
1269 for (k
= j
; k
>= dot_loc
; k
--) {
1270 unicode
[k
+ 5] = unicode
[k
];
1276 if ((j
+ 5) > MAXNAMLEN
) {
1284 unicode
[k
++] = POUND
;
1285 unicode
[k
++] = htoc
[(uint16_t)(crc
& 0xf000) >> 12];
1286 unicode
[k
++] = htoc
[(uint16_t)(crc
& 0xf00) >> 8];
1287 unicode
[k
++] = htoc
[(uint16_t)(crc
& 0xf0) >> 4];
1288 unicode
[k
++] = htoc
[crc
& 0xf];
1294 * Assumes the output buffer is large
1295 * enough to hold the uncompressed
1300 int32_t numberOfBytes
, /* (Input) number of bytes read from media. */
1301 uint8_t *UDFCompressed
, /* (Input) bytes read from media. */
1302 uint16_t *unicode
) /* (Output) uncompressed unicode characters. */
1305 int32_t returnValue
, unicodeIndex
, byteIndex
;
1309 * Use UDFCompressed to store current byte being read.
1311 compID
= UDFCompressed
[0];
1313 /* First check for valid compID. */
1314 if (compID
!= 8 && compID
!= 16) {
1320 /* Loop through all the bytes. */
1321 while (byteIndex
< numberOfBytes
) {
1324 * Move the first byte to the
1325 * high bits of the unicode char.
1327 unicode
[unicodeIndex
] =
1328 UDFCompressed
[byteIndex
++] << 8;
1330 unicode
[unicodeIndex
] = 0;
1332 if (byteIndex
< numberOfBytes
) {
1334 * Then the next byte to the low bits.
1336 unicode
[unicodeIndex
] |=
1337 UDFCompressed
[byteIndex
++];
1341 returnValue
= unicodeIndex
;
1343 return (returnValue
);
1352 int32_t numberOfChars
, /* (Input) number of unicode characters. */
1353 int32_t compID
, /* (Input) compression ID to be used. */
1354 uint16_t *unicode
, /* (Input) unicode characters to compress. */
1355 uint8_t *UDFCompressed
) /* (Output) compressed string, as bytes. */
1359 if (compID
!= 8 && compID
!= 16) {
1361 * Unsupported compression ID !
1366 * Place compression code in first byte.
1368 UDFCompressed
[0] = (uint8_t)compID
;
1369 (void) strncpy((caddr_t
)&UDFCompressed
[1],
1370 (caddr_t
)unicode
, numberOfChars
);
1371 byteIndex
= numberOfChars
+ 1;
1378 ud_convert2utf8(uint8_t *ibuf
, uint8_t *obuf
, int32_t length
)
1384 buf
= (uint16_t *)obuf
;
1386 size
= UncompressUnicode(length
, ibuf
, buf
);
1388 size
= UdfTxName(buf
, size
);
1390 for (i
= 0; i
< size
; i
++) {
1391 obuf
[i
] = (uint8_t)buf
[i
];
1399 ud_convert2utf16(uint8_t *ibuf
, uint8_t *obuf
, int32_t length
)
1405 ptr
= (uint16_t *)ibuf
;
1406 comp_len
= ud_compressunicode(length
, 8, ptr
, obuf
);
1412 * Assumption code set is zero in udfs
1415 ud_convert2local(int8_t *ibuf
, int8_t *obuf
, int32_t length
)
1418 int32_t i
, comp
, index
;
1421 * Special uncompress code
1422 * written to accomodate solaris wchar_t
1425 for (i
= 0, index
= 1; i
< length
; i
++) {
1427 buf4c
[i
] = ibuf
[index
++] << 8;
1431 if (index
< length
) {
1432 buf4c
[i
] |= ibuf
[index
++];
1435 (void) wcstombs((char *)obuf
, buf4c
, 128);
1439 /* ------------ Routines to print basic structures Part 1 ---------------- */
1444 print_charspec(FILE *fout
, char *name
, struct charspec
*cspec
)
1448 (void) fprintf(fout
,
1449 "%s : %x - \"", name
, cspec
->cs_type
);
1450 for (i
= 0; i
< 63; i
++) {
1451 (void) fprintf(fout
,
1452 "%c", cspec
->cs_info
[i
]);
1454 (void) fprintf(fout
, "\n");
1459 print_dstring(FILE *fout
, char *name
, uint16_t cset
, char *bufc
, uint8_t length
)
1463 ud_convert2local(bufc
, bufmb
, length
);
1465 (void) fprintf(fout
,
1466 "%s %s\n", name
, bufmb
);
1470 set_dstring(dstring_t
*dp
, char *cp
, int32_t len
)
1475 length
= strlen(cp
);
1476 if (length
> len
- 1) {
1479 (void) strncpy(dp
, cp
, length
);
1480 dp
[len
- 1] = length
;
1484 print_tstamp(FILE *fout
, char *name
, tstamp_t
*ts
)
1486 (void) fprintf(fout
, "%s tz : %d yr : %d mo : %d da : %d "
1487 "Time : %d : %d : %d : %d : %d : %d\n", name
,
1488 SWAP_16(ts
->ts_tzone
), SWAP_16(ts
->ts_year
), ts
->ts_month
,
1489 ts
->ts_day
, ts
->ts_hour
, ts
->ts_min
, ts
->ts_sec
, ts
->ts_csec
,
1490 ts
->ts_husec
, ts
->ts_usec
);
1496 make_regid(ud_handle_t h
, struct regid
*reg
, char *id
, int32_t type
)
1499 (void) strncpy(reg
->reg_id
, id
, 23);
1501 if (type
== REG_DOM_ID
) {
1502 struct dom_id_suffix
*dis
;
1505 dis
= (struct dom_id_suffix
*)reg
->reg_ids
;
1506 dis
->dis_udf_revison
= SWAP_16(h
->udfs
.ma_write
);
1507 dis
->dis_domain_flags
= 0;
1509 } else if (type
== REG_UDF_ID
) {
1510 struct udf_id_suffix
*uis
;
1513 uis
= (struct udf_id_suffix
*)reg
->reg_ids
;
1514 uis
->uis_udf_revision
= SWAP_16(h
->udfs
.ma_write
);
1515 uis
->uis_os_class
= OS_CLASS_UNIX
;
1516 uis
->uis_os_identifier
= OS_IDENTIFIER_SOLARIS
;
1517 } else if (type
== REG_UDF_II
) {
1518 struct impl_id_suffix
*iis
;
1520 iis
= (struct impl_id_suffix
*)reg
->reg_ids
;
1521 iis
->iis_os_class
= OS_CLASS_UNIX
;
1522 iis
->iis_os_identifier
= OS_IDENTIFIER_SOLARIS
;
1527 print_regid(FILE *fout
, char *name
, struct regid
*reg
, int32_t type
)
1529 (void) fprintf(fout
, "%s : 0x%x : \"%s\" :",
1530 name
, reg
->reg_flags
, reg
->reg_id
);
1532 if (type
== REG_DOM_ID
) {
1533 struct dom_id_suffix
*dis
;
1536 dis
= (struct dom_id_suffix
*)reg
->reg_ids
;
1537 (void) fprintf(fout
, " 0x%x : %s : %s\n",
1538 SWAP_16(dis
->dis_udf_revison
),
1539 (dis
->dis_domain_flags
& PROTECT_SOFT_WRITE
) ?
1540 "HW Protect" : "No HW Write Protect",
1541 (dis
->dis_domain_flags
& PROTECT_HARD_WRITE
) ?
1542 "SW Protect" : "No SW Protect");
1543 } else if (type
== REG_UDF_ID
) {
1544 struct udf_id_suffix
*uis
;
1547 uis
= (struct udf_id_suffix
*)reg
->reg_ids
;
1548 (void) fprintf(fout
,
1549 " 0x%x : OS Class 0x%x : OS Identifier 0x%x\n",
1550 SWAP_16(uis
->uis_udf_revision
),
1551 uis
->uis_os_class
, uis
->uis_os_identifier
);
1553 struct impl_id_suffix
*iis
;
1555 iis
= (struct impl_id_suffix
*)reg
->reg_ids
;
1556 (void) fprintf(fout
,
1557 " OS Class 0x%x : OS Identifier 0x%x\n",
1558 iis
->iis_os_class
, iis
->iis_os_identifier
);
1564 print_regid(FILE *fout
, char *name
, struct regid
*reg
)
1566 (void) fprintf(fout
, "%s : 0x%x : \"%s\" :",
1567 name
, reg
->reg_flags
, reg
->reg_id
);
1569 if (strncmp(reg
->reg_id
, "*OSTA UDF Compliant", 19) == 0) {
1570 (void) fprintf(fout
, " 0x%x : %s : %s\n",
1571 reg
->reg_ids
[0] | (reg
->reg_ids
[1] << 8),
1572 (reg
->reg_ids
[2] & 1) ?
1573 "HW Protect" : "No HW Write Protect",
1574 (reg
->reg_ids
[2] & 2) ?
1575 "SW Protect" : "No SW Protect");
1576 } else if ((strncmp(reg
->reg_id
, "*UDF Virtual Partition", 22) == 0) ||
1577 (strncmp(reg
->reg_id
, "*UDF Sparable Partition", 23) == 0) ||
1578 (strncmp(reg
->reg_id
, "*UDF Virtual Alloc Tbl", 22) == 0) ||
1579 (strncmp(reg
->reg_id
, "*UDF Sparing Table", 18) == 0)) {
1580 (void) fprintf(fout
,
1581 " 0x%x : OS Class 0x%x : OS Identifier 0x%x\n",
1582 reg
->reg_ids
[0] | (reg
->reg_ids
[1] << 8),
1583 reg
->reg_ids
[2], reg
->reg_ids
[3]);
1585 (void) fprintf(fout
,
1586 " OS Class 0x%x : OS Identifier 0x%x\n",
1587 reg
->reg_ids
[0], reg
->reg_ids
[1]);
1593 /* ------------ Routines to print basic structures Part 2 ---------------- */
1596 * This part is OS specific and is currently
1600 /* ------------ Routines to print basic structures Part 3 ---------------- */
1603 print_ext_ad(FILE *fout
, char *name
, struct extent_ad
*ead
)
1605 (void) fprintf(fout
,
1606 "%s EAD Len %x Loc %x\n",
1607 name
, SWAP_32(ead
->ext_len
), SWAP_32(ead
->ext_loc
));
1611 print_tag(FILE *fout
, struct tag
*tag
)
1613 (void) fprintf(fout
,
1614 "tag_id : %x ver : %x cksum : %x "
1615 "sno : %x crc : %x crc_len : %x loc : %x\n",
1616 SWAP_16(tag
->tag_id
), SWAP_16(tag
->tag_desc_ver
),
1617 tag
->tag_cksum
, SWAP_16(tag
->tag_sno
),
1618 SWAP_16(tag
->tag_crc
), SWAP_16(tag
->tag_crc_len
),
1619 SWAP_32(tag
->tag_loc
));
1624 print_pvd(FILE *fout
, struct pri_vol_desc
*pvd
)
1626 (void) fprintf(fout
,
1627 "\n\t\t\tPrimary Volume Descriptor\n");
1628 print_tag(fout
, &pvd
->pvd_tag
);
1629 (void) fprintf(fout
, "vdsn : %x vdn : %x\n",
1630 SWAP_32(pvd
->pvd_vdsn
), SWAP_32(pvd
->pvd_pvdn
));
1631 print_dstring(fout
, "volid : ", pvd
->pvd_desc_cs
.cs_type
,
1632 pvd
->pvd_vol_id
, 32);
1633 (void) fprintf(fout
,
1634 "vsn : %x mvsn : %x il : %x mil :"
1635 " %x csl : %x mcsl %x\n",
1636 SWAP_16(pvd
->pvd_vsn
), SWAP_16(pvd
->pvd_mvsn
),
1637 SWAP_16(pvd
->pvd_il
), SWAP_16(pvd
->pvd_mil
),
1638 SWAP_32(pvd
->pvd_csl
), SWAP_32(pvd
->pvd_mcsl
));
1639 print_dstring(fout
, "vsid :", pvd
->pvd_desc_cs
.cs_type
,
1641 print_charspec(fout
, "desc_cs", &pvd
->pvd_desc_cs
);
1642 print_charspec(fout
, "exp_cs", &pvd
->pvd_exp_cs
);
1643 print_ext_ad(fout
, "val ", &pvd
->pvd_vol_abs
);
1644 print_ext_ad(fout
, "vcnl ", &pvd
->pvd_vcn
);
1645 print_regid(fout
, "ai", &pvd
->pvd_appl_id
, REG_UDF_II
);
1646 print_regid(fout
, "ii", &pvd
->pvd_ii
, REG_UDF_II
);
1647 (void) fprintf(fout
, "pvdsl : %x flags : %x\n",
1648 SWAP_32(pvd
->pvd_pvdsl
),
1649 SWAP_16(pvd
->pvd_flags
));
1653 print_avd(FILE *fout
, struct anch_vol_desc_ptr
*avdp
)
1655 (void) fprintf(fout
,
1656 "\n\t\t\tAnchor Volume Descriptor\n");
1657 print_tag(fout
, &avdp
->avd_tag
);
1658 print_ext_ad(fout
, "Main Volume Descriptor Sequence : ",
1659 &avdp
->avd_main_vdse
);
1660 print_ext_ad(fout
, "Reserve Volume Descriptor Sequence : ",
1661 &avdp
->avd_res_vdse
);
1665 print_vdp(FILE *fout
, struct vol_desc_ptr
*vdp
)
1667 (void) fprintf(fout
,
1668 "\n\t\t\tVolume Descriptor Pointer\n");
1669 print_tag(fout
, &vdp
->vdp_tag
);
1670 (void) fprintf(fout
, "vdsn : %x ",
1671 SWAP_32(vdp
->vdp_vdsn
));
1672 print_ext_ad(fout
, "vdse ", &vdp
->vdp_nvdse
);
1676 print_iuvd(FILE *fout
, struct iuvd_desc
*iuvd
)
1678 (void) fprintf(fout
,
1679 "\n\t\t\tImplementation Use Volume Descriptor\n");
1680 print_tag(fout
, &iuvd
->iuvd_tag
);
1681 (void) fprintf(fout
,
1682 "vdsn : %x ", SWAP_32(iuvd
->iuvd_vdsn
));
1683 print_regid(fout
, "Impl Id : ", &iuvd
->iuvd_ii
, REG_UDF_ID
);
1684 print_charspec(fout
, "cset ", &iuvd
->iuvd_cset
);
1685 print_dstring(fout
, "lvi : ", iuvd
->iuvd_cset
.cs_type
,
1686 iuvd
->iuvd_lvi
, 128);
1687 print_dstring(fout
, "ifo1 : ", iuvd
->iuvd_cset
.cs_type
,
1688 iuvd
->iuvd_ifo1
, 36);
1689 print_dstring(fout
, "ifo2 : ", iuvd
->iuvd_cset
.cs_type
,
1690 iuvd
->iuvd_ifo2
, 36);
1691 print_dstring(fout
, "ifo3 : ", iuvd
->iuvd_cset
.cs_type
,
1692 iuvd
->iuvd_ifo3
, 36);
1694 print_regid(fout
, "iid ", &iuvd
->iuvd_iid
, REG_UDF_II
);
1698 print_part(FILE *fout
, struct part_desc
*pd
)
1700 (void) fprintf(fout
,
1701 "\n\t\t\tPartition Descriptor\n");
1702 print_tag(fout
, &pd
->pd_tag
);
1703 (void) fprintf(fout
,
1704 "vdsn : %x flags : %x num : %x ",
1705 SWAP_32(pd
->pd_vdsn
),
1706 SWAP_16(pd
->pd_pflags
),
1707 SWAP_16(pd
->pd_pnum
));
1708 print_regid(fout
, "contents ", &pd
->pd_pcontents
, REG_UDF_II
);
1710 print_phdr(fout
, (struct phdr_desc
*)(&pd
->pd_pc_use
));
1711 (void) fprintf(fout
,
1712 "acc : %x start : %x length : %x ",
1713 SWAP_32(pd
->pd_acc_type
),
1714 SWAP_32(pd
->pd_part_start
),
1715 SWAP_32(pd
->pd_part_length
));
1716 print_regid(fout
, "Impl Id : ", &pd
->pd_ii
, REG_UDF_II
);
1720 print_lvd(FILE *fout
, struct log_vol_desc
*lvd
)
1722 (void) fprintf(fout
,
1723 "\n\t\t\tLogical Volume Descriptor\n");
1724 print_tag(fout
, &lvd
->lvd_tag
);
1725 (void) fprintf(fout
,
1726 "vdsn : %x ", SWAP_32(lvd
->lvd_vdsn
));
1727 print_charspec(fout
, "Desc Char Set ", &lvd
->lvd_desc_cs
);
1728 print_dstring(fout
, "lvid : ", lvd
->lvd_desc_cs
.cs_type
,
1730 (void) fprintf(fout
,
1732 SWAP_32(lvd
->lvd_log_bsize
));
1733 print_regid(fout
, "Dom Id", &lvd
->lvd_dom_id
, REG_DOM_ID
);
1734 print_long_ad(fout
, "lvcu", &lvd
->lvd_lvcu
);
1735 (void) fprintf(fout
,
1736 "mtlen : %x nmaps : %x ",
1737 SWAP_32(lvd
->lvd_mtbl_len
),
1738 SWAP_32(lvd
->lvd_num_pmaps
));
1739 print_regid(fout
, "Impl Id : ", &lvd
->lvd_ii
, REG_UDF_II
);
1740 print_ext_ad(fout
, "Int Seq", &lvd
->lvd_int_seq_ext
);
1741 print_pmaps(fout
, lvd
->lvd_pmaps
, SWAP_32(lvd
->lvd_num_pmaps
));
1745 print_usd(FILE *fout
, struct unall_spc_desc
*ua
)
1749 (void) fprintf(fout
,
1750 "\n\t\t\tUnallocated Space Descriptor\n");
1751 print_tag(fout
, &ua
->ua_tag
);
1752 count
= SWAP_32(ua
->ua_nad
);
1753 (void) fprintf(fout
,
1754 "vdsn : %x nad : %x\n",
1755 SWAP_32(ua
->ua_vdsn
), count
);
1756 for (i
= 0; i
< count
; i
++) {
1757 (void) fprintf(fout
,
1758 "loc : %x len : %x\n",
1759 SWAP_32(ua
->ua_al_dsc
[i
* 2]),
1760 SWAP_32(ua
->ua_al_dsc
[i
* 2 + 1]));
1765 print_lvid(FILE *fout
, struct log_vol_int_desc
*lvid
)
1769 struct lvid_iu
*liu
;
1771 (void) fprintf(fout
,
1772 "\n\t\t\tLogical Volume Integrity Descriptor\n");
1773 print_tag(fout
, &lvid
->lvid_tag
);
1774 print_tstamp(fout
, "Rec TM ", &lvid
->lvid_tstamp
);
1775 if (SWAP_32(lvid
->lvid_int_type
) == 0) {
1776 (void) fprintf(fout
,
1777 "int_typ : Open\n");
1778 } else if (SWAP_32(lvid
->lvid_int_type
) == 1) {
1779 (void) fprintf(fout
, "int_typ : Closed\n");
1781 (void) fprintf(fout
, "int_typ : Unknown\n");
1783 print_ext_ad(fout
, "Nie ", &lvid
->lvid_nie
);
1784 count
= SWAP_32(lvid
->lvid_npart
);
1785 (void) fprintf(fout
,
1786 "Uniq : %llx npart : %x liu : %x\n",
1787 SWAP_64(lvid
->lvid_lvcu
.lvhd_uniqid
),
1788 count
, SWAP_32(lvid
->lvid_liu
));
1789 for (i
= 0; i
< count
; i
++) {
1790 (void) fprintf(fout
,
1791 "Part : %x Free : %x Size : %x\n",
1792 i
, SWAP_32(lvid
->lvid_fst
[i
]),
1793 SWAP_32(lvid
->lvid_fst
[count
+ i
]));
1796 addr
= (caddr_t
)lvid
->lvid_fst
;
1798 liu
= (struct lvid_iu
*)(addr
+ 2 * count
* 4);
1799 print_regid(fout
, "Impl Id :", &liu
->lvidiu_regid
, REG_UDF_II
);
1800 (void) fprintf(fout
,
1801 "nfiles : %x ndirs : %x miread : %x"
1802 " miwrite : %x mawrite : %x\n",
1803 SWAP_32(liu
->lvidiu_nfiles
), SWAP_32(liu
->lvidiu_ndirs
),
1804 SWAP_16(liu
->lvidiu_mread
), SWAP_16(liu
->lvidiu_mwrite
),
1805 SWAP_16(liu
->lvidiu_maxwr
));
1809 /* ------------ Routines to print basic structures Part 4 ---------------- */
1812 print_fsd(FILE *fout
, ud_handle_t h
, struct file_set_desc
*fsd
)
1814 (void) fprintf(fout
,
1815 "\n\t\t\tFile Set Descriptor\n");
1817 print_tag(fout
, &fsd
->fsd_tag
);
1818 print_tstamp(fout
, "Rec TM ", &fsd
->fsd_time
);
1819 (void) fprintf(fout
,
1820 "ilvl : %x milvl : %x csl : %x"
1821 " mcsl : %x fsn : %x fsdn : %x\n",
1822 SWAP_16(fsd
->fsd_ilevel
), SWAP_16(fsd
->fsd_mi_level
),
1823 SWAP_32(fsd
->fsd_cs_list
), SWAP_32(fsd
->fsd_mcs_list
),
1824 SWAP_32(fsd
->fsd_fs_no
), SWAP_32(fsd
->fsd_fsd_no
));
1825 print_charspec(fout
, "ID CS ", &fsd
->fsd_lvidcs
);
1826 print_dstring(fout
, "lvi : ", fsd
->fsd_lvidcs
.cs_type
,
1827 fsd
->fsd_lvid
, 128);
1828 print_charspec(fout
, "ID CS ", &fsd
->fsd_fscs
);
1829 print_dstring(fout
, "fsi : ", fsd
->fsd_lvidcs
.cs_type
,
1831 print_dstring(fout
, "cfi : ", fsd
->fsd_lvidcs
.cs_type
,
1833 print_dstring(fout
, "afi : ", fsd
->fsd_lvidcs
.cs_type
,
1835 print_long_ad(fout
, "Ricb ", &fsd
->fsd_root_icb
);
1836 print_regid(fout
, "DI ", &fsd
->fsd_did
, REG_DOM_ID
);
1837 print_long_ad(fout
, "Next Fsd ", &fsd
->fsd_next
);
1838 if (h
->udfs
.ecma_version
== UD_ECMA_VER3
) {
1839 print_long_ad(fout
, "System Stream Directory ICB ",
1845 print_phdr(FILE *fout
, struct phdr_desc
*ph
)
1847 print_short_ad(fout
, "ust ", &ph
->phdr_ust
);
1848 print_short_ad(fout
, "usb ", &ph
->phdr_usb
);
1849 print_short_ad(fout
, "int ", &ph
->phdr_it
);
1850 print_short_ad(fout
, "fst ", &ph
->phdr_fst
);
1851 print_short_ad(fout
, "fsh ", &ph
->phdr_fsb
);
1855 print_fid(FILE *fout
, struct file_id
*fid
)
1860 (void) fprintf(fout
,
1861 "File Identifier Descriptor\n");
1862 print_tag(fout
, &fid
->fid_tag
);
1863 (void) fprintf(fout
, "fvn : %x fc : %x length : %x ",
1864 fid
->fid_ver
, fid
->fid_flags
, fid
->fid_idlen
);
1865 print_long_ad(fout
, "ICB", &fid
->fid_icb
);
1866 addr
= &fid
->fid_spec
[SWAP_16(fid
->fid_iulen
)];
1867 (void) fprintf(fout
, "iulen : %x comp : %x name : ",
1868 SWAP_16(fid
->fid_iulen
), *addr
);
1870 for (i
= 0; i
< fid
->fid_idlen
; i
++) {
1871 (void) fprintf(fout
, "%c", *addr
++);
1873 (void) fprintf(fout
, "\n");
1877 print_aed(FILE *fout
, struct alloc_ext_desc
*aed
)
1879 (void) fprintf(fout
,
1880 "Allocation Extent Descriptor\n");
1881 print_tag(fout
, &aed
->aed_tag
);
1882 (void) fprintf(fout
, "prev ael loc : %x laed : %x\n",
1883 SWAP_32(aed
->aed_rev_ael
), SWAP_32(aed
->aed_len_aed
));
1886 static char *ftype
[] = {
1887 "NON", "USE", "PIE", "IE",
1888 "DIR", "REG", "BDEV", "CDEV",
1889 "EATT", "FIFO", "SOCK", "TERM",
1894 print_icb_tag(FILE *fout
, struct icb_tag
*itag
)
1896 (void) fprintf(fout
,
1897 "prnde : %x strat : %x param : %x max_ent %x\n",
1898 SWAP_32(itag
->itag_prnde
), SWAP_16(itag
->itag_strategy
),
1899 SWAP_16(itag
->itag_param
), SWAP_16(itag
->itag_max_ent
));
1900 (void) fprintf(fout
,
1901 "ftype : %s prn : %x loc : %x flags : %x\n",
1902 (itag
->itag_ftype
>= 14) ? ftype
[0] : ftype
[itag
->itag_ftype
],
1903 SWAP_16(itag
->itag_lb_prn
),
1904 SWAP_32(itag
->itag_lb_loc
), SWAP_16(itag
->itag_flags
));
1909 print_ie(FILE *fout
, struct indirect_entry
*ie
)
1911 (void) fprintf(fout
,
1912 "Indirect Entry\n");
1913 print_tag(fout
, &ie
->ie_tag
);
1914 print_icb_tag(fout
, &ie
->ie_icb_tag
);
1915 print_long_ad(fout
, "ICB", &ie
->ie_indirecticb
);
1919 print_td(FILE *fout
, struct term_desc
*td
)
1921 (void) fprintf(fout
,
1922 "Terminating Descriptor\n");
1923 print_tag(fout
, &td
->td_tag
);
1927 print_fe(FILE *fout
, struct file_entry
*fe
)
1929 (void) fprintf(fout
,
1931 print_tag(fout
, &fe
->fe_tag
);
1932 print_icb_tag(fout
, &fe
->fe_icb_tag
);
1933 (void) fprintf(fout
,
1934 "uid : %x gid : %x perms : %x nlnk : %x\n",
1935 SWAP_32(fe
->fe_uid
), SWAP_32(fe
->fe_gid
),
1936 SWAP_32(fe
->fe_perms
), SWAP_16(fe
->fe_lcount
));
1937 (void) fprintf(fout
,
1938 "rec_for : %x rec_dis : %x rec_len : %x "
1939 "sz : %llx blks : %llx\n",
1940 fe
->fe_rec_for
, fe
->fe_rec_dis
, SWAP_32(fe
->fe_rec_len
),
1941 SWAP_64(fe
->fe_info_len
), SWAP_64(fe
->fe_lbr
));
1942 print_tstamp(fout
, "ctime ", &fe
->fe_acc_time
);
1943 print_tstamp(fout
, "mtime ", &fe
->fe_mod_time
);
1944 print_tstamp(fout
, "atime ", &fe
->fe_attr_time
);
1945 (void) fprintf(fout
,
1946 "ckpoint : %x ", SWAP_32(fe
->fe_ckpoint
));
1947 print_long_ad(fout
, "ICB", &fe
->fe_ea_icb
);
1948 print_regid(fout
, "impl", &fe
->fe_impl_id
, REG_UDF_II
);
1949 (void) fprintf(fout
,
1950 "uniq_id : %llx len_ear : %x len_adesc %x\n",
1951 SWAP_64(fe
->fe_uniq_id
), SWAP_32(fe
->fe_len_ear
),
1952 SWAP_32(fe
->fe_len_adesc
));
1956 print_pmaps(FILE *fout
, uint8_t *addr
, int32_t count
)
1958 struct pmap_hdr
*hdr
;
1959 struct pmap_typ1
*map1
;
1960 struct pmap_typ2
*map2
;
1963 hdr
= (struct pmap_hdr
*)addr
;
1964 switch (hdr
->maph_type
) {
1967 map1
= (struct pmap_typ1
*)hdr
;
1968 (void) fprintf(fout
, "Map type 1 ");
1969 (void) fprintf(fout
, "VSN %x prn %x\n",
1970 SWAP_16(map1
->map1_vsn
),
1971 SWAP_16(map1
->map1_pn
));
1975 map2
= (struct pmap_typ2
*)hdr
;
1976 (void) fprintf(fout
, "Map type 2 ");
1977 (void) fprintf(fout
, "VSN %x prn %x\n",
1978 SWAP_16(map2
->map2_vsn
),
1979 SWAP_16(map2
->map2_pn
));
1980 print_regid(fout
, "Partition Type Identifier",
1981 &map2
->map2_pti
, REG_UDF_ID
);
1984 (void) fprintf(fout
, "unknown map type\n");
1986 addr
+= hdr
->maph_length
;
1993 print_short_ad(FILE *fout
, char *name
, struct short_ad
*sad
)
1995 (void) fprintf(fout
,
1996 "%s loc : %x len : %x\n", name
,
1997 SWAP_32(sad
->sad_ext_loc
), SWAP_32(sad
->sad_ext_len
));
2001 print_long_ad(FILE *fout
, char *name
, struct long_ad
*lad
)
2003 (void) fprintf(fout
,
2004 "%s prn : %x loc : %x len : %x\n", name
,
2005 SWAP_16(lad
->lad_ext_prn
), SWAP_32(lad
->lad_ext_loc
),
2006 SWAP_32(lad
->lad_ext_len
));