(一)DeviceIoControl的PInvoke

/* ----------------------------------------------------------
文件名称:DeviceIoControl.cs 作者:秦建辉 MSN:splashcn@msn.com
QQ:36748897 博客:http://blog.csdn.net/jhqin 开发环境:
Visual Studio V2010
.NET Framework 4 Client Profile 版本历史:
V1.0 2011年10月10日
实现对DeviceIoControl接口的PInvoke 参考资料:
http://www.pinvoke.net/
------------------------------------------------------------ */
using System;
using System.Runtime.InteropServices; namespace Splash.IO.PORTS
{
#region ENUM
public enum USB_HUB_NODE : uint
{
UsbHub,
UsbMIParent
} public enum USB_CONNECTION_STATUS
{
NoDeviceConnected,
DeviceConnected,
DeviceFailedEnumeration,
DeviceGeneralFailure,
DeviceCausedOvercurrent,
DeviceNotEnoughPower,
DeviceNotEnoughBandwidth,
DeviceHubNestedTooDeeply,
DeviceInLegacyHub
} public enum USB_DEVICE_SPEED : byte
{
UsbLowSpeed, // 低速USB 1.1
UsbFullSpeed, // 全速USB 1.1
UsbHighSpeed, // 高速USB 2.0
UsbSuperSpeed // 极速USB 3.0
}
#endregion public partial class USB
{
internal const Int32 IOCTL_GET_HCD_DRIVERKEY_NAME = 0x220424;
internal const Int32 IOCTL_USB_GET_ROOT_HUB_NAME = 0x220408;
internal const Int32 IOCTL_USB_GET_NODE_CONNECTION_NAME = 0x220414;
internal const Int32 IOCTL_USB_GET_NODE_INFORMATION = 0x220408;
internal const Int32 IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX = 0x220448;
internal const Int32 IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION = 0x220410; internal const Int32 MAXIMUM_USB_STRING_LENGTH = ;
internal const Int32 USB_STRING_DESCRIPTOR_TYPE = ; [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal struct USB_HCD_DRIVERKEY_NAME
{
public Int32 ActualLength;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
public String Name;
} #region USB_NODE_INFORMATION
[StructLayout(LayoutKind.Sequential, Pack = )]
internal struct USB_HUB_DESCRIPTOR
{
public Byte bDescriptorLength;
public Byte bDescriptorType; // 描述符类型:0x29
public Byte bNumberOfPorts; // 支持的下游端口数目
public Int16 wHubCharacteristics; // 特征描述
public Byte bPowerOnToPowerGood; // 从端口加电到端口正常工作的时间间隔(以2ms为单位)
public Byte bHubControlCurrent; // 设备所需最大电流
[MarshalAs(UnmanagedType.ByValArray, SizeConst = )]
public Byte[] bRemoveAndPowerMask; // 指示连接在集线器端口的设备是否可移走
} [StructLayout(LayoutKind.Sequential)]
internal struct USB_HUB_INFORMATION
{
public USB_HUB_DESCRIPTOR HubDescriptor;
public Byte HubIsBusPowered;
} [StructLayout(LayoutKind.Sequential)]
internal struct USB_MI_PARENT_INFORMATION
{
public Int32 NumberOfInterfaces;
}; [StructLayout(LayoutKind.Explicit)]
internal struct UsbNodeUnion
{
[FieldOffset()]
public USB_HUB_INFORMATION HubInformation;
[FieldOffset()]
public USB_MI_PARENT_INFORMATION MiParentInformation;
} [StructLayout(LayoutKind.Sequential)]
internal struct USB_NODE_INFORMATION
{
public USB_HUB_NODE NodeType;
public UsbNodeUnion u;
}
#endregion #region USB_NODE_CONNECTION_INFORMATION
[StructLayout(LayoutKind.Sequential, Pack = )]
internal struct USB_DEVICE_DESCRIPTOR
{
public Byte bLength;
public Byte bDescriptorType;
public UInt16 bcdUSB;
public Byte bDeviceClass;
public Byte bDeviceSubClass;
public Byte bDeviceProtocol;
public Byte bMaxPacketSize0;
public UInt16 idVendor;
public UInt16 idProduct;
public UInt16 bcdDevice;
public Byte iManufacturer;
public Byte iProduct;
public Byte iSerialNumber;
public Byte bNumConfigurations;
} [StructLayout(LayoutKind.Sequential, Pack = )]
internal struct USB_ENDPOINT_DESCRIPTOR
{
public Byte bLength;
public Byte bDescriptorType;
public Byte bEndpointAddress;
public Byte bmAttributes;
public UInt16 wMaxPacketSize;
public Byte bInterval;
} [StructLayout(LayoutKind.Sequential, Pack = )]
internal struct USB_PIPE_INFO
{
public USB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
public UInt32 ScheduleOffset;
} [StructLayout(LayoutKind.Sequential, Pack = )]
internal struct USB_NODE_CONNECTION_INFORMATION_EX
{
public Int32 ConnectionIndex;
public USB_DEVICE_DESCRIPTOR DeviceDescriptor;
public Byte CurrentConfigurationValue;
public Byte Speed;
public Byte DeviceIsHub;
public Int16 DeviceAddress;
public Int32 NumberOfOpenPipes;
public USB_CONNECTION_STATUS ConnectionStatus;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = )]
public USB_PIPE_INFO[] PipeList;
}
#endregion #region USB_DESCRIPTOR_REQUEST
[StructLayout(LayoutKind.Sequential)]
internal struct USB_SETUP_PACKET
{
public Byte bmRequest;
public Byte bRequest;
public UInt16 wValue;
public UInt16 wIndex;
public UInt16 wLength;
} [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal struct USB_STRING_DESCRIPTOR
{
public Byte bLength;
public Byte bDescriptorType;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAXIMUM_USB_STRING_LENGTH)]
public String bString;
} [StructLayout(LayoutKind.Sequential)]
internal struct USB_DESCRIPTOR_REQUEST
{
public Int32 ConnectionIndex;
public USB_SETUP_PACKET SetupPacket;
public USB_STRING_DESCRIPTOR Data;
}
#endregion #region USB_NODE_CONNECTION_DRIVERKEY_NAME
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal struct USB_NODE_CONNECTION_DRIVERKEY_NAME
{
public Int32 ConnectionIndex;
public Int32 ActualLength;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAXIMUM_USB_STRING_LENGTH)]
public String DriverKeyName;
}
#endregion #region DeviceIoControl
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern Boolean DeviceIoControl(
IntPtr hFile,
Int32 dwIoControlCode,
IntPtr lpInBuffer,
Int32 nInBufferSize,
ref USB_HCD_DRIVERKEY_NAME lpOutBuffer,
Int32 nOutBufferSize,
out Int32 nBytesReturned,
IntPtr lpOverlapped
); [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern Boolean DeviceIoControl(
IntPtr hFile,
Int32 dwIoControlCode,
ref USB_NODE_INFORMATION lpInBuffer,
Int32 nInBufferSize,
ref USB_NODE_INFORMATION lpOutBuffer,
Int32 nOutBufferSize,
out Int32 lpBytesReturned,
IntPtr lpOverlapped
); [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern Boolean DeviceIoControl(
IntPtr hFile,
Int32 dwIoControlCode,
ref USB_NODE_CONNECTION_INFORMATION_EX lpInBuffer,
Int32 nInBufferSize,
ref USB_NODE_CONNECTION_INFORMATION_EX lpOutBuffer,
Int32 nOutBufferSize,
out Int32 lpBytesReturned,
IntPtr lpOverlapped
); [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern Boolean DeviceIoControl(
IntPtr hFile,
Int32 dwIoControlCode,
ref USB_DESCRIPTOR_REQUEST lpInBuffer,
Int32 nInBufferSize,
ref USB_DESCRIPTOR_REQUEST lpOutBuffer,
Int32 nOutBufferSize,
out Int32 lpBytesReturned,
IntPtr lpOverlapped
); [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern Boolean DeviceIoControl(
IntPtr hFile,
Int32 dwIoControlCode,
ref USB_NODE_CONNECTION_DRIVERKEY_NAME lpInBuffer,
Int32 nInBufferSize,
ref USB_NODE_CONNECTION_DRIVERKEY_NAME lpOutBuffer,
Int32 nOutBufferSize,
out Int32 lpBytesReturned,
IntPtr lpOverlapped
);
#endregion
}
}

(二)设备枚举API

/* ----------------------------------------------------------
文件名称:WDKUsbEnum.cs 作者:秦建辉 MSN:splashcn@msn.com
QQ:36748897 博客:http://blog.csdn.net/jhqin 开发环境:
Visual Studio V2010
.NET Framework 4 Client Profile 版本历史:
V1.0 2011年10月10日
基于WDK枚举USB设备
------------------------------------------------------------ */
using System;
using System.Collections.Generic;
using System.Management;
using System.Runtime.InteropServices;
using System.Text; namespace Splash.IO.PORTS
{
/// <summary>
/// USB主控制器信息
/// </summary>
public struct HostControllerInfo
{
public String PNPDeviceID; // 设备ID
public String Name; // 设备名称
} /// <summary>
/// USB Hub信息
/// </summary>
public struct UsbHubInfo
{
public String PNPDeviceID; // 设备ID
public String Name; // 设备名称
public String Status; // 设备状态
} /// <summary>
/// USB HUB节点信息
/// </summary>
public struct UsbNodeInformation
{
public String DevicePath; // 设备路径
public String PNPDeviceID; // 设备ID
public String Name; // 设备名称 public USB_HUB_NODE NodeType; // 节点类型 // USB_HUB_INFORMATION
public Boolean HubIsBusPowered; // 供电方式:true-总线供电 false-独立供电
public Int32 NumberOfPorts; // 端口数
public Int16 HubCharacteristics; // 特征描述
public Byte PowerOnToPowerGood; // 从端口加电到端口正常工作的时间间隔(以2ms为单位)
public Byte HubControlCurrent; // 设备所需最大电流 // USB_MI_PARENT_INFORMATION
public Int32 NumberOfInterfaces; // 接口数
} /// <summary>
/// USB设备描述符
/// </summary>
public struct UsbDeviceDescriptor
{
public Byte bDescriptorType; // 描述符类型 USB_DEVICE_DESCRIPTOR_TYPE
public String UsbVersion; // USB规格版本号
public Byte bDeviceClass; // 设备类型
public Byte bDeviceSubClass; // 设备子类型
public Byte bDeviceProtocol; // 设备协议
public Byte bMaxPacketSize0; // 最大封包大小
public UInt16 idVendor; // VID
public UInt16 idProduct; // PID
public String DeviceVersion; // 设备版本号
public String Manufacturer; // 制造商
public String Product; // 产品描述
public String SerialNumber; // 序列号
public Byte bNumConfigurations; // 配置总数
} /// <summary>
/// USB管道信息
/// </summary>
public struct UsbPipeInfo
{
public UInt32 ScheduleOffset;
public Byte bDescriptorType;
public Byte bEndpointAddress;
public Byte bmAttributes;
public UInt16 wMaxPacketSize;
public Byte bInterval;
} /// <summary>
/// USB节点连接信息
/// </summary>
public struct UsbNodeConnectionInformation
{
public String DevicePath; // 设备路径
public Int32 ConnectionIndex; // 端口号 public UsbDeviceDescriptor DeviceDescriptor; public Byte CurrentConfigurationValue; // 当前设备配置
public Byte Speed; // 设备速度
public Boolean DeviceIsHub; // 是否是集线器
public Int32 DeviceAddress; // 设备地址
public Int32 NumberOfOpenPipes; // 管道数
public USB_CONNECTION_STATUS ConnectionStatus; // 连接状态 public List<UsbPipeInfo> PipeList; // 管道信息
} /// <summary>
/// USB设备枚举
/// </summary>
public partial class USB
{
#region HostController
/// <summary>
/// USB主控制器
/// </summary>
public static HostControllerInfo[] AllHostControllers
{
get
{
List<HostControllerInfo> HostControllers = new List<HostControllerInfo>(); // 获取USB控制器及其相关联的设备实体
ManagementObjectCollection MOC = new ManagementObjectSearcher("SELECT * FROM Win32_USBController").Get();
if (MOC != null)
{
foreach (ManagementObject MO in MOC)
{
HostControllerInfo Element;
Element.PNPDeviceID = MO["PNPDeviceID"] as String; // 设备ID
Element.Name = MO["Name"] as String; // 设备描述
HostControllers.Add(Element);
}
} if (HostControllers.Count == ) return null; else return HostControllers.ToArray();
}
} /// <summary>
/// 获取驱动键名
/// </summary>
/// <param name="PNPDeviceID">USB主控制器设备ID</param>
/// <returns>获取设备驱动在注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class下的路径</returns>
public static String GetHcdDriverKeyName(String PNPDeviceID)
{
if (String.IsNullOrEmpty(PNPDeviceID)) return null; // 打开设备
IntPtr hHCDev = Kernel32.CreateFile(
"\\\\.\\" + PNPDeviceID.Replace('\\', '#') + "#{3ABF6F2D-71C4-462A-8A92-1E6861E6AF27}",
NativeFileAccess.GENERIC_WRITE,
NativeFileShare.FILE_SHARE_WRITE,
IntPtr.Zero,
NativeFileMode.OPEN_EXISTING,
IntPtr.Zero,
IntPtr.Zero);
if (hHCDev == Kernel32.INVALID_HANDLE_VALUE) return null; // 获取驱动键名
Int32 nBytesReturned;
USB_HCD_DRIVERKEY_NAME Buffer = new USB_HCD_DRIVERKEY_NAME();
Boolean Status = DeviceIoControl(hHCDev,
IOCTL_GET_HCD_DRIVERKEY_NAME,
IntPtr.Zero,
,
ref Buffer,
Marshal.SizeOf(Buffer),
out nBytesReturned,
IntPtr.Zero); // 关闭设备
Kernel32.CloseHandle(hHCDev);
return Status ? Buffer.Name : null;
}
#endregion #region USBHUB
/// <summary>
/// USB Hub信息集合
/// </summary>
public static UsbHubInfo[] AllUsbHubs
{
get
{
List<UsbHubInfo> UsbHubs = new List<UsbHubInfo>(); // 获取USB控制器及其相关联的设备实体
ManagementObjectCollection MOC = new ManagementObjectSearcher("SELECT * FROM Win32_USBHub").Get();
if (MOC != null)
{
foreach (ManagementObject MO in MOC)
{
UsbHubInfo Element;
Element.PNPDeviceID = MO["PNPDeviceID"] as String; // 设备ID
Element.Name = MO["Name"] as String; // 设备描述
Element.Status = MO["Status"] as String; // 设备状态
UsbHubs.Add(Element);
}
} if (UsbHubs.Count == ) return null; else return UsbHubs.ToArray();
}
} /// <summary>
/// USB ROOT HUB设备路径
/// </summary>
/// <param name="PNPDeviceID">USB主控制器设备ID</param>
/// <returns>USB ROOT HUB设备路径</returns>
public static String GetUsbRootHubPath(String PNPDeviceID)
{
if (String.IsNullOrEmpty(PNPDeviceID)) return null; // 打开设备
IntPtr hHCDev = Kernel32.CreateFile(
"\\\\.\\" + PNPDeviceID.Replace('\\', '#') + "#{3ABF6F2D-71C4-462A-8A92-1E6861E6AF27}",
NativeFileAccess.GENERIC_WRITE,
NativeFileShare.FILE_SHARE_WRITE,
IntPtr.Zero,
NativeFileMode.OPEN_EXISTING,
IntPtr.Zero,
IntPtr.Zero);
if (hHCDev == Kernel32.INVALID_HANDLE_VALUE) return null; // 获取USB ROOT HUB名称
Int32 nBytesReturned;
USB_HCD_DRIVERKEY_NAME Buffer = new USB_HCD_DRIVERKEY_NAME();
Boolean Status = DeviceIoControl(hHCDev,
IOCTL_USB_GET_ROOT_HUB_NAME,
IntPtr.Zero,
,
ref Buffer,
Marshal.SizeOf(Buffer),
out nBytesReturned,
IntPtr.Zero); // 关闭设备
Kernel32.CloseHandle(hHCDev);
return Status ? Buffer.Name : null;
} /// <summary>
/// USB HUB设备名称
/// </summary>
/// <param name="DevicePath">设备路径</param>
/// <returns>设备名称</returns>
public static String GetUsbHubName(String DevicePath)
{
if (String.IsNullOrEmpty(DevicePath)) return null; // 从设备路径中提取设备ID
String DeviceID = DevicePath.Substring(, DevicePath.LastIndexOf('#')).Replace('#', '_'); // 从Win32_USBHub获取设备描述
ManagementObjectCollection MOC = new ManagementObjectSearcher("SELECT * FROM Win32_USBHub WHERE DeviceID LIKE '" + DeviceID + "'").Get();
if (MOC != null)
{
foreach (ManagementObject MO in MOC)
{
return MO["Name"] as String;
}
} return null;
} /// <summary>
/// 获取USB HUB节点信息
/// </summary>
/// <param name="DevicePath">USB HUB设备路径</param>
/// <returns>节点信息</returns>
public static UsbNodeInformation[] GetUsbNodeInformation(String DevicePath)
{
if (String.IsNullOrEmpty(DevicePath)) return null; // 打开设备文件
IntPtr hHubDevice = Kernel32.CreateFile(
"\\\\.\\" + DevicePath,
NativeFileAccess.GENERIC_WRITE,
NativeFileShare.FILE_SHARE_WRITE,
IntPtr.Zero,
NativeFileMode.OPEN_EXISTING,
IntPtr.Zero,
IntPtr.Zero);
if (hHubDevice == Kernel32.INVALID_HANDLE_VALUE) return null; // 查询节点信息
Int32 nBytesReturned;
USB_NODE_INFORMATION Buffer = new USB_NODE_INFORMATION();
Boolean Status = DeviceIoControl(hHubDevice,
IOCTL_USB_GET_NODE_INFORMATION,
ref Buffer,
Marshal.SizeOf(Buffer),
ref Buffer,
Marshal.SizeOf(Buffer),
out nBytesReturned,
IntPtr.Zero); // 关闭设备文件
Kernel32.CloseHandle(hHubDevice);
if (!Status) return null; UsbNodeInformation Node = new UsbNodeInformation();
Node.NodeType = Buffer.NodeType; // 节点类型
Node.PNPDeviceID = DevicePath.Substring(, DevicePath.LastIndexOf('#')).Replace('#', '\\'); // 设备ID
Node.DevicePath = DevicePath; // 设备路径
Node.Name = GetUsbHubName(DevicePath); // 设备名称
if (Buffer.NodeType == USB_HUB_NODE.UsbHub)
{
Node.NumberOfPorts = Buffer.u.HubInformation.HubDescriptor.bNumberOfPorts; // 端口数
Node.HubIsBusPowered = Convert.ToBoolean(Buffer.u.HubInformation.HubIsBusPowered); // 供电方式
Node.HubCharacteristics = Buffer.u.HubInformation.HubDescriptor.wHubCharacteristics;
Node.PowerOnToPowerGood = Buffer.u.HubInformation.HubDescriptor.bPowerOnToPowerGood;
Node.HubControlCurrent = Buffer.u.HubInformation.HubDescriptor.bHubControlCurrent;
}
else
{
Node.NumberOfInterfaces = Buffer.u.MiParentInformation.NumberOfInterfaces; // 接口数
} return new UsbNodeInformation[] { Node };
}
#endregion #region NODECONNECTION
/// <summary>
/// 获取USB节点连接信息
/// </summary>
/// <param name="DevicePath">设备路径</param>
/// <param name="NumberOfPorts">端口总数</param>
/// <returns>USB节点信息连接信息集合</returns>
public static UsbNodeConnectionInformation[] GetUsbNodeConnectionInformation(String DevicePath, Int32 NumberOfPorts)
{
if (String.IsNullOrEmpty(DevicePath)) return null; // 打开设备文件
IntPtr hHubDevice = Kernel32.CreateFile(
"\\\\.\\" + DevicePath,
NativeFileAccess.GENERIC_WRITE,
NativeFileShare.FILE_SHARE_WRITE,
IntPtr.Zero,
NativeFileMode.OPEN_EXISTING,
IntPtr.Zero,
IntPtr.Zero);
if (hHubDevice == Kernel32.INVALID_HANDLE_VALUE) return null; List<UsbNodeConnectionInformation> NodeCollection = new List<UsbNodeConnectionInformation>(); // 枚举端口
USB_NODE_CONNECTION_INFORMATION_EX Buffer = new USB_NODE_CONNECTION_INFORMATION_EX();
for (Int32 ConnectionIndex = ; ConnectionIndex <= NumberOfPorts; ConnectionIndex++)
{
// 查询节点信息
Int32 nBytesReturned;
Buffer.ConnectionIndex = ConnectionIndex;
Boolean Status = DeviceIoControl(hHubDevice,
IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX,
ref Buffer,
Marshal.SizeOf(Buffer),
ref Buffer,
Marshal.SizeOf(Buffer),
out nBytesReturned,
IntPtr.Zero);
if (Status)
{
// 确定语言ID
UInt16 LanguageID = SelectLanguageID(hHubDevice, ConnectionIndex); // 提取信息
UsbNodeConnectionInformation Node = new UsbNodeConnectionInformation(); Node.DevicePath = DevicePath;
Node.ConnectionIndex = Buffer.ConnectionIndex;
Node.ConnectionStatus = Buffer.ConnectionStatus;
if (Buffer.ConnectionStatus == USB_CONNECTION_STATUS.DeviceConnected)
{
Node.CurrentConfigurationValue = Buffer.CurrentConfigurationValue;
Node.Speed = Buffer.Speed;
Node.DeviceIsHub = Convert.ToBoolean(Buffer.DeviceIsHub);
Node.DeviceAddress = Buffer.DeviceAddress;
Node.NumberOfOpenPipes = Buffer.NumberOfOpenPipes; // 设备描述符
Node.DeviceDescriptor.bDescriptorType = Buffer.DeviceDescriptor.bDescriptorType;
Node.DeviceDescriptor.bDeviceClass = Buffer.DeviceDescriptor.bDeviceClass;
Node.DeviceDescriptor.bDeviceSubClass = Buffer.DeviceDescriptor.bDeviceSubClass;
Node.DeviceDescriptor.bDeviceProtocol = Buffer.DeviceDescriptor.bDeviceProtocol; Node.DeviceDescriptor.UsbVersion = BcdVersionToString(Buffer.DeviceDescriptor.bcdUSB); // USB版本号
Node.DeviceDescriptor.DeviceVersion = BcdVersionToString(Buffer.DeviceDescriptor.bcdDevice); // 设备版本号 Node.DeviceDescriptor.idVendor = Buffer.DeviceDescriptor.idVendor; // 厂商标识
Node.DeviceDescriptor.idProduct = Buffer.DeviceDescriptor.idProduct; // 产品标识 if (LanguageID != )
{
if (Buffer.DeviceDescriptor.iSerialNumber != )
{ // 序列号
Node.DeviceDescriptor.SerialNumber = GetStringDescriptor(hHubDevice,
Buffer.ConnectionIndex,
Buffer.DeviceDescriptor.iSerialNumber,
LanguageID);
} if (Buffer.DeviceDescriptor.iManufacturer != )
{ // 制造商名称
Node.DeviceDescriptor.Manufacturer = GetStringDescriptor(hHubDevice,
Buffer.ConnectionIndex,
Buffer.DeviceDescriptor.iManufacturer,
LanguageID);
} if (Buffer.DeviceDescriptor.iProduct != )
{ // 产品名称
Node.DeviceDescriptor.Product = GetStringDescriptor(hHubDevice,
Buffer.ConnectionIndex,
Buffer.DeviceDescriptor.iProduct,
LanguageID);
}
} Node.DeviceDescriptor.bMaxPacketSize0 = Buffer.DeviceDescriptor.bMaxPacketSize0;
Node.DeviceDescriptor.bNumConfigurations = Buffer.DeviceDescriptor.bNumConfigurations; // 管道信息
Node.PipeList = new List<UsbPipeInfo>();
for (Int32 PipeIndex = ; PipeIndex < Buffer.NumberOfOpenPipes; PipeIndex++)
{
UsbPipeInfo PipeInfo; PipeInfo.ScheduleOffset = Buffer.PipeList[PipeIndex].ScheduleOffset;
PipeInfo.bDescriptorType = Buffer.PipeList[PipeIndex].EndpointDescriptor.bDescriptorType;
PipeInfo.bEndpointAddress = Buffer.PipeList[PipeIndex].EndpointDescriptor.bEndpointAddress;
PipeInfo.bmAttributes = Buffer.PipeList[PipeIndex].EndpointDescriptor.bmAttributes;
PipeInfo.wMaxPacketSize = Buffer.PipeList[PipeIndex].EndpointDescriptor.wMaxPacketSize;
PipeInfo.bInterval = Buffer.PipeList[PipeIndex].EndpointDescriptor.bInterval; Node.PipeList.Add(PipeInfo);
}
} NodeCollection.Add(Node);
}
} // 关闭设备文件
Kernel32.CloseHandle(hHubDevice); // 返回结果
if (NodeCollection.Count == )
return null;
else
return NodeCollection.ToArray();
} /// <summary>
/// 获取字符串描述符
/// </summary>
/// <param name="hHubDevice">USB Hub设备句柄</param>
/// <param name="ConnectionIndex">连接索引号</param>
/// <param name="DescriptorIndex">描述符索引号</param>
/// <param name="LanguageID">语言ID</param>
/// <returns>字符串描述符</returns>
public static String GetStringDescriptor(IntPtr hHubDevice, Int32 ConnectionIndex, Byte DescriptorIndex, UInt16 LanguageID)
{
USB_DESCRIPTOR_REQUEST Buffer = new USB_DESCRIPTOR_REQUEST();
Buffer.ConnectionIndex = ConnectionIndex;
Buffer.SetupPacket.wValue = (UInt16)((USB_STRING_DESCRIPTOR_TYPE << ) | DescriptorIndex);
Buffer.SetupPacket.wIndex = LanguageID;
Buffer.SetupPacket.wLength = MAXIMUM_USB_STRING_LENGTH;
Int32 nBytesReturned;
Boolean Status = DeviceIoControl(hHubDevice,
IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION,
ref Buffer,
Marshal.SizeOf(Buffer),
ref Buffer,
Marshal.SizeOf(Buffer),
out nBytesReturned,
IntPtr.Zero);
if (Status)
return Buffer.Data.bString;
else
return null;
} /// <summary>
/// 选择语言ID
/// </summary>
/// <param name="hHubDevice">USB Hub设备句柄</param>
/// <param name="ConnectionIndex">连接索引号</param>
/// <returns></returns>
public static UInt16 SelectLanguageID(IntPtr hHubDevice, Int32 ConnectionIndex)
{
// 获取支持的语言列表
String SupportedLanguagesString = GetStringDescriptor(hHubDevice, ConnectionIndex, , );
if(String.IsNullOrEmpty(SupportedLanguagesString))return ; UInt16 UserDefaultUILanguage = Splash.Environment.UserDefaultUILanguage;
if(SupportedLanguagesString.IndexOf(Convert.ToChar(UserDefaultUILanguage)) != -)
{ // 用户缺省界面语言
return UserDefaultUILanguage;
}
else if(SupportedLanguagesString.IndexOf(Convert.ToChar(0x0409)) != -)
{ // 美国英语 0x0409
return 0x0409;
}
else
{ // 第一个可选择的LANGID
return Convert.ToUInt16(SupportedLanguagesString[]);
}
}
#endregion #region EXTERNALHUB
/// <summary>
/// 获取外接Hub设备路径
/// </summary>
/// <param name="ParentDevicePath">上层Hub设备路径</param>
/// <param name="ConnectionIndex">连接索引号</param>
/// <returns>外接Hub设备路径</returns>
public static String GetExternalHubPath(String ParentDevicePath, Int32 ConnectionIndex)
{
if (String.IsNullOrEmpty(ParentDevicePath)) return null; // 打开设备文件
IntPtr hParentHubDevice = Kernel32.CreateFile(
"\\\\.\\" + ParentDevicePath,
NativeFileAccess.GENERIC_WRITE,
NativeFileShare.FILE_SHARE_WRITE,
IntPtr.Zero,
NativeFileMode.OPEN_EXISTING,
IntPtr.Zero,
IntPtr.Zero);
if (hParentHubDevice == Kernel32.INVALID_HANDLE_VALUE) return null; USB_NODE_CONNECTION_DRIVERKEY_NAME Buffer = new USB_NODE_CONNECTION_DRIVERKEY_NAME();
Buffer.ConnectionIndex = ConnectionIndex;
Int32 nBytesReturned;
Boolean Status = DeviceIoControl(hParentHubDevice,
IOCTL_USB_GET_NODE_CONNECTION_NAME,
ref Buffer,
Marshal.SizeOf(Buffer),
ref Buffer,
Marshal.SizeOf(Buffer),
out nBytesReturned,
IntPtr.Zero); // 关闭设备文件
Kernel32.CloseHandle(hParentHubDevice); if (Status)
return Buffer.DriverKeyName;
else
return null;
} /// <summary>
/// 获取外接Hub设备路径
/// </summary>
/// <param name="hParentHubDevice">上层Hub设备句柄</param>
/// <param name="ConnectionIndex">连接索引号</param>
/// <returns>外接Hub设备路径</returns>
public static String GetExternalHubPath(IntPtr hParentHubDevice, Int32 ConnectionIndex)
{
if (hParentHubDevice == IntPtr.Zero || ConnectionIndex <= ) return null; USB_NODE_CONNECTION_DRIVERKEY_NAME Buffer = new USB_NODE_CONNECTION_DRIVERKEY_NAME();
Buffer.ConnectionIndex = ConnectionIndex;
Int32 nBytesReturned;
Boolean Status = DeviceIoControl(hParentHubDevice,
IOCTL_USB_GET_NODE_CONNECTION_NAME,
ref Buffer,
Marshal.SizeOf(Buffer),
ref Buffer,
Marshal.SizeOf(Buffer),
out nBytesReturned,
IntPtr.Zero); if (Status)
return Buffer.DriverKeyName;
else
return null;
}
#endregion #region BCDVERSION
/// <summary>
/// 版本BCD编码转字符串
/// </summary>
/// <param name="bcd">版本BCD编码</param>
/// <returns>版本字符串</returns>
private static String BcdVersionToString(UInt16 bcd)
{
StringBuilder sb = new StringBuilder(); // 主版本号
Int32 BIT4 = (bcd >> ) & 0x0F;
if (BIT4 != ) sb.Append(BIT4.ToString()); BIT4 = (bcd >> ) & 0x0F;
sb.Append(BIT4.ToString()); sb.Append("."); // 子版本号
BIT4 = (bcd >> ) & 0x0F;
sb.Append(BIT4.ToString()); BIT4 = bcd & 0x0F;
if (BIT4 != ) sb.Append(BIT4.ToString()); return sb.ToString();
}
#endregion
}
}

(三)输出枚举信息到XML文档

/* ----------------------------------------------------------
文件名称:UsbEnumXML.cs 作者:秦建辉 MSN:splashcn@msn.com
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 = ;
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[].NodeType;
XElement HubNode = new XElement(HubNodeName,
new XAttribute("Name", NodeInfoCollection[].Name),
new XAttribute("PNPDeviceID", NodeInfoCollection[].PNPDeviceID),
new XAttribute("Path", NodeInfoCollection[].DevicePath),
new XAttribute("NodeType", NodeType)
); if (NodeType == USB_HUB_NODE.UsbHub)
{
Int32 NumberOfPorts = NodeInfoCollection[].NumberOfPorts;
HubNode.Add(new XAttribute("NumberOfPorts", NumberOfPorts),
new XAttribute("HubIsBusPowered", NodeInfoCollection[].HubIsBusPowered),
new XAttribute("HubCharacteristics", "0x" + NodeInfoCollection[].HubCharacteristics.ToString("X4")),
new XAttribute("PowerOnToPowerGood", NodeInfoCollection[].PowerOnToPowerGood),
new XAttribute("HubControlCurrent", NodeInfoCollection[].HubControlCurrent)
); // 深度遍历端口
UsbNodeConnectionInformation[] NodeConnectionInfoCollection = USB.GetUsbNodeConnectionInformation(HubPath, NumberOfPorts);
if (NodeConnectionInfoCollection != null)
{
foreach (UsbNodeConnectionInformation NodeConnectionInfo in NodeConnectionInfoCollection)
{ // 增加端口节点
AddPortNode(HubNode, NodeConnectionInfo);
}
}
}
else
{
HubNode.Add("NumberOfInterfaces", NodeInfoCollection[].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 != )
{
DeviceDescriptorNode.Add(new XAttribute("idVendor", "0x" + DeviceDescriptor.idVendor.ToString("X4")));
} if (DeviceDescriptor.idProduct != )
{
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 = ;
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);
}
}
}
}

(四)Kernel32的PInvoke

/* ----------------------------------------------------------
文件名称:Kernel32.cs 作者:秦建辉 MSN:splashcn@msn.com
QQ:36748897 博客:http://blog.csdn.net/jhqin 开发环境:
Visual Studio V2010
.NET Framework 4 Client Profile 版本历史:
V1.0 2011年09月05日
实现对Kernel32.dll接口的PInvoke 参考资料:
http://www.pinvoke.net/
------------------------------------------------------------ */
using System;
using System.Runtime.InteropServices;
using System.Security; namespace Splash
{
#region Kernel32
[SuppressUnmanagedCodeSecurity]
internal static class Kernel32
{
/// <summary>
/// 无效的文件句柄
/// </summary>
public static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-); #region CreateFile
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr CreateFile(
String fileName,
[MarshalAs(UnmanagedType.U4)] NativeFileAccess fileAccess,
[MarshalAs(UnmanagedType.U4)] NativeFileShare fileShare,
IntPtr securityAttributes,
[MarshalAs(UnmanagedType.U4)] NativeFileMode creationDisposition,
NativeFileFlag flags,
IntPtr template
); [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr CreateFile(
String fileName,
[MarshalAs(UnmanagedType.U4)] NativeFileAccess fileAccess,
[MarshalAs(UnmanagedType.U4)] NativeFileShare fileShare,
IntPtr securityAttributes,
[MarshalAs(UnmanagedType.U4)] NativeFileMode creationDisposition,
IntPtr flags,
IntPtr template
);
#endregion [DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern Boolean CloseHandle(IntPtr hFile); #region ReadFile
[DllImport("kernel32.dll", SetLastError = true)]
public static extern Boolean ReadFile(
IntPtr hFile,
[Out] Byte[] lpBuffer,
Int32 nNumberOfBytesToRead,
out Int32 lpNumberOfBytesRead,
[In] ref System.Threading.NativeOverlapped lpOverlapped
); [DllImport("kernel32.dll", SetLastError = true)]
public static extern Boolean ReadFile(
IntPtr hFile,
[Out] Byte[] lpBuffer,
Int32 nNumberOfBytesToRead,
IntPtr lpNumberOfBytesRead,
[In] ref System.Threading.NativeOverlapped lpOverlapped
); [DllImport("kernel32.dll", SetLastError = true)]
public static extern Boolean ReadFile(
IntPtr hFile,
[Out] Byte[] lpBuffer,
Int32 nNumberOfBytesToRead,
out Int32 lpNumberOfBytesRead,
IntPtr lpOverlapped
);
#endregion #region WriteFile
[DllImport("kernel32.dll")]
public static extern Boolean WriteFile(
IntPtr hFile,
Byte[] lpBuffer,
Int32 nNumberOfBytesToWrite,
out Int32 lpNumberOfBytesWritten,
[In] ref System.Threading.NativeOverlapped lpOverlapped
); [DllImport("kernel32.dll")]
public static extern Boolean WriteFile(
IntPtr hFile,
Byte[] lpBuffer,
Int32 nNumberOfBytesToWrite,
IntPtr lpNumberOfBytesWritten,
[In] ref System.Threading.NativeOverlapped lpOverlapped
); [DllImport("kernel32.dll")]
public static extern Boolean WriteFile(
IntPtr hFile,
Byte[] lpBuffer,
Int32 nNumberOfBytesToWrite,
IntPtr lpNumberOfBytesWritten,
IntPtr lpOverlapped
);
#endregion [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern Boolean GetOverlappedResult(
IntPtr hFile,
[In] ref System.Threading.NativeOverlapped lpOverlapped,
out Int32 lpNumberOfBytesTransferred,
Boolean bWait
);
}
#endregion #region ENUM
[Flags]
internal enum NativeFileAccess : uint
{
GENERIC_READ = (0x80000000),
GENERIC_WRITE = (0x40000000),
GENERIC_EXECUTE = (0x20000000),
GENERIC_ALL = (0x10000000), FILE_SPECIAL = ,
FILE_APPEND_DATA = (0x0004), // 文件
FILE_READ_DATA = (0x0001), // 文件和管道
FILE_WRITE_DATA = (0x0002), // 文件和管道
FILE_READ_EA = (0x0008), // 文件和目录
FILE_WRITE_EA = (0x0010), // 文件和目录
FILE_READ_ATTRIBUTES = (0x0080), // 所有
FILE_WRITE_ATTRIBUTES = (0x0100), // 所有
DELETE = 0x00010000,
READ_CONTROL = (0x00020000),
WRITE_DAC = (0x00040000),
WRITE_OWNER = (0x00080000),
SYNCHRONIZE = (0x00100000),
STANDARD_RIGHTS_REQUIRED = (0x000F0000),
STANDARD_RIGHTS_READ = (READ_CONTROL),
STANDARD_RIGHTS_WRITE = (READ_CONTROL),
STANDARD_RIGHTS_EXECUTE = (READ_CONTROL),
STANDARD_RIGHTS_ALL = (0x001F0000),
SPECIFIC_RIGHTS_ALL = (0x0000FFFF),
FILE_GENERIC_READ = (STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE),
FILE_GENERIC_WRITE = (STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE),
SPECIAL =
} internal enum NativeFileMode : uint
{
CREATE_NEW = ,
CREATE_ALWAYS = ,
OPEN_EXISTING = ,
OPEN_ALWAYS = ,
TRUNCATE_EXISTING = ,
} [Flags]
internal enum NativeFileShare : uint
{
NONE = ,
FILE_SHARE_READ = 0x00000001,
FILE_SHARE_WRITE = 0x00000002,
FILE_SHARE_DEELETE = 0x00000004,
} [Flags]
internal enum NativeFileFlag : uint
{
FILE_ATTRIBUTE_READONLY = 0x00000001,
FILE_ATTRIBUTE_HIDDEN = 0x00000002,
FILE_ATTRIBUTE_SYSTEM = 0x00000004,
FILE_ATTRIBUTE_DIRECTORY = 0x00000010,
FILE_ATTRIBUTE_ARCHIVE = 0x00000020,
FILE_ATTRIBUTE_DEVICE = 0x00000040,
FILE_ATTRIBUTE_NORMAL = 0x00000080,
FILE_ATTRIBUTE_TEMPORARY = 0x00000100,
FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200,
FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400,
FILE_ATTRIBUTE_COMPRESSED = 0x00000800,
FILE_ATTRIBUTE_OFFLINE = 0x00001000,
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000,
FILE_ATTRIBUTE_ENCRYPTED = 0x00004000,
FILE_FLAG_WRITE_THROUGH = 0x80000000,
FILE_FLAG_OVERLAPPED = 0x40000000,
FILE_FLAG_NO_BUFFERING = 0x20000000,
FILE_FLAG_RANDOM_ACCESS = 0x10000000,
FILE_FLAG_SEQUENTIAL_SCAN = 0x08000000,
FILE_FLAG_DELETE_ON_CLOSE = 0x04000000,
FILE_FLAG_BACKUP_SEMANTICS = 0x02000000,
FILE_FLAG_POSIX_SEMANTICS = 0x01000000,
FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000,
FILE_FLAG_OPEN_NO_RECALL = 0x00100000,
FILE_FLAG_FIRST_PIPE_INSTANCE = 0x00080000,
}
#endregion
}

USB设备枚举(五)生成TreeView数据源

有一处错误已于2014年5月8日修正。请大家下载SkyDrive上的资源。

/* ----------------------------------------------------------
* 文件名称:TreeViewUsbItem.cs
*
* 作者:秦建辉
*
* QQ:36748897
*
* 博客:http://www.firstsolver.com/wordpress/
*
* 开发环境:
* Visual Studio V2010
* .NET Framework 4 Client Profile
*
* 版本历史:
* V1.0 2014年05月08日
* 修正由网友指出的一处错误
*
* V1.0 2011年10月26日
* 为USB设备枚举信息生成TreeView数据源
------------------------------------------------------------ */
using System;
using System.Collections.Generic;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Splash.IO.PORTS; namespace WPFUsbView
{
/// <summary>
/// TreeView节点对象
/// </summary>
internal class TreeViewUsbItem
{
/// <summary>
/// 节点图标
/// </summary>
public ImageSource Icon { get; set; } /// <summary>
/// 节点名称
/// </summary>
public String Name { get; set; } /// <summary>
/// 节点数据
/// </summary>
public Object Data { get; set; } /// <summary>
/// 子节点列表
/// </summary>
public List<TreeViewUsbItem> Children { get; set; } /// <summary>
/// 计算机图标
/// </summary>
public static ImageSource ImageComputer
{
get
{
return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
Properties.Resources.notebook.Handle,
System.Windows.Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions()
);
}
} /// <summary>
/// 主控制器图标
/// </summary>
public static ImageSource ImageHostController
{
get
{
return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
Properties.Resources.usb.Handle,
System.Windows.Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions()
);
}
} /// <summary>
/// Hub图标
/// </summary>
public static ImageSource ImageHub
{
get
{
return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
Properties.Resources.hub.Handle,
System.Windows.Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions()
);
}
} /// <summary>
/// USB设备图标
/// </summary>
public static ImageSource ImageDevice
{
get
{
return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
Properties.Resources.port.Handle,
System.Windows.Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions()
);
}
} /// <summary>
/// 连接的外部Hub数目
/// </summary>
public static Int32 ConnectedHubs = ; /// <summary>
/// 连接的USB设备数目
/// </summary>
public static Int32 ConnectedDevices = ; /// <summary>
/// 静态根节点
/// </summary>
public static List<TreeViewUsbItem> AllUsbDevices
{
get
{
// 初始化
ConnectedHubs = ; // 连接的外部Hub数目
ConnectedDevices = ; // 连接的USB设备数目 // 创建根节点
TreeViewUsbItem Root = new TreeViewUsbItem();
Root.Icon = ImageComputer;
Root.Name = "Computer";
Root.Data = "Machine Name:" + System.Environment.MachineName; // 子节点列表
// 深度遍历主控制器
HostControllerInfo[] HostControllersCollection = USB.AllHostControllers;
if (HostControllersCollection != null)
{
List<TreeViewUsbItem> HCNodeCollection = new List<TreeViewUsbItem>(HostControllersCollection.Length);
foreach (HostControllerInfo item in HostControllersCollection)
{ // 创建主控制器节点
TreeViewUsbItem HCNode = new TreeViewUsbItem(); HCNode.Icon = ImageHostController;
HCNode.Name = item.Name;
HCNode.Data = item; // 创建根集线器节点
String RootHubPath = USB.GetUsbRootHubPath(item.PNPDeviceID);
HCNode.Children = AddHubNode(RootHubPath, "RootHub"); HCNodeCollection.Add(HCNode);
} Root.Children = HCNodeCollection;
} return new List<TreeViewUsbItem>() { Root };
}
} /// <summary>
/// Hub节点
/// </summary>
/// <param name="HubPath">Hub路径</param>
/// <param name="HubNodeName">节点显示名称</param>
/// <returns>Hub节点集合</returns>
private static List<TreeViewUsbItem> AddHubNode(String HubPath, String HubNodeName)
{
UsbNodeInformation[] NodeInfoCollection = USB.GetUsbNodeInformation(HubPath);
if (NodeInfoCollection != null)
{
TreeViewUsbItem HubNode = new TreeViewUsbItem();
HubNode.Icon = ImageHub;
if (String.IsNullOrEmpty(NodeInfoCollection[].Name))
{
HubNode.Name = HubNodeName;
}
else
{
HubNode.Name = NodeInfoCollection[].Name;
}
HubNode.Data = NodeInfoCollection[]; if (NodeInfoCollection[].NodeType == USB_HUB_NODE.UsbHub)
{
HubNode.Children = AddPortNode(HubPath, NodeInfoCollection[].NumberOfPorts);
}
else
{
HubNode.Children = null;
} return new List<TreeViewUsbItem>() { HubNode };
} return null;
} /// <summary>
/// Port节点
/// </summary>
/// <param name="HubPath">Hub路径</param>
/// <param name="NumberOfPorts">端口数</param>
/// <returns>Port节点集合</returns>
private static List<TreeViewUsbItem> AddPortNode(String HubPath, Int32 NumberOfPorts)
{
// 深度遍历端口
UsbNodeConnectionInformation[] NodeConnectionInfoCollection = USB.GetUsbNodeConnectionInformation(HubPath, NumberOfPorts);
if (NodeConnectionInfoCollection != null)
{
List<TreeViewUsbItem> PortNodeCollection = new List<TreeViewUsbItem>(NumberOfPorts);
foreach (UsbNodeConnectionInformation NodeConnectionInfo in NodeConnectionInfoCollection)
{ // 增加端口节点
TreeViewUsbItem PortNode = new TreeViewUsbItem(); PortNode.Icon = ImageDevice;
PortNode.Name = "[Port" + NodeConnectionInfo.ConnectionIndex + "]" + NodeConnectionInfo.ConnectionStatus;
PortNode.Data = NodeConnectionInfo;
PortNode.Children = null;
if (NodeConnectionInfo.ConnectionStatus == USB_CONNECTION_STATUS.DeviceConnected)
{
// 设备连接
ConnectedDevices++; // 连接的USB设备数目
if (!String.IsNullOrEmpty(NodeConnectionInfo.DeviceDescriptor.Product))
{ // 产品名称
PortNode.Name = String.Concat(PortNode.Name, ": ", NodeConnectionInfo.DeviceDescriptor.Product);
} if (NodeConnectionInfo.DeviceIsHub)
{
// 获取外部Hub设备路径
String ExternalHubPath = USB.GetExternalHubPath(NodeConnectionInfo.DevicePath, NodeConnectionInfo.ConnectionIndex);
UsbNodeInformation[] NodeInfoCollection = USB.GetUsbNodeInformation(ExternalHubPath);
if (NodeInfoCollection != null)
{
PortNode.Icon = ImageHub;
PortNode.Data = new ExternalHubInfo { NodeInfo = NodeInfoCollection[], NodeConnectionInfo = NodeConnectionInfo };
if (NodeInfoCollection[].NodeType == USB_HUB_NODE.UsbHub)
{
PortNode.Children = AddPortNode(ExternalHubPath, NodeInfoCollection[].NumberOfPorts);
} if (String.IsNullOrEmpty(NodeConnectionInfo.DeviceDescriptor.Product))
{
if (!String.IsNullOrEmpty(NodeInfoCollection[].Name))
{ // 产品名称
PortNode.Name = String.Concat(PortNode.Name, ": ", NodeInfoCollection[].Name);
}
}
} ConnectedHubs++; // 连接的外部Hub数目
}
} PortNodeCollection.Add(PortNode);
} return PortNodeCollection;
} return null;
}
}
}

