ISO 9660: Difference between revisions

6,781 bytes added ,  14 years ago
Added flags and time field formats along with a basic step-by-step 'loading a file' guide.
[unchecked revision][unchecked revision]
(Added Volume Descriptor Set Terminator field.)
(Added flags and time field formats along with a basic step-by-step 'loading a file' guide.)
Line 14:
=== Numerical Formats ===
 
Another quirk of the system is that it has several numbering formats and multi-byte numbers are often represented in "both-endian" format (that is, LSB first followed by MSB first). For this reason, 32 bit LBA's often appear in 8 byte fields. ISO 9660 section 7.3, for example, outlines these 32 bit systems and numbers throughout the documents are referred to as being 7.3.1 format (LSB first), 7.3.2 format (MSB first) or 7.3.3 format (both-endian). Where a both-endian format exists, the x86 architecture makes use of the first 32 bit sequence (the LSB-first sequence) and ignores bytes 4-7.
 
=== Permitted Characters ===
Line 68:
When starting out with a basic CD, we are going to be interested in the Primary Volume Descriptor, which points us to the root directory and path tables, which both allow us to find any file on the CD. Using the path table is ideal for minimal implementations which do not wish to search the directory heirarchy node by node. This is slower (string comparisons across the entire filesystem) but easier to implement.
 
==== Volume Descriptor Set Terminator ====
The Volume Descriptor Set Terminator does not currently define bytes 7-2047 of its Volume Descriptor. This means that the only fields in use for the volume set terminator are the type code (255), the standard identifier ('CD001') and the descriptor version (0x01).
 
Line 195:
 
All fields except for the offset from GMT are in ASCII digits. An unspecified date and time is represented by 16 '0' digits, followed by a zero in the last field.
 
== The Path Table ==
The Path Table contains a well-ordered sequence of records describing every directory extent on the CD. There are some exceptions with this: the Path Table can only contain 65536 records, due to the length of the "Parent Directory Number" field. If there are more than this number of directories on the disc, some CD authoring software will ignore this limit and create a non-compliant CD (this applies to some earlier versions of Nero, for example). If your file system uses the path table, you should be aware of this possibility. Windows uses the Path Table and will fail with such non-compliant CD's (additional nodes exist but appear as zero-byte). Linux, which uses the directory tables is not affected by this issue.
 
The location of the path tables can be found in the Primary Volume Descriptor. There are two table types - the L-Path table (relevant to x86) and the M-Path table. The only difference between these two tables is that multi-byte values in the L-Table are LSB-first and the values in the M-Table are MSB-first.
 
The structure of a Path Table Entry is as follows:
{| {{wikitable}}
!Offset
!Size
!Description
|-
| 0 || 1 || Length of Directory Identifier
|-
| 1 || 1 || Extended Attribute Record Length
|-
| 2 || 4 || Location of Extent (LBA). This is in a different format depending on whether this is the L-Table or M-Table (see explanation above).
|-
| 6 || 2 || Directory number of parent directory (an index in to the path table). This is the field that limits the table to 65536 records.
|-
| 8 || (variable) || Directory Identifier (name) in d-characters.
|-
| (variable) || 1 || Padding Field - contains a zero if the Length of Directory Identifier field is odd, not present otherwise. This means that each table entry will always start on an even byte number.
|}
 
The path table is in ascending order of directory level and is alphabetically sorted within each directory level.
 
== Directories ==
At some point when reading from an ISO 9660 CD, you will need a directory record to locate a file, even if you generally use the path table to locate the directory initially. Unlike the path tables, there is only one version of each directory table, and multi byte numbers are in both-endian format. A directory record is laid out as follows:
 
