ISO 9660 구조

ISO9660은 CD-ROM의 기본 파일 시스템으로 현재까지 꾸준히 사용되고 있다. ISO 9660은 PC와 같은 특정 플랫폼에 한정된 파일 시스템이 아닌 까닭에 전혀 다른 하드웨어에도 사용된다. 다만 윈도우에서는 유니코드를 지원하는 Joliet 확장 기능을 주로 사용하고 POSIX(유닉스 계열)에서는 Rock Ridge 확장 기능을 사용하는 등 플랫폼에 따라 약간의 차이를 보일 수 있다.

ISO 9660이 하드디스크에서 사용되는 파일 시스템과 근본적으로 다른 부분은, CD-ROM의 특성상 읽기 전용 파일 시스템이라는 것이다. 또한 하드디스크에서는 배드 섹터 등을 고려해서 파일이 여러 섹터에 걸쳐 임의로 분할돼 저장되는 것과는 달리, ISO 9660에서는 기본적으로 파일이 일련의 섹터에 차례로 저장된다. 한편 CD-RW 등의 출현으로 쓰기가 가능한 파일 시스템도 개발되었는데, UDF(Universal Disk Format) 파일 시스템은 하드디스크나 플로피 디스켓처럼 섹터를 미리 작은 블럭 단위로 나누어 포맷한 후, 이 블럭을 기준으로 파일을 쓰고 지우는 동작을 하도록 되어 있다. DVD-ROM의 경우 UDF를 기본 파일 시스템으로 하고 있지만 별도로 UDF-Bridge라는 방식을 적용해서 ISO 9660과 파일 시스템이 혼재하도록 구성되어 있다. 이런 까닭에 ISO 9660을 지원하는 윈도우에서도 DVD 파일 구성의 검색이 가능하게 된다.

ISO 9660의 표준에 대해 깊게 들어가면 실제 사용하지 않은 부분까지 불필요하게 언급할 수 있으므로 여기서는 우리가 PC에서 사용하는 부분으로 범위를 줄여서 다루도록 하겠다. 먼저 하드디스크의 마스터 부트 레코드(MBR, Master Boot Record)에 해당한다고 볼 수있는 프라임 볼륨 디스크립터(PVD, Prime Volume Descriptor)에 대한 내용부터 살펴보기로 하자.

프라임 볼륨 디스크립터

하드디스크에는 MBR을 통해 저장된 정보를 액세스하기 위한 기본 정보를 제공하게 된다. CD-ROM에서는 ‘볼륨 디스크립터(Volume Descriptor)’라는 것이 이에 상응하는 역할을 수행하게 된다. 실제 볼륨 디스크립터에는 여러 가지 종류가 있는데, 이 중에서 가장 중요한 것이 PVD이다. CD-ROM의 섹터 구조를 잠시 살펴보면 처음 16개의 섹터(LBA 0~15)는 사용하지 않는 부분으로, 그 내용은 모두 0으로 채워져 있다. 17번째 섹터(10h)부터는 볼륨 디스크립터들이 차례로 채워지게 된다(<그림 1> 참조). 볼륨 디스크립터란 말 그대로 해당 CD-ROM의 내용을 기술하기 위한 목적으로 사용되며 각각의 볼륨 디스크립터는 1섹터(2048바이트)의 크기를 차지한다. 그 중 가장 처음에 오는 것은 PVD이고, 맨 뒤에 오는 볼륨 디스크립터 셋 터미네이터(Volume Descriptor Set Terminator)는 디스크립터 열의 끝을 나타내게 된다. 즉 이 두 개의 볼륨 디스크립터 사이에는 필요한 만큼의 볼륨 디스크립터들이 임의 길이로 올 수 있게 된다. 규격에는 여러 종류의 디스크립터들이 정의되어 있지만 여기서는 PVD에 집중하기로 하겠다. 우선 PVD를 읽어보기로 하자. PVD는 항상 CD-ROM의 LBA=10h에 위치하게 된다.

CD-ROM 볼륨 디스크림터의 구성
<그림1>CD-ROM 볼륨 디스크림터의 구성

$ rd12 10 1
Read12 done

$ dump_buf 128