USB设备枚举(六)生成ListView数据源

/* ----------------------------------------------------------
文件名称:ListViewUsbItem.cs 作者:秦建辉 MSN:splashcn@msn.com
QQ:36748897 博客:http://blog.csdn.net/jhqin 开发环境:
Visual Studio V2010
.NET Framework 4 Client Profile 版本历史:
V1.0 2011年11月08日
为USB设备枚举信息生成ListView数据源
------------------------------------------------------------ */
using System;
using System.Collections.Generic;
using Splash.IO.PORTS; namespace WPFUsbView
{
/// <summary>
/// TreeView节点对象
/// </summary>
internal class ListViewUsbItem
{
/// <summary>
/// USB属性名
/// </summary>
public String Name { get; set; } /// <summary>
/// USB属性值
/// </summary>
public String Value { get; set; } /// <summary>
/// 构造函数
/// </summary>
/// <param name="Name">USB属性名</param>
/// <param name="Value">USB属性值</param>
public ListViewUsbItem(String Name, String Value)
{
this.Name = Name;
this.Value = Value;
} /// <summary>
/// 生成USB属性列表
/// </summary>
/// <param name="Data">用于生成列表的USB数据</param>
/// <returns>属性列表</returns>
public static List<ListViewUsbItem> UsbDetail(Object Data)
{
if (Data is String)
{ // 机器名
String Info = Data as String;
if (!String.IsNullOrEmpty(Info))
{
String[] Content = Info.Split(new Char[] { ':' });
if (Content.Length == )
{
return new List<ListViewUsbItem>() { new ListViewUsbItem(Content[], Content[]) };
}
}
}
else if (Data is HostControllerInfo)
{ // 主控制器信息
HostControllerInfo Info = (HostControllerInfo)Data;
return new List<ListViewUsbItem>()
{
new ListViewUsbItem("Name", Info.Name),
new ListViewUsbItem("PNPDeviceID", Info.PNPDeviceID),
new ListViewUsbItem("HcdDriverKeyName", Info.HcdDriverKeyName)
};
}
else if (Data is UsbNodeInformation)
{ // USB节点信息
UsbNodeInformation Info = (UsbNodeInformation)Data; List<ListViewUsbItem> Items = new List<ListViewUsbItem>();
Add(ref Items, Info);
return Items;
}
else if (Data is UsbNodeConnectionInformation)
{ // USB节点连接信息
UsbNodeConnectionInformation Info = (UsbNodeConnectionInformation)Data;
if(Info.ConnectionStatus != USB_CONNECTION_STATUS.DeviceConnected)
return null; List<ListViewUsbItem> Items = new List<ListViewUsbItem>();
Add(ref Items, Info);
return Items;
}
else if (Data is ExternalHubInfo)
{ // 外部Hub信息
ExternalHubInfo Info = (ExternalHubInfo)Data; List<ListViewUsbItem> Items = new List<ListViewUsbItem>(); // 加入USB节点信息
Items.Add(new ListViewUsbItem("Node Information:", null));
Add(ref Items, Info.NodeInfo); // 加入USB节点连接信息
Items.Add(new ListViewUsbItem(null, null));
Items.Add(new ListViewUsbItem("Node Connection Information:", null));
Add(ref Items, Info.NodeConnectionInfo); return Items;
} return null;
} /// <summary>
/// 增加USB节点信息
/// </summary>
/// <param name="Items">要增加的列表</param>
/// <param name="Info">要增加的信息</param>
private static void Add(ref List<ListViewUsbItem> Items, UsbNodeInformation Info)
{
if (Info.NodeType == USB_HUB_NODE.UsbHub)
{
Items.Add(new ListViewUsbItem("Name", Info.Name));
Items.Add(new ListViewUsbItem("PNPDeviceID", Info.PNPDeviceID));
Items.Add(new ListViewUsbItem("DevicePath", Info.DevicePath));
Items.Add(new ListViewUsbItem("NodeType", Info.NodeType.ToString()));
Items.Add(new ListViewUsbItem("HubIsBusPowered", Info.HubIsBusPowered.ToString()));
Items.Add(new ListViewUsbItem("NumberOfPorts", Info.NumberOfPorts.ToString()));
Items.Add(new ListViewUsbItem("HubCharacteristics", "0x" + Info.HubCharacteristics.ToString("X4")));
Items.Add(new ListViewUsbItem("PowerOnToPowerGood", (Info.PowerOnToPowerGood * ).ToString() + "ms"));
Items.Add(new ListViewUsbItem("HubControlCurrent", Info.HubControlCurrent.ToString()));
}
else
{
Items.Add(new ListViewUsbItem("Name", Info.Name));
Items.Add(new ListViewUsbItem("PNPDeviceID", Info.PNPDeviceID));
Items.Add(new ListViewUsbItem("DevicePath", Info.DevicePath));
Items.Add(new ListViewUsbItem("NodeType", Info.NodeType.ToString()));
Items.Add(new ListViewUsbItem("NumberOfInterfaces", Info.NumberOfInterfaces.ToString()));
}
} /// <summary>
/// 增加USB节点连接信息
/// </summary>
/// <param name="Items">要增加的列表</param>
/// <param name="Info">要增加的信息</param>
private static void Add(ref List<ListViewUsbItem> Items, UsbNodeConnectionInformation Info)
{
Items.Add(new ListViewUsbItem("DevicePath", Info.DevicePath));
Items.Add(new ListViewUsbItem("ConnectionIndex", Info.ConnectionIndex.ToString()));
Items.Add(new ListViewUsbItem("CurrentConfigurationValue", "0x" + Info.CurrentConfigurationValue.ToString("X2")));
Items.Add(new ListViewUsbItem("Speed", ((USB_DEVICE_SPEED)Info.Speed).ToString()));
Items.Add(new ListViewUsbItem("DeviceIsHub", Info.DeviceIsHub.ToString()));
Items.Add(new ListViewUsbItem("DeviceAddress", Info.DeviceAddress.ToString()));
Items.Add(new ListViewUsbItem("NumberOfOpenPipes", Info.NumberOfOpenPipes.ToString())); // 设备描述符
Items.Add(new ListViewUsbItem(null, null));
Items.Add(new ListViewUsbItem("Device Descriptor:", null));
Items.Add(new ListViewUsbItem("DescriptorType", "0x" + Info.DeviceDescriptor.bDescriptorType.ToString("X2")));
Items.Add(new ListViewUsbItem("UsbVersion", Info.DeviceDescriptor.UsbVersion));
Items.Add(new ListViewUsbItem("DeviceClass", "0x" + Info.DeviceDescriptor.bDeviceClass.ToString("X2")));
Items.Add(new ListViewUsbItem("DeviceSubClass", "0x" + Info.DeviceDescriptor.bDeviceSubClass.ToString("X2")));
Items.Add(new ListViewUsbItem("DeviceProtocol", "0x" + Info.DeviceDescriptor.bDeviceProtocol.ToString("X2")));
Items.Add(new ListViewUsbItem("MaxPacketSize0", Info.DeviceDescriptor.bMaxPacketSize0.ToString()));
Items.Add(new ListViewUsbItem("idVendor", "0x" + Info.DeviceDescriptor.idVendor.ToString("X4")));
Items.Add(new ListViewUsbItem("idProduct", "0x" + Info.DeviceDescriptor.idProduct.ToString("X4")));
Items.Add(new ListViewUsbItem("DeviceVersion", Info.DeviceDescriptor.DeviceVersion));
Items.Add(new ListViewUsbItem("Manufacturer", Info.DeviceDescriptor.Manufacturer));
Items.Add(new ListViewUsbItem("Product", Info.DeviceDescriptor.Product));
Items.Add(new ListViewUsbItem("SerialNumber", Info.DeviceDescriptor.SerialNumber));
Items.Add(new ListViewUsbItem("NumConfigurations", Info.DeviceDescriptor.bNumConfigurations.ToString())); // 管道信息
foreach (UsbPipeInfo Pipe in Info.PipeList)
{
Items.Add(new ListViewUsbItem(null, null));
Items.Add(new ListViewUsbItem("Endpoint Descriptor:", null));
Items.Add(new ListViewUsbItem("ScheduleOffset", Pipe.ScheduleOffset.ToString()));
Items.Add(new ListViewUsbItem("DescriptorType", "0x" + Pipe.bDescriptorType.ToString("X2")));
Items.Add(new ListViewUsbItem("EndpointAddress", "0x" + Pipe.bEndpointAddress.ToString("X2")));
Items.Add(new ListViewUsbItem("bmAttributes", "0x" + Pipe.bmAttributes.ToString("X2")));
Items.Add(new ListViewUsbItem("MaxPacketSize", Pipe.wMaxPacketSize.ToString()));
Items.Add(new ListViewUsbItem("Interval", "0x" + Pipe.bInterval.ToString("X2")));
}
}
}
}

