/////////////////////////////////////////////////////////////////////////////// // // Microsoft Research Singularity // // Copyright (c) Microsoft Corporation. All rights reserved. // // File: Manifest.cs // // Note: Creates and binds endpoints using a manifest. // using System; using System.Text; using System.Collections; using Microsoft.SingSharp; using Microsoft.Singularity; using Microsoft.Singularity.Channels; using Microsoft.Singularity.Directory; using Microsoft.Singularity.Extending; using Microsoft.Singularity.Io; using Microsoft.Singularity.Memory; using Microsoft.Singularity.Xml; namespace Microsoft.Singularity.Loader { /// /// This is a placeholder class for an application's manifest. /// At present the application manifest is represented by a hashtable. /// The hashtable has several important properties: /// - name: the name of the application /// - path: path to the application executable /// public class Manifest { /// /// We treat the application manifest as a collection of /// key, value pairs. /// private Hashtable! data = new Hashtable(); private const string pipeContract = "Microsoft.Singularity.Io.UnicodePipeContract"; private string name; private string path; private string publisher; private string[] privileges = null; private readonly XmlNode! applicationNode; private readonly XmlNode! processNode; private readonly XmlNode categoriesNode; /// /// Create a manifest object from the given xml representation /// [Microsoft.Contracts.NotDelayed] public Manifest(byte[] xml) { Kernel.Waypoint(2600); XmlReader! reader = new XmlReader(xml); XmlNode! doc = (!)reader.Parse(); Kernel.Waypoint(2601); this(doc); } [Microsoft.Contracts.NotDelayed] public Manifest(IoMemory memory) { Kernel.Waypoint(2600); XmlReader! reader = new XmlReader(memory); XmlNode! doc = (!)reader.Parse(); Kernel.Waypoint(2601); this(doc); } [Microsoft.Contracts.NotDelayed] private Manifest(XmlNode! doc) { XmlNode app = (!)doc.GetChild("application"); name = app["name"]; publisher = app["publisher"]; XmlNode proc = null; foreach (XmlNode! process in app.Children) { if (process.Name != "process") { continue; } if (process.GetAttribute("main", "false") == "true") { path = process["path"]; proc = process; break; } } applicationNode = app; XmlNode! processNode = this.processNode = (!)proc; base(); XmlNode privsNode = applicationNode.GetChild("privileges"); if (privsNode != null) { int pCount = 0; foreach (XmlNode! privilegeNode in privsNode.Children) { if (privilegeNode.Name != "privilege") continue; if (privilegeNode.GetAttribute("name", null) != null) { pCount++; } } if (pCount != 0) { privileges = new string[pCount]; pCount = 0; foreach (XmlNode! privilegeNode in privsNode.Children) { if (privilegeNode.Name != "privilege") continue; String privilege = privilegeNode.GetAttribute("name", null); if (privilege != null) { privileges[pCount++] = privilege; } } } } categoriesNode = processNode.GetChild("categories"); if (categoriesNode != null) { return; } #if false string ns = child["namespace"]; string name = child["name"]; string value = child["value"]; if (name != null && value != null) { DataItem item = new DataItem(ns, name, value); data[name] = item; } else { throw new Exception("Invalid manifest"); } #endif Kernel.Waypoint(2602); } public object GetProperty(object! name) { return data[name]; } public void SetProperty(object! name, object value) { data[name] = value; } // given an action find the corresponding category node public XmlNode GetCategoryNode(string actionName) { if (categoriesNode == null) return null; if (actionName == null) { foreach (XmlNode! c in categoriesNode.Children) { string name = c.GetAttribute("name",""); if (name != "console") return c; bool present = c.GetAttribute("DefaultAction",false); if (present) return c; } return null; } else { foreach (XmlNode! c in categoriesNode.Children) { string a = c.GetAttribute("Action",null); if (a != null && a == actionName) { return c; } } return null; } } public bool GetParameterCounts( string action, out int boolCount, out int longCount, out int stringCount, out int stringArrayCount) { XmlNode categoryNode; boolCount = 0; longCount = 0; stringCount = 0; stringArrayCount = 0; XmlNode boolParametersNode; XmlNode longParametersNode; XmlNode stringParametersNode; XmlNode stringArrayParametersNode; categoryNode = GetCategoryNode(action); if (categoryNode == null) { return true; } boolParametersNode = categoryNode.GetChild("BoolParameters"); if (boolParametersNode != null) { boolCount = boolParametersNode.GetAttribute("length", 0); } longParametersNode = categoryNode.GetChild("LongParameters"); if (longParametersNode != null) { longCount = longParametersNode.GetAttribute("length", 0); } stringParametersNode = categoryNode.GetChild("StringParameters"); if (stringParametersNode != null) { stringCount = stringParametersNode.GetAttribute("length", 0); } stringArrayParametersNode = categoryNode.GetChild("StringArrayParameters"); if (stringArrayParametersNode != null) { stringArrayCount = stringArrayParametersNode.GetAttribute("length", 0); } return true; } public int SetEndpoints(Process! process, string action) { // walk the XmlTree looking endpoints // these will be used by the binder to setup and transfer to // the starting process much like what is done for drivers XmlNode categoryNode; categoryNode = GetCategoryNode(action); if (categoryNode == null) { #if DEBUG DebugStub.WriteLine("::: no category"); #endif return 0; } XmlNode endpoints = categoryNode.GetChild("endpoints"); if (endpoints == null) { return 0; } int endpointCount = endpoints.GetAttribute("length", 0); if (endpointCount == 0) { return 0; } // now allocate memory for ep set process.SetEndpointCount(endpointCount); //DebugStub.WriteLine("Setting endpoint count to {0}", __arglist(endpointCount)); return endpointCount; } public string Name { get { return name; } } public string Publisher { get { return publisher; } } public string Path { get { return path; } } public string[] Privileges { get { return privileges; } } #if false public override string! ToString() { StringBuilder sb = new StringBuilder(); sb.AppendFormat("", Name); // the main executable sb.AppendFormat("", Path); foreach (DataItem item in data.Values) { if (item.Directory == null) { sb.AppendFormat("", item.Name, item.Value); } else { sb.AppendFormat("", item.Directory, item.Name, item.Value); } } sb.Append(""); sb.Append(""); sb.Append(""); sb.Append(""); return sb.ToString(); } public byte[] Serialize() { return (new UTF8Encoding()).GetBytes(ToString()); } #endif } }