public static NativeEntry?FromReader(BinaryReader reader) { NativeEntry ne = new NativeEntry(); byte recordLength = reader.ReadByte(); if (recordLength == 0) { return(null); } byte extraSectors = reader.ReadByte(); Debug.Assert(extraSectors == 0); ne.FirstSector = reader.ReadInt32(); reader.BaseStream.Seek(4, SeekOrigin.Current); ne.Length = reader.ReadInt32(); reader.BaseStream.Seek(4, SeekOrigin.Current); ne.Timestamp = ReadDate(reader); ne.Flags = ( NativeEntryFlags )reader.ReadByte(); byte fileUnitSize = reader.ReadByte(); Debug.Assert(fileUnitSize == 0); byte interleaveGapSize = reader.ReadByte(); Debug.Assert(interleaveGapSize == 0); reader.BaseStream.Seek(4, SeekOrigin.Current); byte nameLength = reader.ReadByte(); ne.Name = ReadString(reader, nameLength); int namePad = (nameLength % 2 == 0) ? 1 : 0; reader.BaseStream.Seek(namePad, SeekOrigin.Current); int pad = recordLength - 33 - nameLength - namePad; reader.BaseStream.Seek(pad, SeekOrigin.Current); return(ne); }
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]); } }
public static NativeEntry? FromReader( BinaryReader reader ) { NativeEntry ne = new NativeEntry(); byte recordLength = reader.ReadByte(); if( recordLength == 0 ) return null; byte extraSectors = reader.ReadByte(); Debug.Assert( extraSectors == 0 ); ne.FirstSector = reader.ReadInt32(); reader.BaseStream.Seek( 4, SeekOrigin.Current ); ne.Length = reader.ReadInt32(); reader.BaseStream.Seek( 4, SeekOrigin.Current ); ne.Timestamp = ReadDate( reader ); ne.Flags = ( NativeEntryFlags )reader.ReadByte(); byte fileUnitSize = reader.ReadByte(); Debug.Assert( fileUnitSize == 0 ); byte interleaveGapSize = reader.ReadByte(); Debug.Assert( interleaveGapSize == 0 ); reader.BaseStream.Seek( 4, SeekOrigin.Current ); byte nameLength = reader.ReadByte(); ne.Name = ReadString( reader, nameLength ); int namePad = ( nameLength % 2 == 0 ) ? 1 : 0; reader.BaseStream.Seek( namePad, SeekOrigin.Current ); int pad = recordLength - 33 - nameLength - namePad; reader.BaseStream.Seek( pad, SeekOrigin.Current ); return ne; }