USB设备枚举(七)WPF扩展方法

/* ----------------------------------------------------------
文件名称:WPFExtensions.cs 作者:秦建辉 MSN:splashcn@msn.com
QQ:36748897 博客:http://blog.csdn.net/jhqin 开发环境:
Visual Studio V2010
.NET Framework 4 Client Profile 版本历史:
V1.1 2011年11月07日
实现扩展方法:WPF中TreeView类的ExpandAll功能 V1.0 2011年11月03日
实现扩展方法:WPF中Button类的PerformClick功能
------------------------------------------------------------ */
using System.Windows.Controls;
using System.Windows.Automation.Peers;
using System.Windows.Automation.Provider; namespace Splash.WPF
{
/// <summary>
/// 扩展方法
/// </summary>
public static partial class Extensions
{
/// <summary>
/// 扩展方法:实现WPF中Button类的PerformClick功能
/// </summary>
/// <param name="button">Button实例</param>
/// <remarks>
/// 需要添加对UIAutomationProvider.dll的引用
/// 参考网址:http://www.cnblogs.com/zhouyinhui/archive/2010/05/20/1740111.html
/// </remarks>
public static void PerformClick(this Button button)
{
ButtonAutomationPeer BAP = new ButtonAutomationPeer(button);
IInvokeProvider IIP = BAP.GetPattern(PatternInterface.Invoke) as IInvokeProvider;
if (IIP != null)
{
IIP.Invoke();
}
} /// <summary>
/// 扩展方法:实现WPF中TreeView类的ExpandAll功能
/// </summary>
/// <param name="treeView">要展开的TreeView实例</param>
/// <remarks>
/// 参考网址:http://www.cnblogs.com/sayo/archive/2008/07/23/1249804.html
/// </remarks>
public static void ExpandAll(this TreeView treeView)
{
ExpandSubItems(treeView as ItemsControl);
} private static void ExpandSubItems(ItemsControl control)
{
if (control == null) return;
foreach (object item in control.Items)
{
TreeViewItem treeItem = control.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
if (treeItem != null && treeItem.HasItems)
{
treeItem.IsExpanded = true;
ExpandSubItems(treeItem as ItemsControl);
}
}
}
}
}

