using System; using System.Collections; using System.Runtime.InteropServices; using System.Text; using System.Xml; namespace Intel.Management.Wsman { class WsmanEnumeration : IWsmanEnumeration, IEnumerable { private WsmanConnection _conn; private XmlDocument _document; private XmlNamespaceManager _ns; private WsmanEnumerator _internal; public WsmanEnumeration(WsmanConnection conn, XmlDocument document, XmlNamespaceManager ns) { _conn = conn; _document = document; _ns=ns; } public IWsmanConnection Connection { get { return _conn; } } [DispId(-4)] public IEnumerator GetEnumerator() { if (_internal == null) _internal = new WsmanEnumerator(this); return _internal; } public bool HasNext { get { XmlElement itemsElt; XmlNode endSeqNod; if (_internal == null) _internal = new WsmanEnumerator(this); return _internal.CheckForItems(out itemsElt,out endSeqNod); } } public IWsmanItem Next() { if (_internal == null) _internal = new WsmanEnumerator(this); _internal.MoveNext(); return (IWsmanItem)_internal.Current; } internal class WsmanEnumerator : IEnumerator { private XmlDocument _items; private XmlNamespaceManager _itemsNs; private object _object; private WsmanEnumeration _enum; private XmlNode _endSeqNode; public WsmanEnumerator(WsmanEnumeration wsEnum) { _enum = wsEnum; _items = null; _itemsNs = null; _object = null; } public bool CheckForItems(out XmlElement itemsElt, out XmlNode endSeqNode) { itemsElt = null; endSeqNode = null; // check for dead enumerator if (_enum._document == null) { _object = null; return false; } // we don't have a dead enumerator so pull items if (_items == null) { _items = (XmlDocument)_enum._conn.SubmitRequest(_enum._document, null, null); if(_items != null) LoadNamespaces(_items); } if (_items != null) { _endSeqNode = endSeqNode = _items.DocumentElement.SelectSingleNode("s:Body/n:PullResponse/n:EndOfSequence", _itemsNs); itemsElt = (XmlElement)_items.DocumentElement.SelectSingleNode("s:Body/n:PullResponse/n:Items", _itemsNs); if ((itemsElt != null && itemsElt.HasChildNodes) || endSeqNode==null) return true; } return false; } public object Current { get { if (_object == null) throw new InvalidOperationException(); return _object; } } public bool MoveNext() { XmlElement itemsElt; XmlNode endSeqNode; if (!CheckForItems(out itemsElt,out endSeqNode)) return false; _object = null; XmlNode node = null; if(itemsElt != null) node = itemsElt.FirstChild; if (node != null) { if (node.NamespaceURI.Equals(WsmanResources.ADDRESSING_NS)) { _object = new WsmanItem( new ManagedReference(_enum._conn, node.OuterXml)); } else if (node.NamespaceURI.Equals(WsmanResources.WSMAN_NS) && node.LocalName.Equals("Item")) { IManagedReference refObj=null; IManagedInstance instObj=null; XmlNode child = node.FirstChild; if (child != null) { if (node.NamespaceURI.Equals(WsmanResources.ADDRESSING_NS)) refObj = new ManagedReference(_enum._conn, child.OuterXml); else instObj = new ManagedInstance(_enum._conn, child.OuterXml); child = child.NextSibling; if (child != null && instObj == null) instObj = new ManagedInstance(_enum._conn, child.OuterXml); else if (child != null && refObj == null) refObj = new ManagedReference(_enum._conn, child.OuterXml); } _object = new WsmanItem(instObj,refObj); } else { _object = new WsmanItem( new ManagedInstance(_enum._conn, node.OuterXml)); } itemsElt.RemoveChild(node); if (itemsElt.ChildNodes.Count == 0) { if (endSeqNode != null) { _enum._document = null; _enum._ns = null; _items = null; _itemsNs = null; } else { _items = null; _itemsNs = null; } } return true; } return false; } public void Reset() { throw new NotSupportedException(); } public void Dispose() { // check for dead enumerator if (_enum._document == null) return; // Check if the pulling objects from the FW not already ended. if (_endSeqNode == null) { // Build the enumeration conext node. string enumContaxt = _enum._document.DocumentElement.GetElementsByTagName("n:Pull")[0].ChildNodes[0].OuterXml; StringBuilder releaseNode = new StringBuilder(); releaseNode.Append(""); releaseNode.Append(enumContaxt); releaseNode.Append(""); // Plannt the relevant action. _enum._document.DocumentElement.GetElementsByTagName("a:Action")[0].InnerText = "http://schemas.xmlsoap.org/ws/2004/09/enumeration/Release"; _enum._document.DocumentElement.GetElementsByTagName("s:Body")[0].RemoveAll(); // Remove the exist body. _enum._document.DocumentElement.GetElementsByTagName("s:Body")[0].InnerXml = releaseNode.ToString(); // Plant the new body. _enum._conn.SubmitRequest(_enum._document, null, null); } _object = null; _enum._document = null; _enum._ns = null; _items = null; _itemsNs = null; } private void LoadNamespaces(XmlDocument document) { _itemsNs = new XmlNamespaceManager(document.NameTable); _itemsNs.AddNamespace("s", WsmanResources.SOAP_NS); _itemsNs.AddNamespace("n", WsmanResources.ENUM_NS); } } public void Dispose() { //release the enumerator if not complete //firmware only supports 3 enumerators Close(); } public void Close() { _internal.Dispose(); } } }