// // ReadVolumeHeader: // reads the filesystem volume header. this header should // be at the beginning of every 3do iso/disc. it contains // information about the filesystem on the disc, including // block size, total disc size, root directory location, etc. // // arguments: // 1) CoreVolumeHeader *vh (OUT): a pointer to an allocated CoreVolumeHeader object. // this will be initialized with the data read from the disc // return value: // true on success, false otherwise // public bool ReadVolumeHeader(ref CoreVolumeHeader vh) { UInt32 bytesRead = 0; bool ret; byte[] buffer = new byte[CoreVolumeHeaderConsts.VolumeHeaderSize]; GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned); ret = _fileReader.Read(handle.AddrOfPinnedObject(), CoreVolumeHeaderConsts.VolumeHeaderSize, ref bytesRead); if (!ret) { return(false); } vh = (CoreVolumeHeader)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(CoreVolumeHeader)); handle.Free(); // // make all relevant fields little endian // EndianSwap(ref vh.id); EndianSwap(ref vh.blockSize); EndianSwap(ref vh.blockCount); EndianSwap(ref vh.rootDirId); EndianSwap(ref vh.rootDirBlocks); EndianSwap(ref vh.rootDirBlockSize); EndianSwap(ref vh.lastRootDirCopy); unsafe { for (int i = 0; i < 8; i++) { fixed(uint *copies = vh.rootDirCopies) { EndianSwap(ref copies[i]); } } } // // keep a local copy for ourselves // _coreVolumeHeader = vh; // // go ahead and move the fp forward to the root dir location // unsafe { fixed(uint *copies = vh.rootDirCopies) { ret = SeekToBlock(copies[0], false); } } if (!ret) { return(false); } return(true); }
public FileSystem(IFileReader fileReader) { _fileReader = fileReader; _fileReader.SeekToByte(0, false); _coreFileSystem = new CoreFileSystem(_fileReader); var coreVolumeHeader = new CoreVolumeHeader(); var coreDirectoryHeader = new CoreDirectoryHeader(); _coreFileSystem.ReadVolumeHeader(ref coreVolumeHeader); _coreFileSystem.SeekToBlock(coreVolumeHeader.FirstCopy, false); uint directoryHeaderStart = _coreFileSystem.FileReader.CurrentByte; _coreFileSystem.ReadDirectoryHeader(ref coreDirectoryHeader); _rootVolumeHeader = new VolumeHeader(coreVolumeHeader); _rootDirectory = new Directory(directoryHeaderStart, this, coreDirectoryHeader, null, null); }
public bool OpenDirectory(string path) { bool ret; char separator = '/'; string token; CoreVolumeHeader coreVolumeHeader = new CoreVolumeHeader(); CoreDirectoryEntry dirEntry = new CoreDirectoryEntry(); CoreDirectoryEntry newEntry; CoreDirectoryEntry oldEntry; string[] parts = path.Split(separator); // // can't do much with an empty path // if (path.Length <= 0) { return(false); } // // if the path isn't absolute, then this isn't going to work // if (path.StartsWith("/")) { return(false); } // // check if our path is somewhat sane // if (parts.Length <= 1) { return(false); } // // seek to the beginning of the filesystem // ret = _coreFileSystem.FileReader.SeekToByte(0, false); if (!ret) { return(false); } // clear our dir tree _dirTree.Clear(); // // read the volume info from the filesystem // ret = _coreFileSystem.ReadVolumeHeader(ref coreVolumeHeader); if (!ret) { return(false); } // // read the root directory's header // ret = _coreFileSystem.ReadDirectoryHeader(ref _coreDirectoryHeader); if (!ret) { return(false); } // // create a directory entry for the root dir and throw it into our dir tree // newEntry = new CoreDirectoryEntry(); unsafe { newEntry.blockSize = coreVolumeHeader.rootDirBlockSize; newEntry.entryLengthBlocks = coreVolumeHeader.rootDirBlocks; newEntry.fileName[0] = (byte)'/'; newEntry.fileName[1] = 0; newEntry.lastCopy = coreVolumeHeader.lastRootDirCopy; newEntry.copies = coreVolumeHeader.rootDirCopies[0]; } _dirTree.Add(newEntry); // // our current path // _path = "/"; foreach (string part in parts) { ret = FindInCurrentDirectory(part, ref dirEntry); if (!ret) { break; } } // enable enumeration if (ret) { _endOfDir = false; } return(true); }
internal VolumeHeader(CoreVolumeHeader coreVolumeHeader) { _coreVolumeHeader = coreVolumeHeader; }