protected static void RetrieveProperties(string hash, ref PortDefinition pd, WinUsb_AsyncUsbStream s) { IDictionaryEnumerator dict; dict = s_textProperties.GetEnumerator(); while (dict.MoveNext()) { pd.Properties.Add(dict.Key, s.RetrieveStringFromDevice((ushort)dict.Value)); } dict = s_digitProperties.GetEnumerator(); while (dict.MoveNext()) { pd.Properties.Add(dict.Key, s.RetrieveIntegerFromDevice((ushort)dict.Value)); } }
protected static void RetrieveProperties(string hash, ref PortDefinition pd, WinUsb_AsyncUsbStream s) { IDictionaryEnumerator dict; dict = s_textProperties.GetEnumerator(); while(dict.MoveNext()) { pd.Properties.Add(dict.Key, s.RetrieveStringFromDevice((ushort)dict.Value)); } dict = s_digitProperties.GetEnumerator(); while(dict.MoveNext()) { pd.Properties.Add(dict.Key, s.RetrieveIntegerFromDevice((ushort)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 guid, SortedList lst) { //string devicePath = null; //(new DeviceManagement()).FindDeviceFromGuid(guid, ref devicePath); //using (WinUsb_AsyncUsbStream s = new WinUsb_AsyncUsbStream(devicePath)) //{ // //const ushort SERIAL_NUMBER_INDEX = 0; // //const ushort MANUFACTURER_NAME_INDEX = 1; // //const ushort PRODUCT_NAME_INDEX = 2; // //const ushort USB_DISPLAY_STRING_INDEX = 4; // //const ushort USB_FRIENDLY_STRING_INDEX = 5; // string displayName = s.RetrieveStringFromDevice(USB_DISPLAY_STRING_INDEX); // string hash = s.RetrieveStringFromDevice(USB_FRIENDLY_STRING_INDEX); // //string operationalPort = s.RetrieveStringFromDevice(IOCTL_WINUSB_PORT_NAME, dmp); // //if ((operationalPort == null) || (displayName == null) || (hash == null)) // if ((displayName == null) || (hash == null)) // { // return; // } // // 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()); // PortDefinition pd = PortDefinition.CreateInstanceForWinUsb(displayName, devicePath); // //if (dmp != null) dmp.Dump("[16 == EnumeratePorts]"); // //RetrieveProperties(hash, ref pd, s); // if (!pd.Properties.Contains(DeviceHash)) pd.Properties.Add(DeviceHash, hash); // lst.Add(pd.DisplayName, pd); //} IntPtr devInfo = Native.SetupDiGetClassDevs(ref guid, null, 0, Native.DIGCF_DEVICEINTERFACE | Native.DIGCF_PRESENT); if(devInfo == Native.INVALID_HANDLE_VALUE) { return; } try { 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 guid, index++, ref interfaceData)) { try { 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(); using(WinUsb_AsyncUsbStream s = new WinUsb_AsyncUsbStream(port)) { //const ushort SERIAL_NUMBER_INDEX = 0; //const ushort MANUFACTURER_NAME_INDEX = 1; //const ushort PRODUCT_NAME_INDEX = 2; //const ushort USB_DISPLAY_STRING_INDEX = 4; //const ushort USB_FRIENDLY_STRING_INDEX = 5; string displayName = s.RetrieveStringFromDevice(USB_DISPLAY_STRING_INDEX); string hash = s.RetrieveStringFromDevice(USB_FRIENDLY_STRING_INDEX); //string operationalPort = s.RetrieveStringFromDevice(IOCTL_WINUSB_PORT_NAME, dmp); //if ((operationalPort == null) || (displayName == null) || (hash == null)) if((displayName == null) || (hash == null)) { return; } // 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.CreateInstanceForWinUsb(displayName, port); if(!pd.Properties.Contains(DeviceHash)) pd.Properties.Add(DeviceHash, hash); lst.Add(pd.DisplayName, pd); } } } catch { // go to next device } } } finally { Native.SetupDiDestroyDeviceInfoList(devInfo); } }
// 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 IEnumerable<PortDefinition> EnumeratePorts( Guid guid ) { var devInfo = NativeMethods.SetupDiGetClassDevs( ref guid, null, 0, NativeMethods.DIGCF_DEVICEINTERFACE | NativeMethods.DIGCF_PRESENT ); if( devInfo == NativeMethods.INVALID_HANDLE_VALUE ) yield break; try { var interfaceData = new NativeMethods.SP_DEVICE_INTERFACE_DATA( ); interfaceData.cbSize = Marshal.SizeOf( interfaceData ); var index = 0; while( NativeMethods.SetupDiEnumDeviceInterfaces( devInfo, 0, ref guid, index++, ref interfaceData ) ) { PortDefinition pd = null; try { var detail = new NativeMethods.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). detail.cbSize = interfaceData.cbSize == 32 ? 8 : 5; // get device interface details to allow opening the port for querying the friendly name if( !NativeMethods.SetupDiGetDeviceInterfaceDetail( devInfo, ref interfaceData, ref detail, Marshal.SizeOf( detail ) * 2, 0, 0 ) ) continue; var port = detail.DevicePath.ToLower( ); using( var s = new WinUsb_AsyncUsbStream( port ) ) { var displayName = s.RetrieveStringFromDevice( USB_DISPLAY_STRING_INDEX ); var hash = s.RetrieveStringFromDevice( USB_FRIENDLY_STRING_INDEX ); if( ( displayName == null ) || ( hash == null ) ) yield break; displayName += "_" + hash; pd = PortDefinition.CreateInstanceForWinUsb( displayName, port ); if( !pd.Properties.Contains( DeviceHash ) ) pd.Properties.Add( DeviceHash, hash ); } } catch(IOException) { // go to next device } if( pd != null ) yield return pd; } } finally { NativeMethods.SetupDiDestroyDeviceInfoList( devInfo ); } }
// 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 guid, SortedList lst) { //string devicePath = null; //(new DeviceManagement()).FindDeviceFromGuid(guid, ref devicePath); //using (WinUsb_AsyncUsbStream s = new WinUsb_AsyncUsbStream(devicePath)) //{ // //const ushort SERIAL_NUMBER_INDEX = 0; // //const ushort MANUFACTURER_NAME_INDEX = 1; // //const ushort PRODUCT_NAME_INDEX = 2; // //const ushort USB_DISPLAY_STRING_INDEX = 4; // //const ushort USB_FRIENDLY_STRING_INDEX = 5; // string displayName = s.RetrieveStringFromDevice(USB_DISPLAY_STRING_INDEX); // string hash = s.RetrieveStringFromDevice(USB_FRIENDLY_STRING_INDEX); // //string operationalPort = s.RetrieveStringFromDevice(IOCTL_WINUSB_PORT_NAME, dmp); // //if ((operationalPort == null) || (displayName == null) || (hash == null)) // if ((displayName == null) || (hash == null)) // { // return; // } // // 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()); // PortDefinition pd = PortDefinition.CreateInstanceForWinUsb(displayName, devicePath); // //if (dmp != null) dmp.Dump("[16 == EnumeratePorts]"); // //RetrieveProperties(hash, ref pd, s); // if (!pd.Properties.Contains(DeviceHash)) pd.Properties.Add(DeviceHash, hash); // lst.Add(pd.DisplayName, pd); //} IntPtr devInfo = Native.SetupDiGetClassDevs(ref guid, null, 0, Native.DIGCF_DEVICEINTERFACE | Native.DIGCF_PRESENT); if (devInfo == Native.INVALID_HANDLE_VALUE) { return; } try { 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 guid, index++, ref interfaceData)) { try { 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(); using (WinUsb_AsyncUsbStream s = new WinUsb_AsyncUsbStream(port)) { //const ushort SERIAL_NUMBER_INDEX = 0; //const ushort MANUFACTURER_NAME_INDEX = 1; //const ushort PRODUCT_NAME_INDEX = 2; //const ushort USB_DISPLAY_STRING_INDEX = 4; //const ushort USB_FRIENDLY_STRING_INDEX = 5; string displayName = s.RetrieveStringFromDevice(USB_DISPLAY_STRING_INDEX); string hash = s.RetrieveStringFromDevice(USB_FRIENDLY_STRING_INDEX); //string operationalPort = s.RetrieveStringFromDevice(IOCTL_WINUSB_PORT_NAME, dmp); //if ((operationalPort == null) || (displayName == null) || (hash == null)) if ((displayName == null) || (hash == null)) { return; } // 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.CreateInstanceForWinUsb(displayName, port); if (!pd.Properties.Contains(DeviceHash)) { pd.Properties.Add(DeviceHash, hash); } lst.Add(pd.DisplayName, pd); } } } catch { // go to next device } } } finally { Native.SetupDiDestroyDeviceInfoList(devInfo); } }
// 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 IEnumerable <PortDefinition> EnumeratePorts(Guid guid) { var devInfo = NativeMethods.SetupDiGetClassDevs(ref guid, null, 0, NativeMethods.DIGCF_DEVICEINTERFACE | NativeMethods.DIGCF_PRESENT); if (devInfo == NativeMethods.INVALID_HANDLE_VALUE) { yield break; } try { var interfaceData = new NativeMethods.SP_DEVICE_INTERFACE_DATA( ); interfaceData.cbSize = Marshal.SizeOf(interfaceData); var index = 0; while (NativeMethods.SetupDiEnumDeviceInterfaces(devInfo, 0, ref guid, index++, ref interfaceData)) { PortDefinition pd = null; try { var detail = new NativeMethods.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). detail.cbSize = interfaceData.cbSize == 32 ? 8 : 5; // get device interface details to allow opening the port for querying the friendly name if (!NativeMethods.SetupDiGetDeviceInterfaceDetail(devInfo, ref interfaceData, ref detail, Marshal.SizeOf(detail) * 2, 0, 0)) { continue; } var port = detail.DevicePath.ToLower( ); using (var s = new WinUsb_AsyncUsbStream(port)) { var displayName = s.RetrieveStringFromDevice(USB_DISPLAY_STRING_INDEX); var hash = s.RetrieveStringFromDevice(USB_FRIENDLY_STRING_INDEX); if ((displayName == null) || (hash == null)) { yield break; } displayName += "_" + hash; pd = PortDefinition.CreateInstanceForWinUsb(displayName, port); if (!pd.Properties.Contains(DeviceHash)) { pd.Properties.Add(DeviceHash, hash); } } } catch (IOException) { // go to next device } if (pd != null) { yield return(pd); } } } finally { NativeMethods.SetupDiDestroyDeviceInfoList(devInfo); } }