Yes, you can, you have all the necessary functions in the Win32 API in user32.dll and setuapi.dll. This is a C # example:
internal static bool FindUsbDevice(string vendorId, string productId, ref string deviceDesc, ref string deviceInstanceId, ref Guid classId) { bool returnValue = false; string enumeratorClass = "USB"; IntPtr szClass = Marshal.StringToHGlobalAuto(enumeratorClass); Guid classGuid = Guid.Empty; IntPtr deviceInfoSet = new System.IntPtr(); try { deviceInfoSet = DeviceManagement.SetupDiGetClassDevs(ref classGuid, szClass, IntPtr.Zero, DeviceManagement.DIGCF_ALLCLASSES | DeviceManagement.DIGCF_PRESENT); DeviceManagement.SP_DEVINFO_DATA spDevInfoData = new DeviceManagement.SP_DEVINFO_DATA(); spDevInfoData.cbSize = Marshal.SizeOf(spDevInfoData); for (int i = 0; DeviceManagement.SetupDiEnumDeviceInfo(deviceInfoSet, i, ref spDevInfoData); i++) { int nSize = 0; string DeviceInstanceId = new string('0', 259); IntPtr ptrDeviceInstanceId = Marshal.StringToHGlobalAuto(DeviceInstanceId); if (!DeviceManagement.SetupDiGetDeviceInstanceId(deviceInfoSet, ref spDevInfoData, ptrDeviceInstanceId, DeviceInstanceId.Length, ref nSize)) { Console.WriteLine("SetupDiGetDeviceInstanceId() error"); continue; } DeviceInstanceId = Marshal.PtrToStringAnsi(ptrDeviceInstanceId); if (!DeviceInstanceId.Contains(string.Format("USB\\VID_{0}&PID_{1}", vendorId, productId))) continue; returnValue = true; deviceInstanceId = DeviceInstanceId; classId = spDevInfoData.ClassGuid; int DataT = 0; string buffer = new string('0', 259); IntPtr pBuffer = Marshal.StringToHGlobalAuto(buffer); int bufferSize = 259; if (!DeviceManagement.SetupDiGetDeviceRegistryProperty( deviceInfoSet, ref spDevInfoData, DeviceManagement.SPDRP_DEVICEDESC, ref DataT, pBuffer, bufferSize, ref bufferSize)) { if (Marshal.GetLastWin32Error() == DeviceManagement.ERROR_INVALID_DATA) Debug.WriteLine("Error invalid data"); else Debug.WriteLine("error"); } else { buffer = Marshal.PtrToStringAnsi(pBuffer, bufferSize); deviceDesc = buffer; } } } catch (Exception ex) { throw ex; } finally { DeviceManagement.SetupDiDestroyDeviceInfoList(deviceInfoSet); } return returnValue; }
while shell code:
public sealed partial class DeviceManagement { ///<summary > // API declarations relating to device management (SetupDixxx and // RegisterDeviceNotification functions). /// </summary> // from dbt.h internal const Int32 DBT_DEVICEARRIVAL = 0X8000; internal const Int32 DBT_DEVICEREMOVECOMPLETE = 0X8004; internal const Int32 DBT_DEVTYP_DEVICEINTERFACE = 5; internal const Int32 DBT_DEVTYP_HANDLE = 6; internal const Int32 DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = 4; internal const Int32 DEVICE_NOTIFY_SERVICE_HANDLE = 1; internal const Int32 DEVICE_NOTIFY_WINDOW_HANDLE = 0; internal const Int32 WM_DEVICECHANGE = 0X219; // from setupapi.h internal const Int32 DIGCF_PRESENT = 2; internal const Int32 DIGCF_DEVICEINTERFACE = 0X10; internal const Int32 DIGCF_ALLCLASSES = 0x4; internal const Int32 SPDRP_FRIENDLYNAME = 0xC; internal const Int32 SPDRP_DEVICEDESC = 0x0; internal const Int32 SPDRP_CLASSGUID = 0x8; // from WinError.h internal const Int32 ERROR_INSUFFICIENT_BUFFER = 122; internal const Int32 ERROR_INVALID_DATA = 13; // Two declarations for the DEV_BROADCAST_DEVICEINTERFACE structure. // Use this one in the call to RegisterDeviceNotification() and // in checking dbch_devicetype in a DEV_BROADCAST_HDR structure: [StructLayout(LayoutKind.Sequential)] internal class DEV_BROADCAST_DEVICEINTERFACE { internal Int32 dbcc_size; internal Int32 dbcc_devicetype; internal Int32 dbcc_reserved; internal Guid dbcc_classguid; internal Int16 dbcc_name; } // Use this to read the dbcc_name String and classguid: [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] internal class DEV_BROADCAST_DEVICEINTERFACE_1 { internal Int32 dbcc_size; internal Int32 dbcc_devicetype; internal Int32 dbcc_reserved; [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 16)] internal Byte[] dbcc_classguid; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 255)] internal Char[] dbcc_name; } [StructLayout(LayoutKind.Sequential)] internal class DEV_BROADCAST_HDR { internal Int32 dbch_size; internal Int32 dbch_devicetype; internal Int32 dbch_reserved; } internal struct SP_DEVICE_INTERFACE_DATA { internal Int32 cbSize; internal System.Guid InterfaceClassGuid; internal Int32 Flags; internal IntPtr Reserved; } internal struct SP_DEVICE_INTERFACE_DETAIL_DATA { internal Int32 cbSize; internal String DevicePath; } internal struct SP_DEVINFO_DATA { internal Int32 cbSize; internal System.Guid ClassGuid; internal Int32 DevInst; internal Int32 Reserved; } [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] internal static extern IntPtr RegisterDeviceNotification(IntPtr hRecipient, IntPtr NotificationFilter, Int32 Flags); [DllImport("setupapi.dll", SetLastError = true)] internal static extern bool SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet, int MemberIndex, ref SP_DEVINFO_DATA DeviceInfoData); [DllImport("setupapi.dll", SetLastError = true)] internal static extern bool SetupDiGetDeviceInstanceId(IntPtr DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData, IntPtr DeviceInstanceId, int DeviceInstanceIdSize, ref int RequiredSize); [DllImport("setupapi.dll", SetLastError = true)] internal static extern bool SetupDiGetDeviceRegistryProperty(IntPtr DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData, int Property, ref int PropertyRegDataType, IntPtr PropertyBuffer, int PropertyBufferSize, ref int RequiredSize); [DllImport("setupapi.dll", SetLastError = true)] internal static extern Int32 SetupDiCreateDeviceInfoList(ref System.Guid ClassGuid, Int32 hwndParent); [DllImport("setupapi.dll", SetLastError = true)] internal static extern Int32 SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet); [DllImport("setupapi.dll", SetLastError = true)] internal static extern Boolean SetupDiEnumDeviceInterfaces(IntPtr DeviceInfoSet, IntPtr DeviceInfoData, ref System.Guid InterfaceClassGuid, Int32 MemberIndex, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData); [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)] internal static extern IntPtr SetupDiGetClassDevs(ref System.Guid ClassGuid, IntPtr Enumerator, IntPtr hwndParent, Int32 Flags); [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)] internal static extern Boolean SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, IntPtr DeviceInterfaceDetailData, Int32 DeviceInterfaceDetailDataSize, ref Int32 RequiredSize, IntPtr DeviceInfoData); [DllImport("user32.dll", SetLastError = true)] internal static extern Boolean UnregisterDeviceNotification(IntPtr Handle); }
Hope this helps, you should quickly translate it to Visual C ++