E000: 01 43 44 30 30 31 01 00 4C 49 4E 55 58 20 20 20 .CD001.. LINUX
E010: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
E020: 20 20 20 20 20 20 20 20 4D 61 73 6F 39 39 30 36 Maso9906
E030: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
E040: 20 20 20 20 20 20 20 20 00 00 00 00 00 00 00 00 ........
E050: DA 42 04 00 00 04 42 DA 00 00 00 00 00 00 00 00 .B....B. ........
E060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
E070: 00 00 00 00 00 00 00 00 01 00 00 01 01 00 00 01 ........ ........
E080: 00 08 08 00 F4 06 00 00 00 00 06 F4 13 00 00 00 ........ ........
E090: 00 00 00 00 00 00 00 15 00 00 00 00 22 00 17 00 ........ ....”...
E0A0: 00 00 00 00 00 17 00 08 00 00 00 00 08 00 63 05 ........ ......c.
E0B0: 12 04 38 06 24 02 00 00 01 00 00 01 01 00 20 20 ..8.$... ......
E0C0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
E0D0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
...
E230: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 4D 4B MK
E240: 49 53 4F 46 53 20 49 53 4F 20 39 36 36 30 20 46 ISOFS IS O 9660 F
E250: 49 4C 45 53 59 53 54 45 4D 20 42 55 49 4C 44 45 ILESYSTE M BUILDE
E260: 52 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 R
E270: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
...
E310: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
E320: 20 20 20 20 20 20 20 20 20 20 20 20 20 31 39 39 199
E330: 39 30 35 31 38 31 32 35 31 31 34 30 30 24 31 39 90518125 11400$19
E340: 39 39 30 35 31 38 31 32 35 31 31 34 30 30 24 30 99051812 511400$0
E350: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 00 00000000 0000000.
E360: 31 39 39 39 30 35 31 38 31 32 35 31 31 34 30 30 19990518 12511400
E370: 24 01 00 20 20 20 20 20 20 20 20 20 20 20 20 20 $..
E380: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
...
E570: 20 20 20 00 00 00 00 00 00 00 00 00 00 00 00 00 ..... ........
E580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
...
E7F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........

이와 같은 예는 오래 전 본지(마이크로소프트웨어)의 부록으로 제공되었던 리눅스 CD-ROM의 PVD를 읽어낸 것이다. 다음은 PVD의 구성을 구조체 형식으로 표현한 것이다.

struct pvd
{
BYTE vol_desc_type; // 01h
char standard_identifier[5]; // “CD001”
BYTE version; // 01h
BYTE unused; // 00h
char system_identifier[32]; // “LINUX ...”
char volume_identifier[32]; // “Maso9906...”
BYTE unused2[8]; // all zero
DWORD volume_space_size_lend; // DAh 42h 04h 00h
DWORD volume_space_size_bend; // 00h 04h 42h DAh
BYTE unused3[32]; // all zero
WORD volume_set_size_lend; // 01h 00h
WORD volume_set_size_bend; // 00h 01h
WORD volume_sequence_number_lend; // 01h 00h
WORD volume_sequence_number_bend; // 00h 01h
WORD logical_block_size_lend; // 00h 08h
WORD logical_block_size_bend; // 08h 00h
DWORD path_table_size_lend; // F4h 06h 00h 00h
DWORD path_table_size_bend; // 00h 00h 06h F4h
DWORD location_typeL_path_table; // 13h 00h 00h 00h
DWORD location_opt_typeL_path_table; // 00h 00h 00h 00h
DWORD location_typeM_path_table; // 00h 00h 00h 15h
DWORD location_opt_typeM_path_table; // 00h 00h 00h 00h
struct directory_record root_rec; // 34 bytes
char volume_set_identifier[128];
char publisher_identifier[128];
char data_preparer_identifier[128];
char application_identifier[128];
char copyright_file_identifier[37];
char abstract_file_identifier[37];
char bibliographical_file_identifier[37];
char creation_date_time[17];
char modification_date_time[17];
char expiration_date_time[17];
char effective_date_time[17];
BYTE file_structure_version; // 01h
BYTE reserved1; // 00h
char app_use[512];
char reserved2[653];
}

PVD 섹터의 첫 번째 바이트는 디스크립터의 타입을 나타낸다. PVD의 경우 값은 1이다. 디스크립터의 종류별 타입의 값은 다음과 같다.

0 : Boot Record
1 : Primary Volume Descriptor
2 : Supplementary Volume Descriptor
3 : Volume Partition Descriptor
4-FEh : Reserved
FFh : Volume Descriptor Set Terminator

