//
// CP210x_COM_port_lister.cs
// Snippet for C# console tool, coded on MSVS 2008
// List up COM port, Product ID (just for XP) and serial number of CP210x, currently connected to this PC
//using System;
using System.Runtime.InteropServices;
using System.Text;
namespace CP210x_COM_port_lister
{
class Program
{
private readonly static IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
// constants for SetupDiGetClassDevs( flags )
internal const UInt32 DIGCF_PRESENT = 0x00000002;
internal const UInt32 DIGCF_DEVICEINTERFACE = 0x00000010;
// constants for SetupDiOpenDevRegKey( scope,,parameterRegistryValueKind,samDesired )
internal const UInt32 DICS_FLAG_GLOBAL = 0x00000001;
internal const UInt32 DIREG_DEV = 0x00000001;
internal const UInt32 KEY_READ = 0x00020019;
// constants for SetupDiGetDeviceRegistryProperty( Property )
internal const UInt32 SPDRP_DEVICEDESC = 0x00000000;
internal const UInt32 SPDRP_MFG = 0x0000000B;
internal const UInt32 SPDRP_FRIENDLYNAME = 0x0000000C;
internal const UInt32 SPDRP_LOCATION_INFORMATION = 0x0000000D;
[StructLayout(LayoutKind.Sequential)]
public struct DEVINFO_DATA
{
internal Int32 cbSize;
internal Guid ClassGuid;
internal UInt32 DevInst;
internal IntPtr Reserved;
}
[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern Boolean SetupDiClassGuidsFromName(
String className,
ref Guid classGuidArray1stItem,
UInt32 classGuidArraySize,
out Int32 RequiredSize
);
[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr SetupDiGetClassDevs(
ref Guid classGuid,
IntPtr enumerator,
IntPtr hwndParent,
UInt32 flags
);
[DllImport("setupapi.dll", SetLastError = true)]
static extern Boolean SetupDiDestroyDeviceInfoList(
IntPtr hDevInfo
);
[DllImport("setupapi.dll", SetLastError = true)]
static extern Boolean SetupDiEnumDeviceInfo(
IntPtr DeviceInfoSet,
UInt32 MemberIndex,
out DEVINFO_DATA DeviceInfoData
);
[DllImport("setupapi.dll", EntryPoint = "SetupDiGetDeviceInstanceId", CharSet = CharSet.Auto, SetLastError = true)]
static extern Boolean SetupDiGetDeviceInstanceId_getSize(
IntPtr DeviceInfoSet,
ref DEVINFO_DATA DeviceInfoData,
IntPtr DeviceInstanceId,
Int32 DeviceInstanceIdSize,
out Int32 RequiredSize
);
[DllImport("setupapi.dll", EntryPoint = "SetupDiGetDeviceInstanceId", CharSet = CharSet.Auto, SetLastError = true)]
static extern Boolean SetupDiGetDeviceInstanceId_getString(
IntPtr DeviceInfoSet,
ref DEVINFO_DATA DeviceInfoData,
StringBuilder DeviceInstanceId,
Int32 DeviceInstanceIdSize,
IntPtr RequiredSize
);
[DllImport("setupapi.dll", EntryPoint = "SetupDiGetDeviceRegistryProperty", CharSet = CharSet.Auto, SetLastError = true)]
static extern Boolean SetupDiGetDeviceRegistryProperty_getSize(
IntPtr DeviceInfoSet,
ref DEVINFO_DATA DeviceInfoData,
UInt32 Property,
IntPtr PropertyRegDataType,
IntPtr PropertyBuffer,
Int32 PropertyBufferSize,
out Int32 RequiredSize
);
[DllImport("setupapi.dll", EntryPoint = "SetupDiGetDeviceRegistryProperty", CharSet = CharSet.Auto, SetLastError = true)]
static extern Boolean SetupDiGetDeviceRegistryProperty_getString(
IntPtr DeviceInfoSet,
ref DEVINFO_DATA DeviceInfoData,
UInt32 Property,
IntPtr PropertyRegDataType,
StringBuilder PropertyBuffer,
Int32 PropertyBufferSize,
IntPtr RequiredSize
);
[DllImport("Setupapi", SetLastError = true)]
public static extern IntPtr SetupDiOpenDevRegKey(
IntPtr hDeviceInfoSet,
ref DEVINFO_DATA deviceInfoData,
UInt32 scope,
UInt32 hwProfile,
UInt32 parameterRegistryValueKind,
UInt32 samDesired
);
[DllImport("advapi32.dll", EntryPoint = "RegQueryValueEx", CharSet = CharSet.Auto, SetLastError = true)]
static extern int RegQueryValueEx_getSize(
IntPtr hKey,
String lpValueName,
IntPtr lpReserved,
IntPtr lpType,
IntPtr lpData,
out Int32 lpcbData
);
[DllImport("advapi32.dll", EntryPoint = "RegQueryValueEx", CharSet = CharSet.Auto, SetLastError = true)]
static extern int RegQueryValueEx_getString(
IntPtr hKey,
String lpValueName,
IntPtr lpReserved,
IntPtr lpType,
StringBuilder lpData,
ref Int32 lpcbData
);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern int RegCloseKey(
IntPtr hKey
);
static void Main(string[] args)
{
// device ID of CP210x VCP
// default VID/PID: 10C4/EA60
// for custom VID/PID, modify this string
String deviceID = @"USB\VID_10C4&PID_EA60\";
StringBuilder instanceID = new StringBuilder();
StringBuilder locationInfo = new StringBuilder();
StringBuilder portName = new StringBuilder();
String serialNumer;
Int32 requiredSize;
// Get Class GUID for PORTS class
Guid[] classGuidArray = new Guid[1];
if ( !SetupDiClassGuidsFromName( "PORTS", ref classGuidArray[0], 1, out requiredSize ) )
return;
// List up PORTS class devices in present
IntPtr hDevInfoSet = SetupDiGetClassDevs( ref classGuidArray[0], IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT );
if (hDevInfoSet == INVALID_HANDLE_VALUE)
return;
// Enumerate devices in the list
DEVINFO_DATA devInfo = new DEVINFO_DATA();
devInfo.cbSize = Marshal.SizeOf(devInfo);
for ( UInt32 deviceIndex = 0;
SetupDiEnumDeviceInfo( hDevInfoSet, deviceIndex, out devInfo );
deviceIndex++ )
{
// Get device instance ID
SetupDiGetDeviceInstanceId_getSize( hDevInfoSet, ref devInfo, IntPtr.Zero, 0, out requiredSize);
instanceID.EnsureCapacity( requiredSize );
SetupDiGetDeviceInstanceId_getString(hDevInfoSet, ref devInfo, instanceID, requiredSize, IntPtr.Zero);
// Check device ID
if ( !instanceID.ToString().StartsWith(deviceID, StringComparison.OrdinalIgnoreCase) )
continue;
// Split serial number
serialNumer = instanceID.ToString().Substring(deviceID.Length);
// Get location information
// For XP, LocationInformation value on registry hardware key holds
// iProduct string on the device
SetupDiGetDeviceRegistryProperty_getSize(hDevInfoSet, ref devInfo, SPDRP_LOCATION_INFORMATION, IntPtr.Zero,
IntPtr.Zero, 0, out requiredSize);
locationInfo.EnsureCapacity(requiredSize);
SetupDiGetDeviceRegistryProperty_getString(hDevInfoSet, ref devInfo, SPDRP_LOCATION_INFORMATION, IntPtr.Zero,
locationInfo, requiredSize, IntPtr.Zero);
// Open device parameters reg key
IntPtr hkey = SetupDiOpenDevRegKey(hDevInfoSet, ref devInfo, DICS_FLAG_GLOBAL,
0, DIREG_DEV, KEY_READ );
if (hkey == INVALID_HANDLE_VALUE)
continue;
// Qurey for portname
RegQueryValueEx_getSize( hkey, "PortName", IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, out requiredSize);
portName.EnsureCapacity( requiredSize );
RegQueryValueEx_getString(hkey, "PortName", IntPtr.Zero, IntPtr.Zero, portName, ref requiredSize);
// Close reg key
RegCloseKey( hkey );
Console.WriteLine("Port: " + portName + " Product ID: " + locationInfo + " Serial number: " + serialNumer);
}
// Destroy device info list
SetupDiDestroyDeviceInfoList( hDevInfoSet );
}
}
}