2008-11-17 18:29:00 -05:00
|
|
|
// ----------------------------------------------------------------------------
|
2008-03-05 09:52:00 -05:00
|
|
|
//
|
|
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
//
|
2008-11-17 18:29:00 -05:00
|
|
|
// ----------------------------------------------------------------------------
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
|
|
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 <n> entries in the 1st block, and unused bytes at
|
|
|
|
// the end, entry <n+1> 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();
|
2008-11-17 18:29:00 -05:00
|
|
|
if (matches == null) {
|
2008-03-05 09:52:00 -05:00
|
|
|
errorOut = ErrorCode.InsufficientResources;
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
Lookup (Enumerate, matches);
|
|
|
|
|
|
|
|
responses = new [ExHeap] EnumerationRecords[matches.Count];
|
2008-11-17 18:29:00 -05:00
|
|
|
if (responses == null) {
|
2008-03-05 09:52:00 -05:00
|
|
|
errorOut = ErrorCode.InsufficientResources;
|
|
|
|
return null;
|
|
|
|
}
|
2008-11-17 18:29:00 -05:00
|
|
|
for (int i = 0; i < matches.Count; i++) {
|
2008-03-05 09:52:00 -05:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|