타입 다음에는 아스키 문자열인 “CD001”과 함께 version이 차례로 오게 된다. 이를 통해서 이 디스크의 파일 시스템이 ISO 9660임을 알 수 있다. 다음 시스템 아이덴티파이어와 볼륨 아이덴티파이어는 각각 32바이트 길이의 문자열로 CD-ROM의 내용을 표시한다.
앞서 언급한대로 ISO 9660은 플랫폼에 무관하게 적용될 수 있도록 했기 때문에 기본적인 정보들을 리틀 엔디언 및 빅 엔디언으로 동시에 기록해 두도록 하고 있다. 플랫폼(사용하는 CPU)에 따라서 숫자를 기록하는 방식이 달라지기 때문이다. 따라서 볼륨 아이덴티파이어 이후에 오는 정보들은 일반 문자열을 제외하고는 모두 두 가지 포맷으로 작성되어 있음을 확인할 수 있다. 각 엔트리는 리틀 엔디언, 빅 엔디언 순서로 반복되어 있다. 먼저 volume_space_size는 CD-ROM에 수록된 전체 섹터 수를 나타낸다. 이 예에서는 총 크기가 442DAh로 279258섹터, 약 570MB임을 알 수 있다. 이 값 역시 리틀 엔디언, 빅 엔디언 순으로 기록되어 있다. volume_set_size와 volume_sequence_number는 볼륨이 여러 장의 디스크로 구성되는 경우에 사용되며 여기서는 그 값이 1이다. 다음의 logical_block_size는 섹터의 논리적 크기를 말하는 것으로, 이미 언급되었듯이 800h, 즉 2048바이트이다.
계속해서 이어지는 필드들은 패스 테이블에 관한 것이다. 패스 테이블은 잠시 후에 자세히 다루겠지만, 디렉토리 정보를 요약하여 별도의 섹터에 만들어 둔 디렉토리 정보 테이블로서, 이를 이용하면 전반적인 디스크의 액세스 속도를 높일 수 있다. 패스 테이블은 볼륨 디스크립터 섹터들의 뒤를 이어 위치하게 된다. path_table_size는 패스 테이블 내용 전체의 바이트 단위의 길이를 나타낸다. 여기서는 그 값이 6F4로, 모두 한 섹터 내에 저장이 되는 크기이다. 패스 테이블은 두 번 반복 저장될 수 있으며 각 섹터 역시 리틀 엔디언과 빅 엔디언의 두 종류를 갖게 된다. 따라서 location_typeL_path_table은 첫 번째 패스 테이블의 주소를, location_opt_typeL_path_table은 여분의 패스 테이블 주소를 나타낸다. Type L은 리틀 엔디언 패스 테이블을, Type M은 빅 엔디언 패스 테이블을 나타낸다. 여기서는 첫 번째 패스 테이블만이 사용되고 있고, 여분의 옵션 테이블은 0으로 처리되어 있다.
패스 테이블에 대한 정보 다음에는 루트 디렉토리에 대한 디렉토리 레코드 구조가 저장되어 있다. 디렉토리 레코드의 구조에 대해서는 디렉토리 섹터 부분에서 다루게 된다. 읽거나 참조하기 위한 최종 목표 파일을 찾아가기 위해서는 이 루트 디렉토리부터 차례로 탐색해 나가게 된다. 이후 엔트리들은 문자열로 구성된 각종 아이덴티파이어 및 작성일과 유효 기간 등에 대한 정보를 나타내고 있다. 엔트리의 이름만으로도 충분히 이해될 것이므로 자세한 설명은 생략하기로 하겠다.
참고로 이 디스크에서 PVD 바로 뒤에 오는 섹터를 읽어보자.

$ rd12 11 1
Read12 done

$ dump_buf

E000: 00 43 44 30 30 31 01 45 4C 20 54 4F 52 49 54 4F .CD001.E L TORITO
E010: 20 53 50 45 43 49 46 49 43 41 54 49 4F 4E 00 00 SPECIFI CATION..
E020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
E030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
E040: 00 00 00 00 00 00 00 88 02 00 00 00 00 00 00 00 ........ ........
E050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
...

앞의 볼륨 디스크립터는 타입이 0으로 부트 레코드 볼륨 디스크립터이다. “EL TORITO SPECIFICATION”이라는 문자열을 통해 이 디스크는 부팅 가능한 디스크임을 나타낸다.
이번에는 볼륨 디스크립터 셋 터미네이터를 찾기 위해 그 다음 섹터를 읽어보기로 하겠다.