(八)创建基于WPF的USB设备浏览器

软件界面:

下载地址(包含产品及源代码):

微软SkyDrive下载链接:WPFUsbView.zip

CSDN下载页面:http://download.csdn.net/detail/jhqin/3773593

源代码:

MainWindow.xaml

<Window x:Class="WPFUsbView.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:usb="clr-namespace:WPFUsbView"
Title="USB Device Viewer" Height="" Width="" Icon="/WPFUsbView;component/images/usb.ico" WindowStyle="ThreeDBorderWindow" WindowStartupLocation="CenterScreen" Loaded="Window_Loaded" WindowState="Maximized">
<Window.Resources>
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TreeViewItem}}}" />
</Style>
</Window.Resources> <Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions> <Grid Grid.Row="" Background="CadetBlue">
<ToolBar Height="" Width="Auto" HorizontalAlignment="Left" Background="CadetBlue">
<Button Margin="4,0" Name="buttonRefresh" Click="buttonRefresh_Click">
<Image Source="/WPFUsbView;component/images/refresh.png"></Image>
</Button>
<Button Margin="4,0" Name="buttonOpenXML" Click="buttonOpenXML_Click">
<Image Source="/WPFUsbView;component/images/XML.png"></Image>
</Button>
<Button Margin="4,0" Name="buttonInfo" Click="buttonInfo_Click">
<Image Source="/WPFUsbView;component/images/Info.png"></Image>
</Button>
</ToolBar>
</Grid> <Grid Grid.Row="" Name="gridDetail">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="6*"></ColumnDefinition>
</Grid.ColumnDefinitions> <TreeView Grid.Column="" HorizontalAlignment="Left" VerticalAlignment="Top" Name="treeView1" FontSize="" SelectedItemChanged="treeView1_SelectedItemChanged">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type usb:TreeViewUsbItem}" ItemsSource="{Binding Path=Children}">
<StackPanel Orientation="Horizontal">
<Image VerticalAlignment="Center" Source="{Binding Icon}" Width="" Height="" Margin="0,0,2,2"></Image>
<TextBlock VerticalAlignment="Center" Text="{Binding Name}"></TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView> <GridSplitter Grid.Column="" Width="" HorizontalAlignment="Center" VerticalAlignment="Stretch" LayoutUpdated="GridSplitter_LayoutUpdated">
<GridSplitter.Background>
<ImageBrush ImageSource="/WPFUsbView;component/images/SplitLine.png" Stretch="UniformToFill" TileMode="Tile" Viewport="0,0,15,500" ViewportUnits="Absolute" />
</GridSplitter.Background>
</GridSplitter> <ListView Grid.Column="" Name="listView1" FontSize="">
<ListView.ItemTemplate>
<DataTemplate DataType="{x:Type usb:ListViewUsbItem}">
<StackPanel Orientation="Horizontal" Margin="0,2">
<TextBlock Width="" Text="{Binding Name}"></TextBlock>
<TextBlock Width="Auto" Text="{Binding Value}" Foreground="Blue"></TextBlock>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid> <StatusBar Grid.Row="" Height="" Background="SteelBlue">
<StatusBarItem>
<Image Source="/WPFUsbView;component/images/usbdevice.png"></Image>
</StatusBarItem>
<StatusBarItem>
<TextBlock FontSize="" Foreground="Brown" Name="textBlockUsbDevice"></TextBlock>
</StatusBarItem>
<StatusBarItem>
<Image Source="/WPFUsbView;component/images/usb-hub.png"></Image>
</StatusBarItem>
<StatusBarItem>
<TextBlock FontSize="" Foreground="Brown" Name="textBlockUsbHub"></TextBlock>
</StatusBarItem>
</StatusBar>
</Grid>
</Window>

