/// <summary>return a down stream external hub</summary> /// <returns>Downstream external hub</returns> internal UsbHub GetHub() { if (!PortIsHub) { return(null); } var hub = new UsbHub(); IntPtr h, h2; hub.HubIsRootHub = false; hub.HubDeviceDesc = "External Hub"; // Open a handle to the Host Controller h = CreateFile(PortHubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero); if (h == INVALID_HANDLE_VALUE) { return(hub); } // Get the DevicePath for downstream hub var nodeName = new UsbNodeConnectionName { ConnectionIndex = PortPortNumber }; int nBytes = Marshal.SizeOf(nodeName); IntPtr ptrNodeName = Marshal.AllocHGlobal(nBytes); Marshal.StructureToPtr(nodeName, ptrNodeName, true); // Use an IOCTL call to request the Node Name if (DeviceIoControl(h, IOCTL_USB_GET_NODE_CONNECTION_NAME, ptrNodeName, nBytes, ptrNodeName, nBytes, out _, IntPtr.Zero)) { nodeName = (UsbNodeConnectionName)Marshal.PtrToStructure(ptrNodeName, typeof(UsbNodeConnectionName)); hub.HubDevicePath = @"\\.\" + nodeName.NodeName; } // Now let's open the Hub (based upon the HubName we got above) h2 = CreateFile(hub.HubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero); if (h2 != INVALID_HANDLE_VALUE) { var nodeInfo = new UsbNodeInformation { NodeType = (int)UsbHubNode.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 _, IntPtr.Zero)) { nodeInfo = (UsbNodeInformation)Marshal.PtrToStructure(ptrNodeInfo, typeof(UsbNodeInformation)); hub.HubIsBusPowered = Convert.ToBoolean(nodeInfo.HubInformation.HubIsBusPowered); hub.HubPortCount = nodeInfo.HubInformation.HubDescriptor.bNumberOfPorts; } Marshal.FreeHGlobal(ptrNodeInfo); CloseHandle(h2); } // Fill in the missing Manufacture, Product, and SerialNumber values // values by just creating a Device instance and copying the values UsbDevice device = GetDevice(); hub.HubInstanceId = device.DeviceInstanceId; hub.HubManufacturer = device.Manufacturer; hub.HubProduct = device.Product; hub.HubSerialNumber = device.SerialNumber; hub.HubDriverKey = device.DriverKey; Marshal.FreeHGlobal(ptrNodeName); CloseHandle(h); return(hub); }
/// <summary>Return Root Hub for this Controller</summary> internal UsbHub GetRootHub() { IntPtr h, h2; var root = new UsbHub { HubIsRootHub = true, 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 == INVALID_HANDLE_VALUE) { return(root); } var hubName = new UsbRootHubName(); 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 _, IntPtr.Zero)) { hubName = (UsbRootHubName)Marshal.PtrToStructure(ptrHubName, typeof(UsbRootHubName)); 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 != INVALID_HANDLE_VALUE) { var nodeInfo = new UsbNodeInformation { NodeType = (int)UsbHubNode.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 _, IntPtr.Zero)) { nodeInfo = (UsbNodeInformation)Marshal.PtrToStructure(ptrNodeInfo, typeof(UsbNodeInformation)); 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); }