📄 usb.cs
字号:
public USBHub GetRootHub()
{
IntPtr h, h2;
USBHub Root = new USBHub();
Root.HubIsRootHub = true;
Root.HubDeviceDesc = "Root Hub";
// Open a handle to the Host Controller
h = CreateFile(ControllerDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
if (h.ToInt32() != INVALID_HANDLE_VALUE)
{
int nBytesReturned;
USB_ROOT_HUB_NAME HubName = new USB_ROOT_HUB_NAME();
int nBytes = Marshal.SizeOf(HubName);
IntPtr ptrHubName = Marshal.AllocHGlobal(nBytes);
// get the Hub Name
if (DeviceIoControl(h, IOCTL_USB_GET_ROOT_HUB_NAME, ptrHubName, nBytes, ptrHubName, nBytes, out nBytesReturned, IntPtr.Zero))
{
HubName = (USB_ROOT_HUB_NAME)Marshal.PtrToStructure(ptrHubName, typeof(USB_ROOT_HUB_NAME));
Root.HubDevicePath = @"\\.\" + HubName.RootHubName;
}
// TODO: Get DriverKeyName for Root Hub
// Now let's open the Hub (based upon the HubName we got above)
h2 = CreateFile(Root.HubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
if (h2.ToInt32() != INVALID_HANDLE_VALUE)
{
USB_NODE_INFORMATION NodeInfo = new USB_NODE_INFORMATION();
NodeInfo.NodeType = (int)USB_HUB_NODE.UsbHub;
nBytes = Marshal.SizeOf(NodeInfo);
IntPtr ptrNodeInfo = Marshal.AllocHGlobal(nBytes);
Marshal.StructureToPtr(NodeInfo, ptrNodeInfo, true);
// get the Hub Information
if (DeviceIoControl(h2, IOCTL_USB_GET_NODE_INFORMATION, ptrNodeInfo, nBytes, ptrNodeInfo, nBytes, out nBytesReturned, IntPtr.Zero))
{
NodeInfo = (USB_NODE_INFORMATION)Marshal.PtrToStructure(ptrNodeInfo, typeof(USB_NODE_INFORMATION));
Root.HubIsBusPowered = Convert.ToBoolean(NodeInfo.HubInformation.HubIsBusPowered);
Root.HubPortCount = NodeInfo.HubInformation.HubDescriptor.bNumberOfPorts;
}
Marshal.FreeHGlobal(ptrNodeInfo);
CloseHandle(h2);
}
Marshal.FreeHGlobal(ptrHubName);
CloseHandle(h);
}
return Root;
}
}
//
// The Hub class
//
public class USBHub
{
internal int HubPortCount;
internal string HubDriverKey, HubDevicePath, HubDeviceDesc;
internal string HubManufacturer, HubProduct, HubSerialNumber, HubInstanceID;
internal bool HubIsBusPowered, HubIsRootHub;
// a simple default constructor
public USBHub()
{
HubPortCount = 0;
HubDevicePath = "";
HubDeviceDesc = "";
HubDriverKey = "";
HubIsBusPowered = false;
HubIsRootHub = false;
HubManufacturer = "";
HubProduct = "";
HubSerialNumber = "";
HubInstanceID = "";
}
// return Port Count
public int PortCount
{
get { return HubPortCount; }
}
// return the Device Path, such as "\\?\pci#ven_10de&dev_005a&subsys_815a1043&rev_a2#3&267a616a&0&58#{3abf6f2d-71c4-462a-8a92-1e6861e6af27}"
public string DevicePath
{
get { return HubDevicePath; }
}
// The DriverKey may be useful as a search key
public string DriverKey
{
get { return HubDriverKey; }
}
// return the Friendly Name, such as "VIA USB Enhanced Host Controller"
public string Name
{
get { return HubDeviceDesc; }
}
// the device path of this device
public string InstanceID
{
get { return HubInstanceID; }
}
// is is this a self-powered hub?
public bool IsBusPowered
{
get { return HubIsBusPowered; }
}
// is this a root hub?
public bool IsRootHub
{
get { return HubIsRootHub; }
}
public string Manufacturer
{
get { return HubManufacturer; }
}
public string Product
{
get { return HubProduct; }
}
public string SerialNumber
{
get { return HubSerialNumber; }
}
// return a list of the down stream ports
public System.Collections.ObjectModel.ReadOnlyCollection<USBPort> GetPorts()
{
List<USBPort> PortList = new List<USBPort>();
// Open a handle to the Hub device
IntPtr h = CreateFile(HubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
if (h.ToInt32() != INVALID_HANDLE_VALUE)
{
int nBytes = Marshal.SizeOf(typeof(USB_NODE_CONNECTION_INFORMATION_EX));
IntPtr ptrNodeConnection = Marshal.AllocHGlobal(nBytes);
// loop thru all of the ports on the hub
// BTW: Ports are numbered starting at 1
for (int i = 1; i <= HubPortCount; i++)
{
int nBytesReturned;
USB_NODE_CONNECTION_INFORMATION_EX NodeConnection = new USB_NODE_CONNECTION_INFORMATION_EX();
NodeConnection.ConnectionIndex = i;
Marshal.StructureToPtr(NodeConnection, ptrNodeConnection, true);
if (DeviceIoControl(h, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, ptrNodeConnection, nBytes, ptrNodeConnection, nBytes, out nBytesReturned, IntPtr.Zero))
{
NodeConnection = (USB_NODE_CONNECTION_INFORMATION_EX)Marshal.PtrToStructure(ptrNodeConnection, typeof(USB_NODE_CONNECTION_INFORMATION_EX));
// load up the USBPort class
USBPort port = new USBPort();
port.PortPortNumber = i;
port.PortHubDevicePath = HubDevicePath;
USB_CONNECTION_STATUS Status = (USB_CONNECTION_STATUS)NodeConnection.ConnectionStatus;
port.PortStatus = Status.ToString();
USB_DEVICE_SPEED Speed = (USB_DEVICE_SPEED)NodeConnection.Speed;
port.PortSpeed = Speed.ToString();
port.PortIsDeviceConnected = (NodeConnection.ConnectionStatus == (int)USB_CONNECTION_STATUS.DeviceConnected);
port.PortIsHub = Convert.ToBoolean(NodeConnection.DeviceIsHub);
port.PortDeviceDescriptor = NodeConnection.DeviceDescriptor;
// add it to the list
PortList.Add(port);
}
}
Marshal.FreeHGlobal(ptrNodeConnection);
CloseHandle(h);
}
// convert it into a Collection
return new System.Collections.ObjectModel.ReadOnlyCollection<USBPort>(PortList);
}
}
//
// The Port Class
//
public class USBPort
{
internal int PortPortNumber;
internal string PortStatus, PortHubDevicePath, PortSpeed;
internal bool PortIsHub, PortIsDeviceConnected;
internal USB_DEVICE_DESCRIPTOR PortDeviceDescriptor;
// a simple default constructor
public USBPort()
{
PortPortNumber = 0;
PortStatus = "";
PortHubDevicePath = "";
PortSpeed = "";
PortIsHub = false;
PortIsDeviceConnected = false;
}
// return Port Index of the Hub
public int PortNumber
{
get { return PortPortNumber; }
}
// return the Device Path of the Hub
public string HubDevicePath
{
get { return PortHubDevicePath; }
}
// the status (see USB_CONNECTION_STATUS above)
public string Status
{
get { return PortStatus; }
}
// the speed of the connection (see USB_DEVICE_SPEED above)
public string Speed
{
get { return PortSpeed; }
}
// is this a downstream external hub?
public bool IsHub
{
get { return PortIsHub; }
}
// is anybody home?
public bool IsDeviceConnected
{
get { return PortIsDeviceConnected; }
}
// return a down stream external hub
public USBDevice GetDevice()
{
if (!PortIsDeviceConnected)
{
return null;
}
USBDevice Device = new USBDevice();
// Copy over some values from the Port class
// Ya know, I've given some thought about making Device a derived class...
Device.DevicePortNumber = PortPortNumber;
Device.DeviceHubDevicePath = PortHubDevicePath;
Device.DeviceDescriptor = PortDeviceDescriptor;
// Open a handle to the Hub device
IntPtr h = CreateFile(PortHubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
if (h.ToInt32() != INVALID_HANDLE_VALUE)
{
int nBytesReturned;
int nBytes = BUFFER_SIZE;
// We use this to zero fill a buffer
string NullString = new string((char)0, BUFFER_SIZE / Marshal.SystemDefaultCharSize);
// The iManufacturer, iProduct and iSerialNumber entries in the
// Device Descriptor are really just indexes. So, we have to
// request a String Descriptor to get the values for those strings.
if (PortDeviceDescriptor.iManufacturer > 0) {
// build a request for string descriptor
USB_DESCRIPTOR_REQUEST Request = new USB_DESCRIPTOR_REQUEST();
Request.ConnectionIndex = PortPortNumber;
Request.SetupPacket.wValue = (short)((USB_STRING_DESCRIPTOR_TYPE << 8) + PortDeviceDescriptor.iManufacturer);
Request.SetupPacket.wLength = (short)(nBytes - Marshal.SizeOf(Request));
Request.SetupPacket.wIndex = 0x409; // Language Code
// Geez, I wish C# had a Marshal.MemSet() method
IntPtr ptrRequest = Marshal.StringToHGlobalAuto(NullString);
Marshal.StructureToPtr(Request, ptrRequest, true);
// Use an IOCTL call to request the String Descriptor
if (DeviceIoControl(h, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, ptrRequest, nBytes, ptrRequest, nBytes, out nBytesReturned, IntPtr.Zero))
{
// The location of the string descriptor is immediately after
// the Request structure. Because this location is not "covered"
// by the structure allocation, we're forced to zero out this
// chunk of memory by using the StringToHGlobalAuto() hack above
IntPtr ptrStringDesc = new IntPtr(ptrRequest.ToInt32() + Marshal.SizeOf(Request));
USB_STRING_DESCRIPTOR StringDesc = (USB_STRING_DESCRIPTOR)Marshal.PtrToStructure(ptrStringDesc, typeof(USB_STRING_DESCRIPTOR));
Device.DeviceManufacturer = StringDesc.bString;
}
Marshal.FreeHGlobal(ptrRequest);
}
if (PortDeviceDescriptor.iProduct > 0)
{
// build a request for string descriptor
USB_DESCRIPTOR_REQUEST Request = new USB_DESCRIPTOR_REQUEST();
Request.ConnectionIndex = PortPortNumber;
Request.SetupPacket.wValue = (short)((USB_STRING_DESCRIPTOR_TYPE << 8) + PortDeviceDescriptor.iProduct);
Request.SetupPacket.wLength = (short)(nBytes - Marshal.SizeOf(Request));
Request.SetupPacket.wIndex = 0x409; // Language Code
// Geez, I wish C# had a Marshal.MemSet() method
IntPtr ptrRequest = Marshal.StringToHGlobalAuto(NullString);
Marshal.StructureToPtr(Request, ptrRequest, true);
// Use an IOCTL call to request the String Descriptor
if (DeviceIoControl(h, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, ptrRequest, nBytes, ptrRequest, nBytes, out nBytesReturned, IntPtr.Zero))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -