// 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 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); }
// 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 ); }
// 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); } }