/* ----------------------------------------------------------
文件名稱:UsbEnumXML.cs
作者:秦建輝
QQ:36748897
博客:http://blog.csdn.net/jhqin
開發環境:
Visual Studio V2010
.NET Framework 4 Client Profile
版本歷史:
V1.0 2011年10月28日
將USB設備枚舉信息導出為XML文檔
------------------------------------------------------------ */
using System;
using System.Collections.Generic;
using System.Xml.Linq;
namespace Splash.IO.PORTS
{
/// <summary>
/// 將USB設備信息寫入XML文件
/// </summary>
public partial class USB
{
/// <summary>
/// 將USB設備枚舉信息導出為XML文檔
/// </summary>
/// <param name="xmlFileName">保存的XML文件名</param>
/// <returns>
/// true:成功
/// false:失敗
/// </returns>
public static Boolean EnumUsbToXML(String xmlFileName)
{ // 創建根節點
XElement RootNode = new XElement("Computer",
new XAttribute("MachineName", System.Environment.MachineName));
// 深度遍歷主控制器
HostControllerInfo[] HostControllersCollection = USB.AllHostControllers;
if (HostControllersCollection != null)
{
Int32 ControllerIndex = 1;
foreach (HostControllerInfo item in HostControllersCollection)
{ // 創建主控制器節點
String PNPDeviceID = item.PNPDeviceID;
String HcdDriverKeyName = USB.GetHcdDriverKeyName(PNPDeviceID);
XElement HostControllerNode = new XElement("HostController" + ControllerIndex,
new XAttribute("Name", item.Name), // 設備名稱
new XAttribute("PNPDeviceID", PNPDeviceID), // 設備ID
new XAttribute("HcdDriverKeyName", HcdDriverKeyName) // 驅動鍵名
);
RootNode.Add(HostControllerNode);
ControllerIndex++;
// 創建根集線器節點
String RootHubPath = USB.GetUsbRootHubPath(PNPDeviceID);
AddHubNode(HostControllerNode, RootHubPath, "RootHub");
}
}
// 創建XML文檔
XDocument xmlTree = new XDocument(RootNode);
// 存儲文件,序列化時對XML進行格式設置(縮進)
xmlTree.Save(xmlFileName, SaveOptions.None);
return true;
}
/// <summary>
/// 增加集線器節點
/// </summary>
/// <param name="ParentNode">父節點</param>
/// <param name="HubPath">集線器路徑</param>
private static void AddHubNode(XElement ParentNode, String HubPath, String HubNodeName)
{
UsbNodeInformation[] NodeInfoCollection = USB.GetUsbNodeInformation(HubPath);
if (NodeInfoCollection != null)
{
USB_HUB_NODE NodeType = NodeInfoCollection[0].NodeType;
XElement HubNode = new XElement(HubNodeName,
new XAttribute("Name", NodeInfoCollection[0].Name),
new XAttribute("PNPDeviceID", NodeInfoCollection[0].PNPDeviceID),
new XAttribute("Path", NodeInfoCollection[0].DevicePath),
new XAttribute("NodeType", NodeType)
);
if (NodeType == USB_HUB_NODE.UsbHub)
{
Int32 NumberOfPorts = NodeInfoCollection[0].NumberOfPorts;
HubNode.Add(new XAttribute("NumberOfPorts", NumberOfPorts),
new XAttribute("HubIsBusPowered", NodeInfoCollection[0].HubIsBusPowered),
new XAttribute("HubCharacteristics", "0x" + NodeInfoCollection[0].HubCharacteristics.ToString("X4")),
new XAttribute("PowerOnToPowerGood", NodeInfoCollection[0].PowerOnToPowerGood),
new XAttribute("HubControlCurrent", NodeInfoCollection[0].HubControlCurrent)
);
// 深度遍歷端口
UsbNodeConnectionInformation[] NodeConnectionInfoCollection = USB.GetUsbNodeConnectionInformation(HubPath, NumberOfPorts);
if (NodeConnectionInfoCollection != null)
{
foreach (UsbNodeConnectionInformation NodeConnectionInfo in NodeConnectionInfoCollection)
{ // 增加端口節點
AddPortNode(HubNode, NodeConnectionInfo);
}
}
}
else
{
HubNode.Add("NumberOfInterfaces", NodeInfoCollection[0].NumberOfInterfaces);
}
ParentNode.Add(HubNode);
}
}
/// <summary>
/// 增加端口節點
/// </summary>
/// <param name="HubNode">集線器節點</param>
/// <param name="NodeConnectionInfo">USB設備節點連接信息</param>
private static void AddPortNode(XElement HubNode, UsbNodeConnectionInformation NodeConnectionInfo)
{
String DevicePath = NodeConnectionInfo.DevicePath;
Int32 ConnectionIndex = NodeConnectionInfo.ConnectionIndex;
USB_CONNECTION_STATUS ConnectionStatus = NodeConnectionInfo.ConnectionStatus;
// 創建端口節點
XElement PortNode = new XElement("Port" + ConnectionIndex,
new XAttribute("DevicePath", DevicePath),
new XAttribute("ConnectionIndex", ConnectionIndex),
new XAttribute("ConnectionStatus", NodeConnectionInfo.ConnectionStatus)
);
if (ConnectionStatus == USB_CONNECTION_STATUS.DeviceConnected)
{
Boolean DeviceIsHub = NodeConnectionInfo.DeviceIsHub;
PortNode.Add(new XAttribute("DeviceIsHub", DeviceIsHub),
new XAttribute("CurrentConfigurationValue", NodeConnectionInfo.CurrentConfigurationValue),
new XAttribute("Speed", NodeConnectionInfo.Speed),
new XAttribute("DeviceAddress", NodeConnectionInfo.DeviceAddress),
new XAttribute("NumberOfOpenPipes", NodeConnectionInfo.NumberOfOpenPipes)
);
// 設備描述符信息
AddDeviceDescriptorNode(PortNode, ref NodeConnectionInfo.DeviceDescriptor);
// 管道信息
AddPipeInfoNode(PortNode, ref NodeConnectionInfo.PipeList);
// 外部集線器
if (DeviceIsHub)
{ // 獲取外部Hub設備路徑
String ExternalHubPath = GetExternalHubPath(DevicePath, ConnectionIndex);
// 增加外部集線器節點
AddHubNode(PortNode, ExternalHubPath, "ExternalHub");
}
}
HubNode.Add(PortNode);
}
/// <summary>
/// 增加設備描述符節點
/// </summary>
/// <param name="PortNode"></param>
/// <param name="DeviceDescriptor"></param>
private static void AddDeviceDescriptorNode(XElement PortNode, ref UsbDeviceDescriptor DeviceDescriptor)
{
XElement DeviceDescriptorNode = new XElement("DeviceDescriptor",
new XAttribute("bDescriptorType", "0x" + DeviceDescriptor.bDescriptorType.ToString("X2")),
new XAttribute("UsbVersion", DeviceDescriptor.UsbVersion),
new XAttribute("bDeviceClass", "0x" + DeviceDescriptor.bDeviceClass.ToString("X2")),
new XAttribute("bDeviceSubClass", "0x" + DeviceDescriptor.bDeviceSubClass.ToString("X2")),
new XAttribute("bDeviceProtocol", "0x" + DeviceDescriptor.bDeviceProtocol.ToString("X2")),
new XAttribute("bMaxPacketSize0", DeviceDescriptor.bMaxPacketSize0),
new XAttribute("bNumConfigurations", DeviceDescriptor.bNumConfigurations)
);
if (DeviceDescriptor.idVendor != 0)
{
DeviceDescriptorNode.Add(new XAttribute("idVendor", "0x" + DeviceDescriptor.idVendor.ToString("X4")));
}
if (DeviceDescriptor.idProduct != 0)
{
DeviceDescriptorNode.Add(new XAttribute("idProduct", "0x" + DeviceDescriptor.idProduct.ToString("X4")));
}
if (!String.IsNullOrEmpty(DeviceDescriptor.DeviceVersion))
{
DeviceDescriptorNode.Add(new XAttribute("DeviceVersion", DeviceDescriptor.DeviceVersion));
}
if (!String.IsNullOrEmpty(DeviceDescriptor.Manufacturer))
{
DeviceDescriptorNode.Add(new XAttribute("Manufacturer", DeviceDescriptor.Manufacturer));
}
if (!String.IsNullOrEmpty(DeviceDescriptor.Product))
{
DeviceDescriptorNode.Add(new XAttribute("Product", DeviceDescriptor.Product));
}
if (!String.IsNullOrEmpty(DeviceDescriptor.SerialNumber))
{
DeviceDescriptorNode.Add(new XAttribute("SerialNumber", DeviceDescriptor.SerialNumber));
}
PortNode.Add(DeviceDescriptorNode);
}
/// <summary>
/// 增加管道信息節點
/// </summary>
/// <param name="PortNode">端口節點</param>
/// <param name="PipeList">管道信息列表</param>
private static void AddPipeInfoNode(XElement PortNode, ref List<UsbPipeInfo> PipeList)
{
if(PipeList != null)
{
XElement PipeListNode = new XElement("PipeList");
Int32 PipeIndex = 1;
foreach(UsbPipeInfo item in PipeList)
{
XElement PipeInfoNode = new XElement("Pipe" + PipeIndex,
new XAttribute("ScheduleOffset", item.ScheduleOffset),
new XAttribute("bDescriptorType", "0x" + item.bDescriptorType.ToString("X2")),
new XAttribute("bEndpointAddress", "0x" + item.bEndpointAddress.ToString("X2")),
new XAttribute("bmAttributes", "0x" + item.bmAttributes.ToString("X2")),
new XAttribute("wMaxPacketSize", item.wMaxPacketSize),
new XAttribute("bInterval", item.bInterval)
);
PipeListNode.Add(PipeInfoNode);
PipeIndex++;
}
PortNode.Add(PipeListNode);
}
}
}
}