$ rd12 12 1
Read12 done

$ dump_buf

E000: FF 43 44 30 30 31 01 00 00 00 00 00 00 00 00 00 .CD001.. ........
E010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
E020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
E030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
E040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
E050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
...

이 디스크에서는 부트 레코드 볼륨 디스크립터 바로 뒤에 볼륨 디스크립터 셋 터미네이터가 있다. 앞서 말한 대로 타입 값이 FFh인 것으로 이를 확인할 수 있다. 즉 이 디스크에는 총 3개의 볼륨 디스크립터가 사용되고 있음을 알 수 있다.

패스 테이블

패스 테이블(path table)은 앞서 언급한대로 CD-ROM 내의 디렉토리 정보만 요약·정리한 것이다. 패스 테이블에는 파일 정보가 포함되어 있지 않다. 각 레코드의 길이는 가변적이며, 여기에는 디렉토리의 이름과 함께 시작 어드레스가 포함되어 있어 특정 파일을 빨리 찾을 수 있도록 해준다. 패스 테이블을 사용하지 않을 경우에는 하나의 파일을 찾기 위해서 루트 디렉토리부터 차례로 뒤져나가야 한다. 앞서 PVD의 내용에서 살펴보았듯이 볼륨 디스크립터 바로 뒤의 13h번째 섹터에는 리틀 엔디언 형식의 패스 테이블이 오는 것으로 되어 있다. 이제 이 내용을 읽어보기로 하겠다.

$ rd12 13 1
Read12 done

$ dump_buf

E000: 01 00 17 00 00 00 01 00 00 00 03 00 07 01 00 00 ........ ........
E010: 01 00 44 4F 43 00 08 00 BD 00 00 00 01 00 44 4F ..DOC... ......DO
E020: 53 55 54 49 4C 53 06 00 BC 00 00 00 01 00 49 4D SUTILS.. ......IM
E030: 41 47 45 53 04 00 1F 00 00 00 01 00 4D 49 53 43 AGES.... ....MISC
E040: 06 00 C9 00 00 00 01 00 52 45 44 48 41 54 08 00 ........ REDHAT..
E050: 18 00 00 00 01 00 52 52 5F 4D 4F 56 45 44 03 00 ......RR _MOVED..
E060: 08 01 00 00 02 00 46 41 51 00 05 00 11 01 00 00 ......FA Q.......
E070: 02 00 48 4F 57 54 4F 00 05 00 23 01 00 00 02 00 ..HOWTO. ..#.....
E080: 52 48 47 53 47 00 08 00 2B 01 00 00 02 00 52 48 RHGSG... +.....RH
E090: 4D 41 4E 55 41 4C 08 00 C3 00 00 00 03 00 41 55 MANUAL.. ......AU
E0A0: 54 4F 42 4F 4F 54 07 00 BF 00 00 00 03 00 46 49 TOBOOT.. ......FI
E0B0: 50 53 31 35 43 00 06 00 C4 00 00 00 03 00 46 49 PS15C... ......FI
E0C0: 50 53 32 30 08 00 C8 00 00 00 03 00 46 49 50 53 PS20.... ....FIPS
E0D0: 44 4F 43 53 03 00 20 00 00 00 05 00 53 52 43 00 DOCS.. . ....SRC.
E0E0: 04 00 06 01 00 00 06 00 42 41 53 45 08 00 FB 00 ........ BASE....
E0F0: 00 00 06 00 49 4E 53 54 49 4D 41 47 04 00 CA 00 ....INST IMAG....
E100: 00 00 06 00 52 50 4D 53 01 00 19 00 00 00 07 00 ....RPMS ........
...

$ rd12 15 1
Read12 done

struct path_table_entry
{
BYTE len_dir_identifier; // 01h // 03h
BYTE ext_attr_rec_len; // 00h // 00h
DWORD location; // 17h 00h 00h 00h // 07h 01h 00h 00h
WORD parent_dir_num; // 01h 00h // 01h 00h
char dir_identifier[n]; // “” // “DOC”
BYTE padding // 00h // 00h
}

