// Methods

        /// <summary>
        /// Init the pvd and allocate some space for the path table and the root directory
        /// </summary>
        /// <param name="volumeId">The volume identifier</param>
        /// <param name="pathTableSize">Size of the path table in sector (default 1)</param>
        /// <param name="rootDirectorySize">Size of the root directory in sector (default 1)</param>
        public void Prepare(string volumeId, int pathTableSize = 1, int rootDirectorySize = 1)
        {
            try
            {
                if (_prepared)
                {
                    return;
                }

                SeekSector(16);
                WriteEmptySectors(2 + pathTableSize * 4);

                var root = new DirectoryEntry(_isXa);
                root.IsDirectory = true;
                root.ExtentSize  = (uint)(rootDirectorySize * GetSectorDataSize(_defaultSectorMode));
                root.ExtentLba   = (uint)SectorCount;

                _index = new DataTrackIndex(root);

                _primaryVolumeDescriptor               = new PrimaryVolumeDescriptor(1);
                _primaryVolumeDescriptor.VolumeId      = volumeId;
                _primaryVolumeDescriptor.PathTableSize = (uint)(pathTableSize * GetSectorDataSize(_defaultSectorMode));

                // The root directory included in the volume descriptor doesn't allow XA, so let's create a separated one
                _primaryVolumeDescriptor.RootDirectoryEntry             = new DirectoryEntry(false);
                _primaryVolumeDescriptor.RootDirectoryEntry.IsDirectory = true;
                _primaryVolumeDescriptor.RootDirectoryEntry.ExtentSize  = root.ExtentSize;
                _primaryVolumeDescriptor.RootDirectoryEntry.ExtentLba   = root.ExtentLba;

                WriteEmptySectors(rootDirectorySize);

                _prepared = true;
            }
            catch (FrameworkException ex)
            {
                throw ex;
            }
            catch (Exception)
            {
                throw new FrameworkException("Errow while preparing track : unable to prepare data track");
            }
        }
        /// <summary>
        /// Read a primary volume descriptor
        /// </summary>
        /// <param name="stream">The stream to read</param>
        private PrimaryVolumeDescriptor ReadPrimaryVolumeDescriptor(CBinaryReader stream)
        {
            PrimaryVolumeDescriptor descriptor;

            try
            {
                byte version = stream.ReadByte();

                descriptor = new PrimaryVolumeDescriptor(version);

                descriptor.Unused1  = stream.ReadByte();
                descriptor.SystemId = stream.ReadAsciiString(32);
                descriptor.VolumeId = stream.ReadAsciiString(32);
                descriptor.Unused2  = stream.ReadBytes(8);

                descriptor.VolumeSpaceSize = stream.ReadUInt32();
                if (descriptor.VolumeSpaceSize != stream.ReadUInt32BE())
                {
                    throw new FrameworkException("Error while reading PrimaryVolumeDescriptor : VolumeSpaceSize is not valid");
                }

                descriptor.Unused3 = stream.ReadBytes(32);

                descriptor.VolumeSetSize = stream.ReadUInt16();
                if (descriptor.VolumeSetSize != stream.ReadUInt16BE())
                {
                    throw new FrameworkException("Error while reading PrimaryVolumeDescriptor : VolumeSetSize is not valid");
                }

                descriptor.VolumeSequenceNumber = stream.ReadUInt16();
                if (descriptor.VolumeSequenceNumber != stream.ReadUInt16BE())
                {
                    throw new FrameworkException("Error while reading PrimaryVolumeDescriptor : VolumeSequenceNumber  is not valid");
                }

                descriptor.LogicalBlockSize = stream.ReadUInt16();
                if (descriptor.LogicalBlockSize != stream.ReadUInt16BE())
                {
                    throw new FrameworkException("Error while reading PrimaryVolumeDescriptor : LogicalBlockSize  is not valid");
                }

                descriptor.PathTableSize = stream.ReadUInt32();
                if (descriptor.PathTableSize != stream.ReadUInt32BE())
                {
                    throw new FrameworkException("Error while reading PrimaryVolumeDescriptor : PathTableSize  is not valid");
                }

                descriptor.TypeLPathTableLBA    = stream.ReadUInt32();
                descriptor.OptTypeLPathTableLBA = stream.ReadUInt32();
                descriptor.TypeMPathTableLBA    = stream.ReadUInt32BE();
                descriptor.OptTypeMPathTableLBA = stream.ReadUInt32BE();

                if (descriptor.OptTypeLPathTableLBA != 0 || descriptor.OptTypeMPathTableLBA != 0)
                {
                    _hasOptionalPathTable = true;
                }

                descriptor.RootDirectoryEntry = ReadDirectoryEntry(stream);

                // TODO : cas des fichiers
                descriptor.VolumeSetId         = stream.ReadAsciiString(128);
                descriptor.PublisherId         = stream.ReadAsciiString(128);
                descriptor.PreparerId          = stream.ReadAsciiString(128);
                descriptor.ApplicationId       = stream.ReadAsciiString(128);
                descriptor.CopyrightFileId     = stream.ReadAsciiString(38);
                descriptor.AbstractFileId      = stream.ReadAsciiString(36);
                descriptor.BibliographicFileId = stream.ReadAsciiString(37);
                //

                descriptor.CreationDate         = VolumeDescriptor.ToDateTime(stream.ReadBytes(17));
                descriptor.ModificationDate     = VolumeDescriptor.ToDateTime(stream.ReadBytes(17));
                descriptor.ExpirationDate       = VolumeDescriptor.ToDateTime(stream.ReadBytes(17));
                descriptor.EffectiveDate        = VolumeDescriptor.ToDateTime(stream.ReadBytes(17));
                descriptor.FileStructureVersion = stream.ReadByte();
                descriptor.Unused4         = stream.ReadByte();
                descriptor.ApplicationData = stream.ReadBytes(512);
                descriptor.Reserved        = stream.ReadBytes(653);

                // if the disk is CDROM/XA (and then contains an XaEntry in his DirectoryEntries),
                // "CD-XA001" can be read at offset 0x400 of the pvd (actually offset 0x8D of ApplicationData field)
                if (CBuffer.ReadAsciiString(descriptor.ApplicationData, 0x8D, 8) == VolumeDescriptor.VOLUME_XA)
                {
                    _isXa = true;
                }
            }
            catch (FrameworkException ex)
            {
                throw ex;
            }
            catch (Exception)
            {
                throw new FrameworkException("Error while reading PrimaryVolumeDescriptor : PrimaryVolumeDescriptor is not valid");
            }

            return(descriptor);
        }