// // Copyright (c) 2008-2011, Kenneth Bell // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. // using System.IO; using DiscUtils.Streams; using DiscUtils.Vfs; namespace DiscUtils.Iso9660 { /// /// Class for reading existing ISO images. /// public class CDReader : VfsFileSystemFacade, IClusterBasedFileSystem, IUnixFileSystem { /// /// Initializes a new instance of the CDReader class. /// /// The stream to read the ISO image from. /// Whether to read Joliet extensions. public CDReader(Stream data, bool joliet) : base(new VfsCDReader(data, joliet, false)) {} /// /// Initializes a new instance of the CDReader class. /// /// The stream to read the ISO image from. /// Whether to read Joliet extensions. /// Hides version numbers (e.g. ";1") from the end of files. public CDReader(Stream data, bool joliet, bool hideVersions) : base(new VfsCDReader(data, joliet, hideVersions)) {} /// /// Gets which of the Iso9660 variants is being used. /// public Iso9660Variant ActiveVariant { get { return GetRealFileSystem().ActiveVariant; } } /// /// Gets the emulation requested of BIOS when the image is loaded. /// public BootDeviceEmulation BootEmulation { get { return GetRealFileSystem().BootEmulation; } } /// /// Gets the absolute start position (in bytes) of the boot image, or zero if not found. /// public long BootImageStart { get { return GetRealFileSystem().BootImageStart; } } /// /// Gets the memory segment the image should be loaded into (0 for default). /// public int BootLoadSegment { get { return GetRealFileSystem().BootLoadSegment; } } /// /// Gets a value indicating whether a boot image is present. /// public bool HasBootImage { get { return GetRealFileSystem().HasBootImage; } } /// /// Gets the size (in bytes) of each cluster. /// public long ClusterSize { get { return GetRealFileSystem().ClusterSize; } } /// /// Gets the total number of clusters managed by the file system. /// public long TotalClusters { get { return GetRealFileSystem().TotalClusters; } } /// /// Converts a cluster (index) into an absolute byte position in the underlying stream. /// /// The cluster to convert. /// The corresponding absolute byte position. public long ClusterToOffset(long cluster) { return GetRealFileSystem().ClusterToOffset(cluster); } /// /// Converts an absolute byte position in the underlying stream to a cluster (index). /// /// The byte position to convert. /// The cluster containing the specified byte. public long OffsetToCluster(long offset) { return GetRealFileSystem().OffsetToCluster(offset); } /// /// Converts a file name to the list of clusters occupied by the file's data. /// /// The path to inspect. /// The clusters. /// Note that in some file systems, small files may not have dedicated /// clusters. Only dedicated clusters will be returned. public Range[] PathToClusters(string path) { return GetRealFileSystem().PathToClusters(path); } /// /// Converts a file name to the extents containing its data. /// /// The path to inspect. /// The file extents, as absolute byte positions in the underlying stream. /// Use this method with caution - not all file systems will store all bytes /// directly in extents. Files may be compressed, sparse or encrypted. This method /// merely indicates where file data is stored, not what's stored. public StreamExtent[] PathToExtents(string path) { return GetRealFileSystem().PathToExtents(path); } /// /// Gets an object that can convert between clusters and files. /// /// The cluster map. public ClusterMap BuildClusterMap() { return GetRealFileSystem().BuildClusterMap(); } /// /// Retrieves Unix-specific information about a file or directory. /// /// Path to the file or directory. /// Information about the owner, group, permissions and type of the /// file or directory. public UnixFileSystemInfo GetUnixFileInfo(string path) { return GetRealFileSystem().GetUnixFileInfo(path); } /// /// Detects if a stream contains a valid ISO file system. /// /// The stream to inspect. /// true if the stream contains an ISO file system, else false. public static bool Detect(Stream data) { byte[] buffer = new byte[IsoUtilities.SectorSize]; if (data.Length < 0x8000 + IsoUtilities.SectorSize) { return false; } data.Position = 0x8000; int numRead = StreamUtilities.ReadMaximum(data, buffer, 0, IsoUtilities.SectorSize); if (numRead != IsoUtilities.SectorSize) { return false; } BaseVolumeDescriptor bvd = new BaseVolumeDescriptor(buffer, 0); return bvd.StandardIdentifier == BaseVolumeDescriptor.Iso9660StandardIdentifier; } /// /// Opens a stream containing the boot image. /// /// The boot image as a stream. public Stream OpenBootImage() { return GetRealFileSystem().OpenBootImage(); } } }