패스 테이블의 각 엔트리는 하나의 디렉토리를 나타내게 된다. 각 엔트리에는 실제 디렉토리 엔트리의 주소(location)가 포함되어 있다. parent_dir_num는 디렉토리 레벨 순으로 각 디렉토리에 할당된 번호를 나타내는 것으로 루트 디렉토리를 비롯해 가장 상위 디렉토리의 경우 1이 되고 서브 디렉토리는 차례대로 2, 3, 4의 번호가 부여된다. 엔트리의 길이는 가변적인데, 그 이유는 디렉토리의 이름(dir_identifier)이 가변적이기 때문이다. 이름 길이는 가장 첫 번째 필드인 len_dir_identifier에 의해 표시가 된다. 길이는 바이트 값으로 주어지므로 최대 255자가 됨을 알 수 있다. 마지막 필드인 padding은 이름이 홀수 길이로 끝나는 경우 전체 길이를 짝수로 맞추기 위해서 부여되는 것으로, padding 이전에 전체 길이가 짝수가 되면 이는 생략된다. 패스 테이블의 첫 번째 레코드는 루트 디렉토리를 나타내며, 이름은 “ ”(NULL)로 되어 있다.
예제의 디스크는 전체의 패스 테이블이 하나의 섹터에 들어간다. 첫 번째 레코드는 루트 디렉토리의 “.”을 나타낸다. “.” 또는 “..” 디렉토리의 경우 그 길이는 1로 주어진다. 이 패스 테이블은 리틀 엔디언용이었으므로 빅 엔디언 패스 테이블인 15h의 섹터를 읽어보면 정리 형식만 다르고 내용은 같은 패스 테이블을 확인할 수 있다.

디렉토리 섹터의 구조

이제 마지막으로 디렉토리 섹터의 구조를 살펴보기로 하겠다. 디렉토리 레코드는 FAT32에서와 마찬가지로 파일이나 디렉토리에 대한 정보를 나타내는데, 길이는 패스 테이블의 경우와 마찬가지로 가변적이다. 패스 테이블의 경우 그 내용이 한 섹터가 넘을 경우, 섹터의 경계에 상관없이 다음 섹터로 내용이 이어지게 되지만 디렉토리의 경우는 섹터 경계를 넘을 수 없다. 따라서 한 레코드의 전체 길이가 섹터의 경계를 넘게 되면 그 내용은 다음 섹터에 기록되고, 앞 섹터의 빈 부분은 0으로 채워진다.
디렉토리 중 가장 기본이 되는 루트 디렉토리의 주소는 PVD 및 패스 테이블에서 확인할 수 있었다. 여기서는 예제 디스크의 루트 디렉토리 주소인 LBA=17h의 섹터를 읽어보기로 하겠다.

$ rd12 17 1
Read12 done

$ dump_buf 128

E000: 88 00 17 00 00 00 00 00 00 17 00 08 00 00 00 00 ........ ........
E010: 08 00 63 05 12 04 38 06 24 02 00 00 01 00 00 01 ..c...8. $.......
E020: 01 00 53 50 07 01 BE EF 00 52 52 05 01 81 50 58 ..SP.... .RR...PX
E030: 24 01 6D 41 00 00 00 00 41 6D 08 00 00 00 00 00 $.mA.... Am......
E040: 00 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
E050: 00 00 54 46 1A 01 0E 63 05 12 04 38 06 24 63 05 ..TF...c ...8.$c.
E060: 12 0C 33 0B 24 63 05 12 04 38 06 24 43 45 1C 01 ..3.$c.. .8.$CE..
E070: 40 01 00 00 00 00 01 40 00 00 00 00 00 00 00 00 @......@ ........
E080: ED 00 00 00 00 00 00 ED
66 00 17 00 00 00 00 00 ........ f.......
E090: 00 17 00 08 00 00 00 00 08 00 63 05 12 04 38 06 ........ ..c...8.
E0A0: 24 02 00 00 01 00 00 01 01 01 52 52 05 01 81 50 $....... ..RR...P
E0B0: 58 24 01 6D 41 00 00 00 00 41 6D 08 00 00 00 00 X$.mA... .Am.....
E0C0: 00 00 08 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
E0D0: 00 00 00 54 46 1A 01 0E 63 05 12 04 38 06 24 63 ...TF... c...8.$c
E0E0: 05 12 0C 33 0B 24 63 05 12 04 38 06 24 00
7C 00 ...3.$c. ..8.$.|.
E0F0: 41 01 00 00 00 00 01 41 D7 47 00 00 00 00 47 D7 A......A .G....G.
E100: 63 03 14 01 32 34 24 00 00 00 01 00 00 01 0A 43 c...24$. .......C
E110: 4F 50 59 49 4E 47 2E 3B 31 00 52 52 05 01 89 4E OPYING.; 1.RR...N
E120: 4D 0C 01 00 43 4F 50 59 49 4E 47 50 58 24 01 24 M...COPY INGPX$.$
...
E7D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
E7E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
E7F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........