MainWindow.xaml.cs

using System;
using System.IO;
using System.Windows;
using Splash.IO.PORTS;
using Splash.WPF; namespace WPFUsbView
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
} // 枚举设备信息并输出到XML文档
private void buttonOpenXML_Click(object sender, RoutedEventArgs e)
{
String xmlFile = "UsbEnums.xml";
try
{ // 检测当前目录下是否可以创建文件
using (StreamWriter sw = new StreamWriter(xmlFile))
{
sw.Close();
}
}
catch(Exception)
{ // 当前目录无法创建文件,改到我的文档目录下
xmlFile = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\" + xmlFile;
} if (USB.EnumUsbToXML(xmlFile))
{ // 判断文件是否存在
if (System.IO.File.Exists(xmlFile))
{ // 打开文件
Splash.Diagnostics.Extensions.ShellExecute(xmlFile);
return;
}
} MessageBox.Show("Failed!");
return;
} // 更新设备枚举信息
private void buttonRefresh_Click(object sender, RoutedEventArgs e)
{
// 枚举USB设备信息
treeView1.ItemsSource = TreeViewUsbItem.AllUsbDevices; // 展开所有分支
treeView1.ExpandAll(); // 设备连接数
textBlockUsbDevice.Text = TreeViewUsbItem.ConnectedDevices.ToString(); // 外部Hub连接数
textBlockUsbHub.Text = TreeViewUsbItem.ConnectedHubs.ToString();
} // 显示软件版本信息
private void buttonInfo_Click(object sender, RoutedEventArgs e)
{
About AboutWindow = new About();
AboutWindow.Owner = this;
AboutWindow.ShowDialog();
} private void Window_Loaded(object sender, RoutedEventArgs e)
{
// 显示USB设备枚举信息
buttonRefresh.PerformClick();
} // 更新布局,调整各控件大小
private void GridSplitter_LayoutUpdated(object sender, EventArgs e)
{
// 设置TreeView的宽度和高度
treeView1.Width = gridDetail.ColumnDefinitions[].ActualWidth;
treeView1.Height = gridDetail.ActualHeight;
} private void treeView1_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
TreeViewUsbItem Node = e.NewValue as TreeViewUsbItem;
if (Node != null)
{
listView1.ItemsSource = ListViewUsbItem.UsbDetail(Node.Data);
}
}
}
}

