public static NativePrimaryDescriptor?FromStream(BinaryReader reader) { NativePrimaryDescriptor npd = new NativePrimaryDescriptor(); // Starts at logical block 16 (0x8000) reader.BaseStream.Seek(16 * 2048, SeekOrigin.Begin); reader.BaseStream.Seek(1, SeekOrigin.Current); string magic = ReadString(reader, 5); if (magic != "CD001") { return(null); } reader.BaseStream.Seek(2, SeekOrigin.Current); npd.SystemID = ReadString(reader, 32); npd.VolumeID = ReadString(reader, 32); reader.BaseStream.Seek(8, SeekOrigin.Current); npd.SectorCount = reader.ReadInt32(); reader.BaseStream.Seek(4 + 32 + 4 + 4, SeekOrigin.Current); npd.SectorSize = reader.ReadInt16(); reader.BaseStream.Seek(2, SeekOrigin.Current); npd.PathTableLength = reader.ReadInt32(); reader.BaseStream.Seek(4, SeekOrigin.Current); npd.PathTableStart = reader.ReadInt32(); npd.AltPathTableStart = reader.ReadInt32(); reader.BaseStream.Seek(8, SeekOrigin.Current); long x = reader.BaseStream.Position; NativePathEntry npe = NativePathEntry.FromReader(reader); Debug.Assert(npe != null); npd.Root = npe; long z = reader.BaseStream.Position - x; reader.BaseStream.Seek(34 - z, SeekOrigin.Current); npd.VolumeName = ReadString(reader, 128); npd.Publisher = ReadString(reader, 128); reader.BaseStream.Seek(128, SeekOrigin.Current); npd.Application = ReadString(reader, 128); reader.BaseStream.Seek(37 + 37 + 37, SeekOrigin.Current); string creationString = ReadString(reader, 17); npd.Created = ParseDate(creationString); // Seek to the end reader.BaseStream.Seek(17 * 2048, SeekOrigin.Begin); return(npd); }
protected MediaFolder ParseIsoFileSystem(string path, bool minimalCache) { Debug.Assert(path != null); Debug.Assert(File.Exists(path) == true); if (File.Exists(path) == false) { return(null); } using (FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read)) using (BinaryReader reader = new BinaryReader(stream)) { NativePrimaryDescriptor?npdv = NativePrimaryDescriptor.FromStream(reader); Debug.Assert(npdv != null); if (npdv == null) { return(null); } NativePrimaryDescriptor npd = npdv.Value; List <NativePathEntry> npes = new List <NativePathEntry>(); stream.Seek(npd.PathTableStart * 2048, SeekOrigin.Begin); while (stream.Position < (npd.PathTableStart * 2048) + npd.PathTableLength) { NativePathEntry npe = NativePathEntry.FromReader(reader); if (npe == null) { continue; } npes.Add(npe); } List <MediaFolder> folders = new List <MediaFolder>(npes.Count); for (int n = 0; n < npes.Count; n++) { NativePathEntry npe = npes[n]; MediaFolder current = null; MediaFolder parent = null; if (npe.IsRoot == false) { parent = folders[npe.ParentEntry]; } if (npe.Length == 0) { // Look in parent for length if (parent != null) { NativePathEntry pe = npes[npe.ParentEntry]; npe.Length = pe.ChildLengths[npe.Name]; } else { npe.Length = 2048; } } int m = 0; for (int s = 0; s < npe.Length / 2048; s++) { stream.Seek((npe.FirstSector + s) * 2048, SeekOrigin.Begin); while (true) { NativeEntry?nev = NativeEntry.FromReader(reader); if (nev == null) { break; } NativeEntry ne = nev.Value; if (m == 0) { // '.' this dir MediaItemAttributes attributes = MediaItemAttributes.Normal; if ((ne.Flags & NativeEntryFlags.Hidden) == NativeEntryFlags.Hidden) { attributes |= MediaItemAttributes.Hidden; } current = new MediaFolder(this, parent, npe.Name, attributes, ne.Timestamp); folders.Add(current); } else if (m == 1) { // '..' parent dir - ignored } else { // Child if ((ne.Flags & NativeEntryFlags.Directory) == NativeEntryFlags.Directory) { // Directories are handled when it is their turn to be added // EXCEPT for size, which we need to get now and store back // At this time in the code, we have all dirs prior to the one whose length // we just got - since we have already added ourselves, we know we have its // parent too npe.ChildLengths.Add(ne.Name, ne.Length); } else { MediaItemAttributes attributes = MediaItemAttributes.Normal; if ((ne.Flags & NativeEntryFlags.Hidden) == NativeEntryFlags.Hidden) { attributes |= MediaItemAttributes.Hidden; } long lbn = ne.FirstSector /* * 2048*/; MediaFile file = new MediaFile(this, current, ne.Name, attributes, ne.Timestamp, lbn * 2048, ne.Length); //Log.WriteLine(Verbosity.Normal, Feature.Bios, "{0} = {1}", ne.Name, lbn); // Pretty sure this is wrong, but it shouldn't matter Debug.Assert(_lbnLookup.ContainsKey(lbn) == false); _lbnLookup[lbn] = file; } } m++; if ((ne.Flags & NativeEntryFlags.LastEntry) == NativeEntryFlags.LastEntry) { break; } } } } return(folders[0]); } }