struct directory_record
{
BYTE len_dr; // 88h
BYTE extended_attr_rec_len; // 00h
DWORD location_le; // 17h 00h 00h 00h
DWORD location_be; // 00h 00h 00h 17h
DWORD data_len_le; // 00h 08h 00h 00h
DWORD data_len_be; // 00h 00h 08h 00h
BYTE year; // 63h
BYTE month; // 05h
BYTE day; // 12h
BYTE hour; // 04h
BYTE minute; // 38h
BYTE second; // 06h
signed char offset_GMT; // 24h
BYTE file_flags; // 02h
BYTE file_unit_size; // 00h
BYTE interleave_gap_size; // 00h
WORD volume_sequence_num_le; // 01h 00h
WORD volume_sequence_num_be; // 00h 01h
BYTE len_file_identifier; // 01h
BYTE file_identifier[n]; // 00h
BYTE padding[m];
BYTE system_use[l]
}

디렉토리 레코드도 패스 테이블의 경우와 마찬가지로 길이가 가변적이므로 가장 처음 오는 필드(len_dr)는 레코드의 전체 길이를 나타낸다. 두 번째 필드는 확장 속성 레코드를 사용하는 경우에 그 길이를 나타내는데, 윈도우에서는 대부분 값이 0이다. 뒤를 이은 location과 data_len은 각각 디렉토리/파일의 시작 섹터와 전체 길이를 나타낸다.
year, month 등은 레코드가 가리키는 디렉토리/파일이 작성된 날짜와 시간 정보를 나타낸다. year의 경우 정확한 연도는 이 값에 1900년을 더한 수치이다. 앞의 루트 디렉토리 예에서는 값이 63h이므로 1963년이 되는 것이 아니라 1999년이 된다(63h가 16진수 값이기 때문이다). offset_GMT은 GMT(그리니치 표준시간)를 기준으로 15분 간격으로 시간대를 나눈 값으로 서쪽으로 -48, 동쪽으로 +52까지의 값을 갖는다.
다음의 file_flags는 파일의 속성을 나타낸다. file_unit_size와 interleave_gap_size는 인터리브 방식으로 기록된 CD-ROM에 대한 정보를 나타내는 것인데, 현재 대부분의 CD-ROM이 인터리브 방식을 사용하지 않으므로 이 필드 또한 거의 사용되지 않는다. volume_sequence_num은 여러 장의 디스크가 하나의 볼륨 셋트를 이루는 경우 해당 파일이 속한 볼륨의 일련번호를 저장한다. file_identifier는 파일 이름을 나타내고 len_file_identifier은 길이를 나타낸다. 디렉토리의 경우 캐릭터 스트링 또는 00h(“.”), 01h(“..”)이 온다. 앞의 예에서 첫 번째 레코드는 “.”를 나타내는데, 길이는 1로, 내용은 00h로 되어 있음을 알 수 있다. padding은 단순히 00h 값으로 레코드의 뒷부분을 채우기 위한 것이다. 마지막으로 system_use는 ISO 9660에 내용이 정의되지는 않았지만 시스템이 사용하는 영역이다. 디렉토리 레코드의 전체 길이는 이 부분의 길이를 모두 포함하게 된다. 실제 앞의 예에서도 이를 확인할 수 있다.
이상으로 ISO 9660에서 가장 중요한 PVD, 패스 테이블, 디렉토리 레코드에 대해 알아보았다. 이 정도의 정보만 있으면 CD-ROM에서 특정 파일을 찾아 정보를 읽어내는 것이 가능하다. 하드디스크처럼 섹터가 랜덤하게 놓여 있는 것이 아니고 일련의 섹터로 구성되므로 시작 어드레스부터 파일 길이만큼 주욱 읽어내면 된다.

출처 : 월간 마이크로소프트웨어 2003년 8월호