Files and directories are found through directory records. Each directory is a file (an extent of whole logical blocks) holding one directory record per entry. The root directory’s record is in the volume descriptor; the path table lists every directory so that one can be found without walking the tree. Offsets count from 0; “both 16” and “both 32” are the two-byte-order numbers.
Directory record
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
0 | 1 | uint8 | Length of directory record | The record’s length in bytes, always even. 0 means there are no more records in this logical block: carry on at the next block. |
1 | 1 | uint8 | Extended attribute record length | Blocks of extended attribute record before the file data; usually 0. |
2 | 8 | both 32 | Location of extent | First logical block of the file or directory. |
10 | 8 | both 32 | Data length | Length of this file section in bytes, without any extended attribute record. At most 4 GiB less 1. |
18 | 7 | date | Recording date and time | Seven bytes: years since 1900, month, day, hour, minute, second, and offset from GMT in 15-minute steps (signed, −48 to +52). All zero: not given. |
25 | 1 | bits | File flags | See file flags. |
26 | 1 | uint8 | File unit size | For a file recorded interleaved: the size of each unit in blocks. Otherwise 0. |
27 | 1 | uint8 | Interleave gap size | For an interleaved file: blocks skipped between units. Otherwise 0. |
28 | 4 | both 16 | Volume sequence number | The volume of the set that holds the extent. |
32 | 1 | uint8 | Length of file identifier | LEN_FI. |
33 | LEN_FI | text | File identifier | See identifiers. |
| 33 + LEN_FI | 0 or 1 | – | Padding | One zero byte, present only when LEN_FI is even, so the next field starts on an even offset. |
| … | LEN_SU | bytes | System use | Optional, to the end of the record; not specified by ISO 9660. Rock Ridge and other extensions put their entries here: see SUSP. |
Directory records never cross a logical block boundary. The first two records of
every directory are itself (identifier 00) and its parent (identifier
01); the root’s parent is the root. The rest are sorted by file name, then
extension, then version number (highest version first), comparing names padded with
spaces.
File flags
Bit 0 is the least significant bit.
| Bit | Value | Name | When set |
|---|---|---|---|
| 0 | 0x01 | Existence | The file need not be shown to the user (a hidden file). |
| 1 | 0x02 | Directory | The record is a directory. |
| 2 | 0x04 | Associated file | The file is an associated file (on Macintosh discs, the resource fork). |
| 3 | 0x08 | Record | The file’s structure is given by the record format of its extended attribute record. |
| 4 | 0x10 | Protection | Owner and group are given in the extended attribute record, and its permissions restrict access. |
| 5–6 | 0x20, 0x40 | Reserved | 0. |
| 7 | 0x80 | Multi-extent | This is not the last record of the file: the file continues in the next record’s extent. |
A directory has bits 2, 3 and 7 clear; a file without an extended attribute record has bits 3 and 4 clear.
Identifiers
A file identifier is a name, . (SEPARATOR 1), an extension,
; (SEPARATOR 2) and a version number from 1 to 32,767, such as
README.TXT;1. Either the name or the extension may be empty but not both,
and together they are at most 30 characters. Characters are d-characters (or
d1-characters under a supplementary descriptor). A directory identifier has no
separators or version, is at most 31 characters, and is the single byte
00 or 01 for the current and parent directory. Under an
enhanced descriptor names may be up to 207 bytes, with no separators, extension or
version.
| Level | Restrictions |
|---|---|
| 1 | Each file is one extent. Names at most 8 characters, extensions at most 3, directory names at most 8 (the “8.3” names). |
| 2 | Each file is one extent; the general 30- and 31-character limits apply. |
| 3 | No restrictions: a file may be several extents (multi-extent records), which allows files over 4 GiB. |
Directories may be nested at most eight levels deep, root included, except under an enhanced descriptor.
Path table
The path table lists every directory, in order of depth and then of parent and name. It is recorded twice: a type L table with little-endian numbers and a type M table with big-endian numbers. Records are numbered from 1; record 1 is the root.
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
0 | 1 | uint8 | Length of directory identifier | LEN_DI. |
1 | 1 | uint8 | Extended attribute record length | As in the directory record. |
2 | 4 | uint32 (L or M) | Location of extent | First block of the directory. |
6 | 2 | uint16 (L or M) | Parent directory number | The path table record number of the parent; 1 for the root and its children. |
8 | LEN_DI | text | Directory identifier | The name; 00 for the root. |
| 8 + LEN_DI | 0 or 1 | – | Padding | One zero byte when LEN_DI is odd. |
Extended attribute record
Optional, and rare in practice. It fills whole logical blocks at the start of a file’s extent, before the data.
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
0 | 4 | both 16 | Owner identification | 0 if none (and then the group is 0 too). |
4 | 4 | both 16 | Group identification | 0 if none. |
8 | 2 | bits | Permissions | See permissions. |
10 | 17 | date | File creation date | The 17-byte date. |
27 | 17 | date | File modification date | – |
44 | 17 | date | File expiration date | – |
61 | 17 | date | File effective date | – |
78 | 1 | uint8 | Record format | 0 not specified; 1 fixed-length records; 2 variable-length records with little-endian record control words; 3 variable-length with big-endian control words; 4–127 reserved; 128–255 system use. |
79 | 1 | uint8 | Record attributes | How records are shown: 0 line feed before and carriage return after each; 1 the first byte is a Fortran (ISO 1539) carriage control; 2 the record holds its own control characters; 3–255 reserved. |
80 | 4 | both 16 | Record length | Fixed records: their length; variable: the maximum; otherwise 0. |
84 | 32 | a-characters | System identifier | The system that understands the system use fields. |
116 | 64 | bytes | System use | Not specified. |
180 | 1 | uint8 | Extended attribute record version | 1. |
181 | 1 | uint8 | Length of escape sequences | LEN_ESC. |
182 | 64 | – | Reserved | Zeros. |
246 | 4 | both 16 | Length of application use | LEN_AU. |
250 | LEN_AU | bytes | Application use | – |
| 250 + LEN_AU | LEN_ESC | bytes | Escape sequences | Character sets of the file’s contents. |
Permissions
Bit 0 is the least significant bit of the second byte. A set bit forbids; the odd bits are always 1.
| Bit | When set |
|---|---|
| 0 | An owner in a System-class group may not read |
| 2 | An owner in a System-class group may not execute |
| 4 | The owner may not read |
| 6 | The owner may not execute |
| 8 | Of the group’s members, only the owner may read |
| 10 | Of the group’s members, only the owner may execute |
| 12 | Users outside the group may not read |
| 14 | Users outside the group may not execute |
| 1, 3, 5, 7, 9, 11, 13, 15 | Always 1 |
Example
The root directory record stored in a primary volume descriptor, at offset 156 of the descriptor (here 0x809C).
0000809C 22 00 1D 00 00 00 00 00 00 1D 00 08 00 00 00 00 "...............
000080AC 08 00 7B 0B 0E 16 0D 14 00 02 00 00 01 00 00 01 ..{.............
000080BC 01 00 ..
Reading it: length 0x22, 34; no extended attribute record; extent at block
0x1D, 29, in both byte orders; data length 2,048, one block; recorded
7B 0B 0E 16 0D 14 00, which is 1900 + 123 = 2023, 14 November, 22:13:20,
GMT; flags 02, a directory; not interleaved; volume 1; identifier length
1, identifier 00. LEN_FI is odd, so there is no padding byte.