private void GetUsbNodeInformation(IntPtr hubHandle) { var usbNodeInformation = new UsbIoControl.UsbNodeInformation { NodeType = UsbIoControl.UsbHubNode.UsbHub }; int nBytes = usbNodeInformation.SizeOf; IntPtr ptrNodeInfo = IntPtr.Zero; try { ptrNodeInfo = Marshal.AllocHGlobal(nBytes); usbNodeInformation.MarshalTo(ptrNodeInfo, true); if (KernelApi.DeviceIoControl(hubHandle, UsbIoControl.IoctlUsbGetNodeInformation, ptrNodeInfo, nBytes, ptrNodeInfo, nBytes, out _, IntPtr.Zero)) { usbNodeInformation.MarshalFrom(ptrNodeInfo); NodeInformation = usbNodeInformation; } else { CoreTraceSource.Source.TraceEvent(TraceEventType.Error, CoreTraceSource.UsbHubSourceId, $"[{nameof(KernelApi.DeviceIoControl)}] [{nameof(UsbIoControl.IoctlUsbGetNodeInformation)}] Result: [{KernelApi.GetLastError():X}]"); } } finally { if (ptrNodeInfo != IntPtr.Zero) { Marshal.FreeHGlobal(ptrNodeInfo); } } }
private void GetHubCapabilities(IntPtr hubHandle) { UsbApi.UsbHubCapabilitiesEx usbHubCapabilitiesEx = new UsbApi.UsbHubCapabilitiesEx(); int nBytes = Marshal.SizeOf(usbHubCapabilitiesEx); IntPtr ptrUsbHubCapabilitiesEx = IntPtr.Zero; try { ptrUsbHubCapabilitiesEx = Marshal.AllocHGlobal(nBytes); Marshal.StructureToPtr(usbHubCapabilitiesEx, ptrUsbHubCapabilitiesEx, true); if (KernelApi.DeviceIoControl(hubHandle, UsbIoControl.IoctlUsbGetHubCapabilitiesEx, ptrUsbHubCapabilitiesEx, nBytes, ptrUsbHubCapabilitiesEx, nBytes, out _, IntPtr.Zero)) { UsbHubCapabilitiesEx = (UsbApi.UsbHubCapabilitiesEx)Marshal.PtrToStructure(ptrUsbHubCapabilitiesEx, typeof(UsbApi.UsbHubCapabilitiesEx)); } else { CoreTraceSource.Source.TraceEvent(TraceEventType.Error, CoreTraceSource.UsbHubSourceId, $"[{nameof(KernelApi.DeviceIoControl)}] [{nameof(UsbIoControl.IoctlUsbGetHubCapabilitiesEx)}] Result: [{KernelApi.GetLastError():X}]"); } } finally { if (ptrUsbHubCapabilitiesEx != IntPtr.Zero) { Marshal.FreeHGlobal(ptrUsbHubCapabilitiesEx); } } }
private void GetUsbHubInformation(IntPtr hubHandle) { UsbIoControl.UsbHubInformationEx hubInfoEx = new UsbIoControl.UsbHubInformationEx(); int nBytes = hubInfoEx.SizeOf; IntPtr ptrHubInfo = IntPtr.Zero; try { ptrHubInfo = Marshal.AllocHGlobal(nBytes); if (KernelApi.DeviceIoControl(hubHandle, UsbIoControl.IoctlUsbGetHubInformationEx, ptrHubInfo, nBytes, ptrHubInfo, nBytes, out _, IntPtr.Zero)) { hubInfoEx.MarshalFrom(ptrHubInfo); HubInformation = hubInfoEx; } else { CoreTraceSource.Source.TraceEvent(TraceEventType.Error, CoreTraceSource.UsbHubSourceId, $"[{nameof(KernelApi.DeviceIoControl)}] [{nameof(UsbIoControl.IoctlUsbGetNodeInformation)}] Result: [{KernelApi.GetLastError():X}]"); } } finally { if (ptrHubInfo != IntPtr.Zero) { Marshal.FreeHGlobal(ptrHubInfo); } } }
private void GetHostControllerPowerMap(IntPtr handle) { UsbUser.WdmusbPowerState powerState = UsbUser.WdmusbPowerState.WdmUsbPowerSystemWorking; for (; powerState <= UsbUser.WdmusbPowerState.WdmUsbPowerSystemShutdown; powerState++) { UsbUser.UsbuserPowerInfoRequest powerInfoRequest = new UsbUser.UsbuserPowerInfoRequest { Header = { UsbUserRequest = UsbUser.UsbuserGetPowerStateMap, }, PowerInformation = { SystemState = powerState } }; powerInfoRequest.Header.RequestBufferLength = (uint)Marshal.SizeOf(powerInfoRequest); IntPtr ptrPowerInfoRequest = IntPtr.Zero; try { // // Now query USBHUB for the USB_POWER_INFO structure for this hub. // For Selective Suspend support // int nBytes = Marshal.SizeOf(powerInfoRequest); ptrPowerInfoRequest = Marshal.AllocHGlobal(nBytes); Marshal.StructureToPtr(powerInfoRequest, ptrPowerInfoRequest, true); var success = KernelApi.DeviceIoControl(handle, UsbUser.IoctlUsbUserRequest, ptrPowerInfoRequest, nBytes, ptrPowerInfoRequest, nBytes, out _, IntPtr.Zero); if (!success) { CoreTraceSource.Source.TraceEvent(TraceEventType.Error, CoreTraceSource.UsbControllerSourceId, $"[{nameof(KernelApi.DeviceIoControl)}] Returned Error Code: [{KernelApi.GetLastError():X}]"); } else { powerInfoRequest = (UsbUser.UsbuserPowerInfoRequest)Marshal.PtrToStructure(ptrPowerInfoRequest, typeof(UsbUser.UsbuserPowerInfoRequest)); PowerInfo.Add(powerInfoRequest.PowerInformation); } } finally { if (ptrPowerInfoRequest != IntPtr.Zero) { Marshal.FreeHGlobal(ptrPowerInfoRequest); } } } }
private void GetHostControllerInfo(IntPtr handle) { IntPtr ptrUsbControllerInfo0 = IntPtr.Zero; try { // set the header and request sizes UsbUser.UsbuserControllerInfo0 usbControllerInfo0 = new UsbUser.UsbuserControllerInfo0 { Header = { UsbUserRequest = UsbUser.UsbuserGetControllerInfo0 } }; usbControllerInfo0.Header.RequestBufferLength = (uint)Marshal.SizeOf(usbControllerInfo0); // // Query for the USB_CONTROLLER_INFO_0 structure // int bytesRequested = Marshal.SizeOf(usbControllerInfo0); ptrUsbControllerInfo0 = Marshal.AllocHGlobal(bytesRequested); Marshal.StructureToPtr(usbControllerInfo0, ptrUsbControllerInfo0, true); if (KernelApi.DeviceIoControl(handle, UsbUser.IoctlUsbUserRequest, ptrUsbControllerInfo0, bytesRequested, ptrUsbControllerInfo0, bytesRequested, out _, IntPtr.Zero)) { CoreTraceSource.Source.TraceEvent(TraceEventType.Error, CoreTraceSource.UsbControllerSourceId, $"[{nameof(KernelApi.DeviceIoControl)}] [{nameof(UsbUser.IoctlUsbUserRequest)}] Result: [{KernelApi.GetLastError():X}]"); } else { usbControllerInfo0 = (UsbUser.UsbuserControllerInfo0)Marshal.PtrToStructure(ptrUsbControllerInfo0, typeof(UsbUser.UsbuserControllerInfo0)); ControllerInfo = usbControllerInfo0.Info0; } } finally { if (ptrUsbControllerInfo0 != IntPtr.Zero) { Marshal.FreeHGlobal(ptrUsbControllerInfo0); } } }
private static bool GetUsbNodeConnectionName(uint portCount, IntPtr deviceHandle, out UsbIoControl.UsbNodeConnectionName nodeConnectionName) { IntPtr structPtr = IntPtr.Zero; try { int bytesRequested = Marshal.SizeOf(typeof(UsbIoControl.UsbNodeConnectionName)); structPtr = Marshal.AllocHGlobal(bytesRequested); nodeConnectionName = new UsbIoControl.UsbNodeConnectionName() { ConnectionIndex = portCount }; Marshal.StructureToPtr(nodeConnectionName, structPtr, true); if (KernelApi.DeviceIoControl(deviceHandle, UsbIoControl.IoctlUsbGetNodeConnectionName, structPtr, bytesRequested, structPtr, bytesRequested, out _, IntPtr.Zero)) { nodeConnectionName = (UsbIoControl.UsbNodeConnectionName)Marshal.PtrToStructure(structPtr, typeof(UsbIoControl.UsbNodeConnectionName)); } else { CoreTraceSource.Source.TraceEvent(TraceEventType.Error, CoreTraceSource.DeviceFactorySourceId, $"[{nameof(KernelApi.DeviceIoControl)}] [{nameof(UsbIoControl.IoctlUsbGetNodeConnectionName)}] Result: [{KernelApi.GetLastError():X}]"); return(false); } } finally { if (structPtr != IntPtr.Zero) { Marshal.FreeHGlobal(structPtr); } } return(true); }
private static void GetNodeConnectionInformationExV2(uint portCount, IntPtr deviceHandle, out UsbIoControl.UsbNodeConnectionInformationExV2 usbNodeConnectionInformationExV2) { IntPtr structPtr = IntPtr.Zero; try { int bytesRequested = Marshal.SizeOf(typeof(UsbIoControl.UsbNodeConnectionInformationExV2)); structPtr = Marshal.AllocHGlobal(bytesRequested); usbNodeConnectionInformationExV2 = new UsbIoControl.UsbNodeConnectionInformationExV2 { ConnectionIndex = portCount, SupportedUsbProtocols = UsbIoControl.UsbProtocols.Usb300, Length = (uint)bytesRequested }; Marshal.StructureToPtr(usbNodeConnectionInformationExV2, structPtr, true); if (KernelApi.DeviceIoControl(deviceHandle, UsbIoControl.IoctlUsbGetNodeConnectionInformationExV2, structPtr, bytesRequested, structPtr, bytesRequested, out _, IntPtr.Zero)) { usbNodeConnectionInformationExV2 = (UsbIoControl.UsbNodeConnectionInformationExV2)Marshal.PtrToStructure(structPtr, typeof(UsbIoControl.UsbNodeConnectionInformationExV2)); } else { CoreTraceSource.Source.TraceEvent(TraceEventType.Error, CoreTraceSource.DeviceFactorySourceId, $"[{nameof(KernelApi.DeviceIoControl)}] [{nameof(UsbIoControl.IoctlUsbGetNodeConnectionInformationExV2)}] Result: [{KernelApi.GetLastError():X}]"); } } finally { if (structPtr != IntPtr.Zero) { Marshal.FreeHGlobal(structPtr); } } }
private static void GetUsbPortConnectorProperties(uint portCount, IntPtr deviceHandle, out UsbIoControl.UsbPortConnectorProperties usbPortConnectorProperties) { IntPtr structPtr = IntPtr.Zero; try { int bytesRequested = Marshal.SizeOf(typeof(UsbIoControl.UsbPortConnectorProperties)); structPtr = Marshal.AllocHGlobal(bytesRequested); usbPortConnectorProperties = new UsbIoControl.UsbPortConnectorProperties() { ConnectionIndex = portCount }; Marshal.StructureToPtr(usbPortConnectorProperties, structPtr, true); if (KernelApi.DeviceIoControl(deviceHandle, UsbIoControl.IoctlUsbGetPortConnectorProperties, structPtr, bytesRequested, structPtr, bytesRequested, out _, IntPtr.Zero)) { usbPortConnectorProperties = (UsbIoControl.UsbPortConnectorProperties)Marshal.PtrToStructure(structPtr, typeof(UsbIoControl.UsbPortConnectorProperties)); } else { CoreTraceSource.Source.TraceEvent(TraceEventType.Error, CoreTraceSource.DeviceFactorySourceId, $"[{nameof(KernelApi.DeviceIoControl)}] [{nameof(UsbIoControl.IoctlUsbGetPortConnectorProperties)}] Result: [{KernelApi.GetLastError():X}]"); } } finally { if (structPtr != IntPtr.Zero) { Marshal.FreeHGlobal(structPtr); } } }
/// <summary> /// Function to close the data store for writing. /// </summary> /// <param name="closingMessage">[Optional] The message to write when closing.</param> public void Close(string closingMessage = null) { if (Interlocked.Exchange(ref _hasConsole, 0) == 0) { return; } if (!string.IsNullOrWhiteSpace(closingMessage)) { Console.ForegroundColor = ConsoleColor.White; Console.WriteLine(closingMessage); } Console.ResetColor(); if (!_ownsConsole) { return; } Debug.Assert(KernelApi.FreeConsole() != 0); _ownsConsole = false; }
private void GetRootHubName(IntPtr hostControllerHandle) { UsbApi.UsbRootHubName rootHubName = new UsbApi.UsbRootHubName(); int nBytes = Marshal.SizeOf(rootHubName); IntPtr ptrRootHubName = IntPtr.Zero; try { ptrRootHubName = Marshal.AllocHGlobal(nBytes); // Get the root hub name. if (KernelApi.DeviceIoControl(hostControllerHandle, UsbIoControl.IoctlUsbGetRootHubName, ptrRootHubName, nBytes, ptrRootHubName, nBytes, out _, IntPtr.Zero)) { rootHubName = (UsbApi.UsbRootHubName)Marshal.PtrToStructure(ptrRootHubName, typeof(UsbApi.UsbRootHubName)); if (rootHubName.ActualLength > 0) { IsRootHub = true; DeviceDescription = "RootHub"; DevicePath = @"\\?\" + rootHubName.RootHubName; } } else { CoreTraceSource.Source.TraceEvent(TraceEventType.Error, CoreTraceSource.UsbHubSourceId, $"[{nameof(KernelApi.DeviceIoControl)}] [{nameof(UsbIoControl.IoctlUsbGetRootHubName)}] Result: [{KernelApi.GetLastError():X}]"); } } finally { if (ptrRootHubName != IntPtr.Zero) { Marshal.FreeHGlobal(ptrRootHubName); } } }
/// <summary> /// Function to open the data store for writing. /// </summary> /// <param name="initialMessage">[Optional] The initial message to write.</param> public void Open(string initialMessage = null) { if (Interlocked.Exchange(ref _hasConsole, 1) == 1) { return; } // Check for an existing console first. using (Stream stdIn = Console.OpenStandardInput()) { // If it does not exist, then create one. if (stdIn == Stream.Null) { if (!KernelApi.AllocConsole()) { return; } _ownsConsole = true; } } // If we have Enable Native Debugging turned on, all output is redirected to the debug window. // This will reset that back to our logging window. if (Console.IsOutputRedirected) { const uint genericRead = 0x80000000; const uint genericWrite = 0x40000000; IntPtr filePtr = KernelApi.CreateFileW("CONOUT$", (genericRead | genericWrite), (uint)FileShare.ReadWrite, IntPtr.Zero, (uint)FileMode.Open, 0, IntPtr.Zero); var handle = new SafeFileHandle(filePtr, true); if (handle.IsInvalid) { handle.Dispose(); return; } KernelApi.SetStdHandle(KernelApi.StdOutputHandle, filePtr); var stream = new FileStream(handle, FileAccess.Write); var writer = new StreamWriter(stream, Encoding.Default) { AutoFlush = true }; Console.SetOut(writer); if (KernelApi.GetConsoleMode(filePtr, out uint consoleMode)) { KernelApi.SetConsoleMode(filePtr, consoleMode | 0x200); } } if (string.IsNullOrWhiteSpace(initialMessage)) { return; } Console.ForegroundColor = ConsoleColor.White; Console.WriteLine(initialMessage); Console.ResetColor(); }
/// <summary> /// Initializes a new instance of the <see cref="UsbHub"/> class. /// </summary> /// <param name="deviceDescriptor">The device descriptor.</param> /// <param name="devicePath">The device path.</param> public UsbHub(UsbSpec.UsbDeviceDescriptor deviceDescriptor, string devicePath) : base(deviceDescriptor, 0, devicePath) { DeviceDescription = "Standard-USB-Hub"; DevicePath = devicePath; IntPtr hostControllerHandle = IntPtr.Zero; try { hostControllerHandle = KernelApi.CreateFile(devicePath, UsbApi.GenericWrite, UsbApi.FileShareWrite, IntPtr.Zero, UsbApi.OpenExisting, 0, IntPtr.Zero); if (hostControllerHandle.ToInt64() != UsbApi.InvalidHandleValue) { GetRootHubName(hostControllerHandle); // TODO: Get the driver key name for the root hub. IntPtr hubHandle = IntPtr.Zero; try { // Now let's open the hub (based upon the hub name we got above). hubHandle = KernelApi.CreateFile(DevicePath, UsbApi.GenericWrite, UsbApi.FileShareWrite, IntPtr.Zero, UsbApi.OpenExisting, 0, IntPtr.Zero); if (hubHandle.ToInt64() != UsbApi.InvalidHandleValue) { GetUsbNodeInformation(hubHandle); GetUsbHubInformation(hubHandle); GetHubCapabilities(hubHandle); } } finally { if (hubHandle != IntPtr.Zero) { KernelApi.CloseHandle(hubHandle); } } } else { throw new UsbHubException("No port found!"); } } finally { if (hostControllerHandle != IntPtr.Zero) { KernelApi.CloseHandle(hostControllerHandle); } } for (uint index = 1; index <= PortCount; index++) { // Initialize a new port and save the port. try { Devices.Add(DeviceFactory.BuildDevice(this, index, DevicePath)); } catch (Exception e) { CoreTraceSource.Source.TraceEvent(TraceEventType.Error, CoreTraceSource.UsbHubSourceId, "Unhandled exception occurred: {0}", e); } } }
/// <summary> /// Builds the device. /// </summary> /// <param name="parent">The parent.</param> /// <param name="portCount">The port count.</param> /// <param name="devicePath">The device path.</param> /// <returns>The device.</returns> public static Device BuildDevice(Device parent, uint portCount, string devicePath) { Device device = null; // Open a handle to the Hub device IntPtr deviceHandle = KernelApi.CreateFile(devicePath, UsbApi.GenericWrite, UsbApi.FileShareWrite, IntPtr.Zero, UsbApi.OpenExisting, 0, IntPtr.Zero); try { if (deviceHandle.ToInt64() != UsbApi.InvalidHandleValue) { if (GetNodeConnectionInformationEx(portCount, deviceHandle, out var nodeConnection)) { if (nodeConnection.ConnectionStatus == UsbIoControl.UsbConnectionStatus.DeviceConnected) { GetUsbPortConnectorProperties(portCount, deviceHandle, out var portConnectorProperties); GetNodeConnectionInformationExV2(portCount, deviceHandle, out var nodeConnectionV2); if (nodeConnection.DeviceDescriptor.bDeviceClass == UsbDesc.DeviceClassType.UsbHubDevice) { if (GetUsbNodeConnectionName(portCount, deviceHandle, out var connectionName)) { string name = @"\\?\" + connectionName.NodeName; device = new UsbHub(nodeConnection.DeviceDescriptor, name) { NodeConnectionInfo = nodeConnection, NodeConnectionInfoV2 = nodeConnectionV2, UsbPortConnectorProperties = portConnectorProperties }; } } else { device = new UsbDevice(nodeConnection.DeviceDescriptor, portCount, devicePath) { NodeConnectionInfo = nodeConnection, NodeConnectionInfoV2 = nodeConnectionV2, UsbPortConnectorProperties = portConnectorProperties }; } } else { device = new UsbDevice(null, portCount) { NodeConnectionInfo = nodeConnection }; } } } } finally { if (deviceHandle.ToInt64() != UsbApi.InvalidHandleValue) { KernelApi.CloseHandle(deviceHandle); } } return(device); }
private void Initalise(uint index) { IntPtr ptr = IntPtr.Zero; IntPtr deviceInfoHandle = IntPtr.Zero; try { ptr = Marshal.AllocHGlobal(UsbApi.MaxBufferSize); deviceInfoHandle = UsbApi.SetupDiGetClassDevs(ref _guid, 0, IntPtr.Zero, UsbApi.DigcfPresent | UsbApi.DigcfDeviceinterface); // Create a device interface data structure UsbApi.SpDeviceInterfaceData deviceInterfaceData = new UsbApi.SpDeviceInterfaceData(); deviceInterfaceData.CbSize = Marshal.SizeOf(deviceInterfaceData); // Start the enumeration. Boolean success = UsbApi.SetupDiEnumDeviceInterfaces(deviceInfoHandle, IntPtr.Zero, ref _guid, (int)index, ref deviceInterfaceData); if (success) { // Build a DevInfo data structure. UsbApi.SpDevinfoData deviceInfoData = new UsbApi.SpDevinfoData(); deviceInfoData.CbSize = Marshal.SizeOf(deviceInfoData); // Build a device interface detail data structure. UsbApi.SpDeviceInterfaceDetailData deviceInterfaceDetailData = new UsbApi.SpDeviceInterfaceDetailData { CbSize = UIntPtr.Size == 8 ? 8 : (int)(4 + (uint)Marshal.SystemDefaultCharSize) }; // Now we can get some more detailed informations. int nRequiredSize = 0; int nBytes = UsbApi.MaxBufferSize; if (UsbApi.SetupDiGetDeviceInterfaceDetail(deviceInfoHandle, ref deviceInterfaceData, ref deviceInterfaceDetailData, nBytes, ref nRequiredSize, ref deviceInfoData)) { DevicePath = deviceInterfaceDetailData.DevicePath; ParseDevicePath(DevicePath); // Get the device description and driver key name. int requiredSize = 0; int regType = UsbApi.RegSz; if (UsbApi.SetupDiGetDeviceRegistryProperty(deviceInfoHandle, ref deviceInfoData, (int)UsbApi.Spdrp.SpdrpDevicedesc, ref regType, ptr, UsbApi.MaxBufferSize, ref requiredSize)) { DeviceDescription = Marshal.PtrToStringAuto(ptr); } if (UsbApi.SetupDiGetDeviceRegistryProperty( deviceInfoHandle, ref deviceInfoData, (int)UsbApi.Spdrp.SpdrpDriver, ref regType, ptr, UsbApi.MaxBufferSize, ref requiredSize)) { DriverKey = Marshal.PtrToStringAuto(ptr); } } IntPtr hostControllerHandle = IntPtr.Zero; try { hostControllerHandle = KernelApi.CreateFile(deviceInterfaceDetailData.DevicePath, UsbApi.GenericWrite, UsbApi.FileShareWrite, IntPtr.Zero, UsbApi.OpenExisting, 0, IntPtr.Zero); if (deviceInfoHandle.ToInt64() != UsbApi.InvalidHandleValue) { GetHostControllerPowerMap(hostControllerHandle); GetHostControllerInfo(hostControllerHandle); } } finally { if (hostControllerHandle != IntPtr.Zero || deviceInfoHandle.ToInt64() != UsbApi.InvalidHandleValue) { KernelApi.CloseHandle(hostControllerHandle); } } try { Devices.Add(new UsbHub(null, DevicePath)); } catch (Exception ex) { CoreTraceSource.Source.TraceEvent(TraceEventType.Error, CoreTraceSource.UsbControllerSourceId, "Unhandled exception occurred: {0}", ex); throw new UsbControllerException("Unhandled exception occurred", ex); } } else { throw new UsbControllerException("No usb controller found!"); } } finally { if (ptr != IntPtr.Zero) { Marshal.FreeHGlobal(ptr); } if (deviceInfoHandle != IntPtr.Zero) { UsbApi.SetupDiDestroyDeviceInfoList(deviceInfoHandle); } } }