{| {{wikitable}}
!Offset
!Size
!Description
|-
| 0 || 1 || Length of Directory Record.
|-
| 1 || 1 || Extended Attribute Record length.
|-
| 2 || 8 || Location of extent (LBA) in both-endian format.
|-
| 10 || 8 || Data length (size of extent) in both-endian format.
|-
| 18 || 7 || Recording date and time (see format below).
|-
| 25 || 1 || File flags (see below).
|-
| 26 || 1 || File unit size for files recorded in interleaved mode, zero otherwise.
|-
| 27 || 1 || Interleave gap size for files recorded in interleaved mode, zero otherwise.
|-
| 28 || 4 || Volume sequence number - the volume that this extent is recorded on, in 16 bit both-endian format.
|-
| 32 || 1 || Length of file identifier (file name). This terminates with a ';' character followed by the file ID number in ASCII coded decimal ('1').
|-
| 33 || (variable) || Length of file identifier.
|-
| (variable) || 1 || Padding field - zero if length of file identifier is odd, otherwise, this field is not present. This means that a directory entry will always start on an even byte number.
|}
 
Even if a directory spans multiple sectors, the directory entries are not permitted to cross the sector boundary (unlike the path table). Where there is not enough space to record an entire directory entry at the end of a sector, that sector is zero-padded and the next consecutive sector is used. Some of the above fields need explanation. Unfortunately, the date/time format is different from that used in the Primary Volume Descriptor. The Date/Time format is:
 
{| {{wikitable}}
!Offset
!Size
!Description
|-
| 0 || 1 || Number of years since 1900.
|-
| 1 || 1 || Month of the year from 1 to 12.
|-
| 2 || 1 || Day of the month from 1 to 31.
|-
| 3 || 1 || Hour of the day from 0 to 23.
|-
| 4 || 1 || Minute of the hour from 0 to 59.
|-
| 5 || 1 || Second of the minute from 0 to 59.
| -
| 6 || 1 || Offset from GMT in 15 minute intervals from -48 (West) to +52 (East).
|}
 
This is quite a contrast to the PVD which contains ASCII encoded decimal values, but this format is presumably used to save disc space over a large number of entries.
 
The other field that needs some explanation is the File Flags field. This is represented by one bit flags as follows:
{| {{wikitable}}
!Bit
!Description
|-
| 0 || If set, the existence of this file need not be made known to the user (basically a 'hidden' flag.
|-
| 1 || If set, this record describes a directory (in other words, it is a subdirectory extent).
|-
| 2 || If set, this file is an "Associated File".
|-
| 3 || If set, the extended attribute record contains information about the format of this file.
|-
| 4 || If set, owner and group permissions are set in the extended attribute record.
|-
| 5 & 6 || Reserved
|-
| 7 || If set, this is not the final directory record for this file (for files spanning several extents, for example files over 4GiB long.
|}
 
== Locating Data on the CD ==
By now, you should be able to see that there are two main ways to navigate to a file record. You an either search the path table, or you can search the full directory structure. You may find it more convenient and faster to cache the path table, loading directories only when necessary.
 
=== Searching the Path Table ===
If you are using the Path Table method, you will still need to know about Directory Records to find the file you are looking for. Basically, you search the path in a reverse order, following the "Parent Directory" links in the Path Table. Once you have located the directory containing the file you want, load that Directory and scan it for the appropriate file name.
 
=== Recursing from the Root Directory ===
Alternatively, you can ignore the Path Table and just cache the root directory from the Primary Volume Descriptor. You then load each directory in turn. For example, for the path '/BOOT/MYLOADER/STAGE2.BIN'
 
# Read the PVD in to memory. Bytes 156-189 contain the root directory entry.
# Load the root directory by reading the LBA and Length values in this root directory entry.
# Scan the directory entry identifiers for 'BOOT;1'.
# If found, use the LBA and length values to load the 'BOOT' directory in to memory.
# Repeat steps 3 and 4 for the file identifier 'MYLOADER;1'.
# Scan the 'MYLOADER' directory for 'STAGE2.BIN;1'. If found, you can now use the LBA value to load your file in to memory.
 
== See Also ==
Anonymous user