Dictionary <string, DirectoryEntryWithPointers> DecodeDirectory(int firstBlock) { Dictionary <string, DirectoryEntryWithPointers> entries = new Dictionary <string, DirectoryEntryWithPointers>(); int nextBlock = firstBlock; DirectoryHeader header; do { byte[] data = _image.ReadSectors((ulong)(nextBlock * _volumeBlockSizeRatio), _volumeBlockSizeRatio); header = Marshal.ByteArrayToStructureBigEndian <DirectoryHeader>(data); nextBlock = header.next_block + firstBlock; int off = (int)header.first_used; var entry = new DirectoryEntry(); while (off + _directoryEntrySize < data.Length) { entry = Marshal.ByteArrayToStructureBigEndian <DirectoryEntry>(data, off, _directoryEntrySize); string name = StringHandlers.CToString(entry.name, Encoding); var entryWithPointers = new DirectoryEntryWithPointers { entry = entry, pointers = new uint[entry.last_copy + 1] }; for (int i = 0; i <= entry.last_copy; i++) { entryWithPointers.pointers[i] = BigEndianBitConverter.ToUInt32(data, off + _directoryEntrySize + (i * 4)); } entries.Add(name, entryWithPointers); if ((entry.flags & (uint)FileFlags.LastEntry) != 0 || (entry.flags & (uint)FileFlags.LastEntryInBlock) != 0) { break; } off += (int)(_directoryEntrySize + ((entry.last_copy + 1) * 4)); } if ((entry.flags & (uint)FileFlags.LastEntry) != 0) { break; } } while(header.next_block != -1); return(entries); }
Errno GetFileEntry(string path, out DirectoryEntryWithPointers entry) { entry = null; string cutPath = path.StartsWith("/", StringComparison.Ordinal) ? path.Substring(1).ToLower(CultureInfo.CurrentUICulture) : path.ToLower(CultureInfo.CurrentUICulture); string[] pieces = cutPath.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); if (pieces.Length == 0) { return(Errno.InvalidArgument); } string parentPath = string.Join("/", pieces, 0, pieces.Length - 1); if (!_directoryCache.TryGetValue(parentPath, out _)) { Errno err = ReadDir(parentPath, out _); if (err != Errno.NoError) { return(err); } } Dictionary <string, DirectoryEntryWithPointers> parent; if (pieces.Length == 1) { parent = _rootDirectoryCache; } else if (!_directoryCache.TryGetValue(parentPath, out parent)) { return(Errno.InvalidArgument); } KeyValuePair <string, DirectoryEntryWithPointers> dirent = parent.FirstOrDefault(t => t.Key.ToLower(CultureInfo.CurrentUICulture) == pieces[^ 1]); if (string.IsNullOrEmpty(dirent.Key)) { return(Errno.NoSuchFile); } entry = dirent.Value; return(Errno.NoError); }