C#:USB设备枚举 --转自CSDN作者:Splash的更多相关文章

  1. usb设备枚举过程

    USB主机在检测到USB设备插入后,就要对设备进行枚举了.为什么要枚举呢?枚举就是从设备读取一些信息,知道设备是什么样的设备,如何进行通信,这样主机就可以根据这些信息来加载合适的驱动程序.调试USB设 ...

  2. C#USB设备枚举Kernel32的PInvoke

    using System; using System.Runtime.InteropServices; using System.Security; namespace Splash { #regio ...

  3. USB设备驱动之设备初始化(设备枚举)

    USB设备从接入HUB到正常工作之前.都属于设备枚举阶段.所谓设备枚举.就是让host控制器认识USB设备,并为其准备资源.建立好主机与设备间的数据传递机制. 该阶段的工作,是USB通信协议规定的,所 ...

  4. Linux下usb设备驱动详解

    USB驱动分为两块,一块是USB的bus驱动,这个东西,Linux内核已经做好了,我们可以不管,我们只需要了解它的功能.形象的说,USB的bus驱动相当于铺出一条路来,让所有的信息都可以通过这条USB ...

  5. USB 设备驱动(写给自己看的)

    集线器与控制器(USB地址7bit) 设备,配置,端点,接口 USB1.0(低速1.2),1.1(全速450m),2.0(高速,电流传输)区别 引脚4根(V,D-,D+,gnd),miniUSB增加 ...

  6. Windows下USB磁盘开发系列二:枚举系统中所有USB设备

    上篇 <Windows下USB磁盘开发系列一:枚举系统中U盘的盘符>介绍了很简单的获取系统U盘盘符的办法,现在介绍下如何枚举系统中所有USB设备(不光是U盘). 主要调用的API如下: 1 ...

  7. USB协议-USB设备的枚举过程

    USB主机在检测到USB设备插入后,就要对设备进行枚举了.为什么要枚举?枚举就是从设备读取各种描述符信息,这样主机就可以根据这些信息来加载合适的驱动程序,从而知道设备是什么样的设备,如何进行通信等. ...

  8. MFC枚举USB设备碰到的一个疑难,还没解决

    代码如下: 打开USB Hub设备之后,返回句柄hHubDevice,然后使用EnumerateHubPorts来枚举Hub的端 口.疑问在代码的中文注释中. bool CUsbEnumHub::En ...

  9. 浅析USB之设备枚举

    当一个USB设备插入主机后,会有以下活动: 配上状态图

随机推荐

  1. Android驱动开发前的准备(一)

    Android系统移植与驱动开发概述 1.1 Android 系统架构 1.2 Android系统移植的主要工作 1.3 查看linux内核版本 1.4 linux内核版本号的定义规则 1.5 lin ...

  2. springMvc3.0.5搭建全程 (转)

    用了大半年的Spring MVC3.0,用着感觉不错.简单写一个搭建Spring MVC3.0的流程(以Spring3.0.5为列),数据库交互使用spring JDBC Template,附件有项目 ...

  3. outscan 一键批量 get struct2 devMode (CNVD-2016-04656)

    之前写的一个玩意 下载地址:http://pan.baidu.com/s/1i5jmEwP 密码:v8v3 一键批量 get struct2 devMode 支持百度.google(google有访问 ...

  4. HDU 5966 Guessing the Dice Roll

    题意有 N≤10 个人,每个猜一个长度为L≤10的由1−6构成的序列,保证序列两两不同.不断地掷骰子,直到后缀与某人的序列匹配,则对应的人获胜.求每个人获胜的概率. 思路:建立trie图,跑高斯消元. ...

  5. NewQuant的设计(一)——整体的领域设计

    NewQuant的设计思路——整体的领域分析 “领域驱动设计(DDD)”是著名软件工程建模专家Eric Evans提出的一个重要概念,是“面向对象分析设计(OOAD)”的深化.当业务逻辑变得复杂,系统 ...

  6. relocation 错误

    icc test/train/test_lm2.o -shared -lpthread -ldl ./lib/liblm2.a -o liblm2.so ld: ./lib/liblm2.a(cJSO ...

  7. Xcode 各个版本下载地址

    从Xcode8开始不支持uiautomation了,需要下载老版本的xcode Xcode 的各种版本的下载地址  https://developer.apple.com/download/more/

  8. Oracle RAC asm常用命令

    在Oracle RAC环境下,使用grid帐号执行 运行asmcmd进入asm命令模式,如: [grid@oradb-node1 ~]$ asmcmd ASMCMD> ASMCMD> du ...

  9. Linux下使用ping快速检测存活主机

    该shell脚本主要是通过ping来批量检测网段内存活主机,执行结果保存在脚本当前目录下的IPinfor目录中,写的比较匆忙,希望大家留下更好的建议. #!/usr/bin/env bash##### ...

  10. [PHP] - Laravel - 用户登陆中间件

    前言 Laravel 4中,可以使用Route::filter,而在Laravel 5中,没有了filter.php文件,官方建议使用中间件做. 下面是用户登陆的测试例子,涉及到的一些方法和使用,先参 ...