public PortDefinition[] GetPersistablePortDefinitions() { PortDefinition[] ports = null; switch (m_portFilter) { case PortFilter.Emulator: Debug.Assert(false); break; case PortFilter.Serial: ports = AsyncSerialStream.EnumeratePorts(); break; case PortFilter.Usb: { if (MonoDevelop.Core.Platform.IsWindows) { PortDefinition[] portUSB; PortDefinition[] portWinUSB; portUSB = AsyncUsbStream.EnumeratePorts(); portWinUSB = WinUsb_AsyncUsbStream.EnumeratePorts(); int lenUSB = portUSB != null ? portUSB.Length : 0; int lenWinUSB = portWinUSB != null ? portWinUSB.Length : 0; ports = new PortDefinition[lenUSB + lenWinUSB]; if (lenUSB > 0) { Array.Copy(portUSB, ports, lenUSB); } if (lenWinUSB > 0) { Array.Copy(portWinUSB, 0, ports, lenUSB, lenWinUSB); } } else { ports = LibUsb_AsyncUsbStream.EnumeratePorts(); } } break; case PortFilter.TcpIp: ports = PortDefinition_Tcp.EnumeratePorts(false); break; default: Debug.Assert(false); throw new ApplicationException(); } return(ports); }
static public ArrayList Enumerate(params PortFilter[] args) { ArrayList lst = new ArrayList(); foreach (PortFilter pf in args) { PortDefinition[] res; switch (pf) { case PortFilter.Emulator: res = Emulator.EnumeratePipes(); break; case PortFilter.Serial: res = AsyncSerialStream.EnumeratePorts(); break; case PortFilter.LegacyPermiscuousWinUsb: case PortFilter.Usb: { res = WinUsb_AsyncUsbStream.EnumeratePorts(pf == PortFilter.LegacyPermiscuousWinUsb); lst.AddRange(res); res = AsyncUsbStream.EnumeratePorts(); // res will be added to list below... } break; case PortFilter.TcpIp: res = PortDefinition_Tcp.EnumeratePorts(); break; default: res = null; break; } if (res != null) { lst.AddRange(res); } } return(lst); }
private static void RetrieveProperties(string hash, ref PortDefinition pd, AsyncUsbStream s) { IDictionaryEnumerator dict; dict = s_textProperties.GetEnumerator(); while (dict.MoveNext()) { pd.Properties.Add(dict.Key, s.RetrieveStringFromDevice((int)dict.Value)); } dict = s_digitProperties.GetEnumerator(); while (dict.MoveNext()) { pd.Properties.Add(dict.Key, s.RetrieveIntegerFromDevice((int)dict.Value)); } }
public override Stream CreateStream() { try { return(new AsyncUsbStream(m_port)); } catch { object uniqueId = UniqueId; foreach (PortDefinition pd in AsyncUsbStream.EnumeratePorts()) { if (Object.Equals(pd.UniqueId, uniqueId)) { m_properties = pd.Properties; m_port = pd.Port; return(new AsyncUsbStream(m_port)); } } throw; } }
// The following procedure works with the USB device driver; upon finding all instances of USB devices // that match the requested Guid, the procedure checks the corresponding registry keys to find the unique // serial number to show to the user; the serial number is decided by the device driver at installation // time and stored in a registry key whose name is the hash of the laser etched security key of the device private static void EnumeratePorts( Guid inquiriesInterface, string driverVersion, SortedList lst ) { IntPtr devInfo = Native.SetupDiGetClassDevs( ref inquiriesInterface, null, 0, Native.DIGCF_DEVICEINTERFACE | Native.DIGCF_PRESENT ); if(devInfo == Native.INVALID_HANDLE_VALUE) { return; } Native.SP_DEVICE_INTERFACE_DATA interfaceData = new Native.SP_DEVICE_INTERFACE_DATA(); interfaceData.cbSize = Marshal.SizeOf(interfaceData); int index = 0; while(Native.SetupDiEnumDeviceInterfaces( devInfo, 0, ref inquiriesInterface, index++, ref interfaceData )) { Native.SP_DEVICE_INTERFACE_DETAIL_DATA detail = new Native.SP_DEVICE_INTERFACE_DETAIL_DATA(); // explicit size of unmanaged structure must be provided, because it does not include transfer buffer // for whatever reason on 64 bit machines the detail size is 8 rather than 5, likewise the interfaceData.cbSize // is 32 rather than 28 for non 64bit machines, therefore, we make the detemination of the size based // on the interfaceData.cbSize (kind of hacky but it works). if( interfaceData.cbSize == 32 ) { detail.cbSize = 8; } else { detail.cbSize = 5; } if(Native.SetupDiGetDeviceInterfaceDetail( devInfo, ref interfaceData, ref detail, Marshal.SizeOf(detail) * 2, 0, 0 )) { string port = detail.DevicePath.ToLower(); AsyncUsbStream s = null; try { s = new AsyncUsbStream( port ); string displayName = s.RetrieveStringFromDevice( IOCTL_SPOTUSB_DISPLAY_NAME ); string hash = s.RetrieveStringFromDevice( IOCTL_SPOTUSB_DEVICE_HASH ); string operationalPort = s.RetrieveStringFromDevice( IOCTL_SPOTUSB_PORT_NAME ); if((operationalPort == null) || (displayName == null) || (hash == null)) { continue; } // convert kernel format to user mode format // kernel : @"\??\USB#Vid_beef&Pid_0009#5&4162af8&0&1#{09343630-a794-10ef-334f-82ea332c49f3}" // user : @"\\?\usb#vid_beef&pid_0009#5&4162af8&0&1#{09343630-a794-10ef-334f-82ea332c49f3}" StringBuilder operationalPortUser = new StringBuilder(); operationalPortUser.Append( @"\\?" ); operationalPortUser.Append( operationalPort.Substring( 3 ) ); // change the display name if there is a collision (otherwise you will only be able to use one of the devices) displayName += "_" + hash; if (lst.ContainsKey(displayName)) { int i = 2; while (lst.ContainsKey(displayName + " (" + i + ")")) { i++; } displayName += " (" + i + ")"; } PortDefinition pd = PortDefinition.CreateInstanceForUsb( displayName, operationalPortUser.ToString() ); RetrieveProperties( hash, ref pd, s ); lst.Add( pd.DisplayName, pd ); } catch { } finally { if(s != null) s.Close(); } } } Native.SetupDiDestroyDeviceInfoList( devInfo ); }
private static void RetrieveProperties( string hash, ref PortDefinition pd, AsyncUsbStream s ) { IDictionaryEnumerator dict; dict = s_textProperties.GetEnumerator(); while(dict.MoveNext()) { pd.Properties.Add( dict.Key, s.RetrieveStringFromDevice( (int)dict.Value ) ); } dict = s_digitProperties.GetEnumerator(); while(dict.MoveNext()) { pd.Properties.Add( dict.Key, s.RetrieveIntegerFromDevice( (int)dict.Value ) ); } }
// The following procedure works with the USB device driver; upon finding all instances of USB devices // that match the requested Guid, the procedure checks the corresponding registry keys to find the unique // serial number to show to the user; the serial number is decided by the device driver at installation // time and stored in a registry key whose name is the hash of the laser etched security key of the device private static void EnumeratePorts(Guid inquiriesInterface, string driverVersion, SortedList lst) { IntPtr devInfo = Native.SetupDiGetClassDevs(ref inquiriesInterface, null, 0, Native.DIGCF_DEVICEINTERFACE | Native.DIGCF_PRESENT); if (devInfo == Native.INVALID_HANDLE_VALUE) { return; } Native.SP_DEVICE_INTERFACE_DATA interfaceData = new Native.SP_DEVICE_INTERFACE_DATA(); interfaceData.cbSize = Marshal.SizeOf(interfaceData); int index = 0; while (Native.SetupDiEnumDeviceInterfaces(devInfo, 0, ref inquiriesInterface, index++, ref interfaceData)) { Native.SP_DEVICE_INTERFACE_DETAIL_DATA detail = new Native.SP_DEVICE_INTERFACE_DETAIL_DATA(); // explicit size of unmanaged structure must be provided, because it does not include transfer buffer // for whatever reason on 64 bit machines the detail size is 8 rather than 5, likewise the interfaceData.cbSize // is 32 rather than 28 for non 64bit machines, therefore, we make the detemination of the size based // on the interfaceData.cbSize (kind of hacky but it works). if (interfaceData.cbSize == 32) { detail.cbSize = 8; } else { detail.cbSize = 5; } if (Native.SetupDiGetDeviceInterfaceDetail(devInfo, ref interfaceData, ref detail, Marshal.SizeOf(detail) * 2, 0, 0)) { string port = detail.DevicePath.ToLower(); AsyncUsbStream s = null; try { s = new AsyncUsbStream(port); string displayName = s.RetrieveStringFromDevice(IOCTL_SPOTUSB_DISPLAY_NAME); string hash = s.RetrieveStringFromDevice(IOCTL_SPOTUSB_DEVICE_HASH); string operationalPort = s.RetrieveStringFromDevice(IOCTL_SPOTUSB_PORT_NAME); if ((operationalPort == null) || (displayName == null) || (hash == null)) { continue; } // convert kernel format to user mode format // kernel : @"\??\USB#Vid_beef&Pid_0009#5&4162af8&0&1#{09343630-a794-10ef-334f-82ea332c49f3}" // user : @"\\?\usb#vid_beef&pid_0009#5&4162af8&0&1#{09343630-a794-10ef-334f-82ea332c49f3}" StringBuilder operationalPortUser = new StringBuilder(); operationalPortUser.Append(@"\\?"); operationalPortUser.Append(operationalPort.Substring(3)); // change the display name if there is a collision (otherwise you will only be able to use one of the devices) displayName += "_" + hash; if (lst.ContainsKey(displayName)) { int i = 2; while (lst.ContainsKey(displayName + " (" + i + ")")) { i++; } displayName += " (" + i + ")"; } PortDefinition pd = PortDefinition.CreateInstanceForUsb(displayName, operationalPortUser.ToString()); RetrieveProperties(hash, ref pd, s); lst.Add(pd.DisplayName, pd); } catch { } finally { if (s != null) { s.Close(); } } } } Native.SetupDiDestroyDeviceInfoList(devInfo); }