/////////////////////////////////////////////////////////////////////////////// // // Microsoft Research Singularity // // Copyright (c) Microsoft Corporation. All rights reserved. // /////////////////////////////////////////////////////////////////////////////// using System; using System.Collections; using Microsoft.Singularity.V1.Services; using System; using System.Collections; using Microsoft.Singularity; using Microsoft.Singularity.Io; using Microsoft.Singularity.Channels; using Microsoft.Singularity.Drivers; using Microsoft.Singularity.Directory; using Microsoft.Singularity.V1.Services; namespace Iso9660 { public class Iso9660DirectoryInfo : Iso9660FileSystemInfo { private byte LEN { get { return buf[pos + DirEnt.LEN]; }} private byte FLAGS { get { return buf[pos + DirEnt.FLAGS]; }} private int NAME_LEN { get { return buf[pos + DirEnt.NAME_LEN]; }} private int NAME_POS { get { return pos + DirEnt.NAME; }} private string NAME { get { return ByteArray.ToString (buf, NAME_POS, NAME_LEN); }} private bool DOT { get { return ((NAME_LEN == 1) && (buf[NAME_POS] == 0x00)); }} private bool DOTDOT { get { return ((NAME_LEN == 1) && (buf[NAME_POS] == 0x01)); }} public string myPrefix; internal Iso9660DirectoryInfo() {} // // 0. Delegated "lookup" for Enumerate & FindChild // private delegate bool LOOKUP (Object obj); private bool Lookup (LOOKUP lookup, Object obj) { // // The following assumes that the list of directory entries // is terminated in every block by an entry with LEN 0, ie: // // 1. directory entries do not cross block boundaries // (with entries in the 1st block, and unused bytes at // the end, entry starts at pos 0 in the 2nd block) // // 2. the size is used only to calculate the number of blocks // (not the last byte of the last entry in the last block) // ulong nblocks = 1 + (size - 1) / 2048; for (ulong n = 0; n < nblocks; n++) { Iso9660.Stdio.RawDevice.ReadBlock (buf, blockno + n); for (pos = 0;; pos += LEN) { if (LEN == 0) break; if (DOT || DOTDOT) continue; if (lookup (obj)) return true; } } return false; } // // 1. Enumerate (dir/ls) // private bool Enumerate (Object obj) { bool dir = ((FLAGS & (byte)Iso9660FileFlags.Directory) != 0); NodeType nodeType = (dir)? NodeType.Directory: NodeType.File; ((SortedList)obj).Add (NAME.ToLower(), nodeType); // FIXME: ToLower opt? return false; // GetNextChild } public EnumerationRecords[] in ExHeap Enumerate (out ErrorCode errorOut) { SortedList matches; EnumerationRecords[] in ExHeap responses = null; errorOut = ErrorCode.NoError; matches = new SortedList(); if (matches == null) { errorOut = ErrorCode.InsufficientResources; return null; } Lookup (Enumerate, matches); responses = new [ExHeap] EnumerationRecords[matches.Count]; if (responses == null) { errorOut = ErrorCode.InsufficientResources; return null; } for (int i = 0; i < matches.Count; i++){ expose (responses[i]) { delete responses[i].Path; // checker doesn't know its null. responses[i].Path = Bitter.FromString2((!)((string)matches.GetKey(i))); responses[i].Type = (NodeType) (!) matches.GetByIndex(i); } } return responses; } // // 2. FindChild // private bool FindChild (Object obj) { return ((string)obj == NAME.ToLower()); // FIXME: ToLower opt? } internal bool FindChild(string name, bool returnChild, out Iso9660FileSystemInfo child) { if (!Lookup (FindChild, name)) { child = null; return false; } if ((FLAGS & (byte)Iso9660FileFlags.Directory) != 0) { Iso9660DirectoryInfo dir = new Iso9660DirectoryInfo(); dir.myPrefix = myPrefix + SuperBlock.DELIMITER + name; child = dir; } else { Iso9660FileInfo file = new Iso9660FileInfo(); child = file; } child.InitializeMe (buf, pos); return true; } } }