private static IEnumerable <string> EnumerateDevicePath(Guid guid) { var devicePathList = new List <string>(); var hDevInfo = SetupApi.SetupDiGetClassDevs(ref guid, IntPtr.Zero, IntPtr.Zero, SetupApi.DIGCF_PRESENT | SetupApi.DIGCF_DEVICEINTERFACE); var spid = new SetupApi.SP_DEVICE_INTERFACE_DATA(); spid.cbSize = Marshal.SizeOf(spid); int memberindex = 0; while (SetupApi.SetupDiEnumDeviceInterfaces(hDevInfo, IntPtr.Zero, ref guid, memberindex, ref spid)) { int bufferSize = 0; SetupApi.SetupDiGetDeviceInterfaceDetail(hDevInfo, ref spid, IntPtr.Zero, 0, ref bufferSize, IntPtr.Zero); var buffer = Marshal.AllocHGlobal(bufferSize); Marshal.WriteInt32(buffer, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8); var da = new SetupApi.SP_DEVINFO_DATA(); da.cbSize = Marshal.SizeOf(da); SetupApi.SetupDiGetDeviceInterfaceDetail(hDevInfo, ref spid, buffer, bufferSize, ref bufferSize, ref da); IntPtr pDevicePathName = new IntPtr(buffer.ToInt64() + 4); string pathName = Marshal.PtrToStringUni(pDevicePathName); Marshal.FreeHGlobal(buffer); buffer = IntPtr.Zero; memberindex++; Console.WriteLine(pathName); devicePathList.Add(pathName); } return(devicePathList); }
/// <summary> /// Gets a list of <see cref="WinUsbRegistry"/> classes for the specified interface guid. /// </summary> /// <param name="deviceInterfaceGuid">The DeviceInterfaceGUID to search for.</param> /// <param name="deviceRegistryList">A list of device paths associated with the <paramref name="deviceInterfaceGuid"/>.</param> /// <returns>True of one or more device paths was found.</returns> /// <remarks> /// Each <see cref="WinUsbRegistry"/> in the <paramref name="deviceRegistryList"/> represents a seperate WinUSB device (interface). /// </remarks> public static bool GetWinUsbRegistryList(Guid deviceInterfaceGuid, out List <WinUsbRegistry> deviceRegistryList) { deviceRegistryList = new List <WinUsbRegistry>(); int devicePathIndex = 0; SetupApi.SP_DEVICE_INTERFACE_DATA interfaceData = SetupApi.SP_DEVICE_INTERFACE_DATA.Empty; SetupApi.DeviceInterfaceDetailHelper detailHelper; SetupApi.SP_DEVINFO_DATA devInfoData = SetupApi.SP_DEVINFO_DATA.Empty; // [1] IntPtr deviceInfo = SetupApi.SetupDiGetClassDevs(ref deviceInterfaceGuid, null, IntPtr.Zero, SetupApi.DICFG.PRESENT | SetupApi.DICFG.DEVICEINTERFACE); if (deviceInfo != IntPtr.Zero) { while ((SetupApi.SetupDiEnumDeviceInterfaces(deviceInfo, null, ref deviceInterfaceGuid, devicePathIndex, ref interfaceData))) { int length = 1024; detailHelper = new SetupApi.DeviceInterfaceDetailHelper(length); bool bResult = SetupApi.SetupDiGetDeviceInterfaceDetail(deviceInfo, ref interfaceData, detailHelper.Handle, length, out length, ref devInfoData); if (bResult) { WinUsbRegistry regInfo = new WinUsbRegistry(); SetupApi.getSPDRPProperties(deviceInfo, ref devInfoData, regInfo.mDeviceProperties); // Use the actual winusb device path for SYMBOLIC_NAME_KEY. This will be used to open the device. regInfo.mDeviceProperties.Add(SYMBOLIC_NAME_KEY, detailHelper.DevicePath); #if VERY_DEBUG Debug.WriteLine(detailHelper.DevicePath); #endif regInfo.mDeviceInterfaceGuids = new Guid[] { deviceInterfaceGuid }; StringBuilder sbDeviceID = new StringBuilder(1024); if (SetupApi.CM_Get_Device_ID(devInfoData.DevInst, sbDeviceID, sbDeviceID.Capacity, 0) == SetupApi.CR.SUCCESS) { regInfo.mDeviceProperties[DEVICE_ID_KEY] = sbDeviceID.ToString(); } deviceRegistryList.Add(regInfo); } devicePathIndex++; } } if (devicePathIndex == 0) { UsbError.Error(ErrorCode.Win32Error, Marshal.GetLastWin32Error(), "GetDevicePathList", typeof(SetupApi)); } if (deviceInfo != IntPtr.Zero) { SetupApi.SetupDiDestroyDeviceInfoList(deviceInfo); } return(devicePathIndex > 0); }
private string GetPath(IntPtr deviceInfoList, SetupApi.SP_DEVICE_INTERFACE_DATA deviceInfo) { var deviceInterfaceDetailData = IntPtr.Zero; uint needed; if (!SetupApi.SetupDiGetDeviceInterfaceDetail(deviceInfoList, ref deviceInfo, IntPtr.Zero, 0, out needed, IntPtr.Zero)) { var error = Marshal.GetLastWin32Error(); if (error != 122) { return(string.Empty); } } var spDeviceInterfaceData = new SetupApi.SP_DEVICE_INTERFACE_DATA(); spDeviceInterfaceData.cbSize = Marshal.SizeOf(spDeviceInterfaceData); try { deviceInterfaceDetailData = Marshal.AllocHGlobal((int)(8 + needed)); var size = IntPtr.Size == 8 ? 8 : 6; Marshal.WriteInt32(deviceInterfaceDetailData, size); if (!SetupApi.SetupDiGetDeviceInterfaceDetail(deviceInfoList, ref deviceInfo, deviceInterfaceDetailData, needed, out needed, IntPtr.Zero)) { var error = Marshal.GetLastWin32Error(); } var pStr = IntPtr.Add(deviceInterfaceDetailData, sizeof(uint)); var path = Marshal.PtrToStringUni(pStr); return(path); } finally { Marshal.FreeHGlobal(deviceInterfaceDetailData); } }
public KeyboardController() { // Get HID GUID. Hid.HidD_GetHidGuid(out Guid hidGuid); List <HidDevice> devs = new List <HidDevice>(); IntPtr classDevs = SetupApi.SetupDiGetClassDevs(ref hidGuid, IntPtr.Zero, IntPtr.Zero, DiGetClassFlags.Present | DiGetClassFlags.DeviceInterface); try { // Enumerate HID devices. for (uint index = 0;; ++index) { SP_DEVICE_INTERFACE_DATA deviceInterfaceData = new SP_DEVICE_INTERFACE_DATA { cbSize = (uint)Marshal.SizeOf <SP_DEVICE_INTERFACE_DATA>() }; if (!SetupApi.SetupDiEnumDeviceInterfaces(classDevs, IntPtr.Zero, ref hidGuid, index, ref deviceInterfaceData)) { break; // End of list. } SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData = new SP_DEVICE_INTERFACE_DETAIL_DATA { cbSize = IntPtr.Size == 8 ? 8U : (uint)(4 + Marshal.SystemDefaultCharSize) }; SP_DEVINFO_DATA deviceInfoData = new SP_DEVINFO_DATA { cbSize = (uint)Marshal.SizeOf <SP_DEVINFO_DATA>() }; if (SetupApi.SetupDiGetDeviceInterfaceDetail(classDevs, ref deviceInterfaceData, ref deviceInterfaceDetailData, 256U, out uint requiredSize, ref deviceInfoData)) { // Found one. // Try to open device. string devPath = deviceInterfaceDetailData.DevicePath; SafeFileHandle devHandle = Kernel32.CreateFile(devPath, Kernel32.GENERIC_READ | Kernel32.GENERIC_WRITE, Kernel32.FILE_SHARE_READ | Kernel32.FILE_SHARE_WRITE, IntPtr.Zero, Kernel32.CREATE_NEW | Kernel32.CREATE_ALWAYS, Kernel32.FILE_FLAG_OVERLAPPED, IntPtr.Zero); // Get HID attributes. HIDD_ATTRIBUTES attributes = default; HIDP_CAPS caps; Hid.HidD_GetAttributes(devHandle, ref attributes); // Match against Gigabyte keyboard product IDs. if (!supportedKeyboards.TryGetValue(attributes.VendorID, out ushort[] pids))
/// <summary> /// Gets a list of WinUSB device paths for the specified interface guid. /// </summary> /// <param name="deviceInterfaceGuid">The DeviceInterfaceGUID to search for.</param> /// <param name="devicePathList">A list of device paths associated with the <paramref name="deviceInterfaceGuid"/>.</param> /// <returns>True of one or more device paths was found.</returns> /// <remarks> /// Each device path string in the <paramref name="devicePathList"/> represents a seperate WinUSB device (interface). /// </remarks> /// <seealso cref="GetWinUsbRegistryList"/> public static bool GetDevicePathList(Guid deviceInterfaceGuid, out List <String> devicePathList) { devicePathList = new List <string>(); int devicePathIndex = 0; SetupApi.SP_DEVICE_INTERFACE_DATA interfaceData = SetupApi.SP_DEVICE_INTERFACE_DATA.Empty; SetupApi.DeviceInterfaceDetailHelper detailHelper; IntPtr deviceInfo = SetupApi.SetupDiGetClassDevs(ref deviceInterfaceGuid, null, IntPtr.Zero, SetupApi.DICFG.PRESENT | SetupApi.DICFG.DEVICEINTERFACE); if (deviceInfo != IntPtr.Zero) { while ((SetupApi.SetupDiEnumDeviceInterfaces(deviceInfo, null, ref deviceInterfaceGuid, devicePathIndex, ref interfaceData))) { int length = 1024; detailHelper = new SetupApi.DeviceInterfaceDetailHelper(length); bool bResult = SetupApi.SetupDiGetDeviceInterfaceDetail(deviceInfo, ref interfaceData, detailHelper.Handle, length, out length, null); if (bResult) { devicePathList.Add(detailHelper.DevicePath); } devicePathIndex++; } } if (devicePathIndex == 0) { UsbError.Error(ErrorCode.Win32Error, Marshal.GetLastWin32Error(), "GetDevicePathList", typeof(SetupApi)); } if (deviceInfo != IntPtr.Zero) { SetupApi.SetupDiDestroyDeviceInfoList(deviceInfo); } return(devicePathIndex > 0); }
public static bool FindHidDevices(ref List <string> DevicePathNames) { Debug.WriteLine("findHidDevices() -> Method called"); // Initialize the internal variables required for performing the search var bufferSize = 0; var detailDataBuffer = IntPtr.Zero; bool deviceFound; var deviceInfoSet = new IntPtr(); var lastDevice = false; int listIndex; var deviceInterfaceData = new SpDeviceInterfaceData(); // Get the required GUID var systemHidGuid = new Guid(); Hid.HidD_GetHidGuid(ref systemHidGuid); Debug.WriteLine(string.Format("findHidDevices() -> Fetched GUID for HID devices ({0})", systemHidGuid.ToString())); try { // Here we populate a list of plugged-in devices matching our class GUID (DIGCF_PRESENT specifies that the list // should only contain devices which are plugged in) Debug.WriteLine("findHidDevices() -> Using SetupDiGetClassDevs to get all devices with the correct GUID"); deviceInfoSet = SetupApi.SetupDiGetClassDevs(ref systemHidGuid, IntPtr.Zero, IntPtr.Zero, Constants.DigcfPresent | Constants.DigcfDeviceinterface); // Reset the deviceFound flag and the memberIndex counter deviceFound = false; listIndex = 0; deviceInterfaceData.cbSize = Marshal.SizeOf(deviceInterfaceData); // Look through the retrieved list of class GUIDs looking for a match on our interface GUID do { //Debug.WriteLine("usbGenericHidCommunication:findHidDevices() -> Enumerating devices"); var success = SetupApi.SetupDiEnumDeviceInterfaces(deviceInfoSet, IntPtr.Zero, ref systemHidGuid, listIndex, ref deviceInterfaceData); if (!success) { //Debug.WriteLine("usbGenericHidCommunication:findHidDevices() -> No more devices left - giving up"); lastDevice = true; } else { // The target device has been found, now we need to retrieve the device path so we can open // the read and write handles required for USB communication // First call is just to get the required buffer size for the real request SetupApi.SetupDiGetDeviceInterfaceDetail (deviceInfoSet, ref deviceInterfaceData, IntPtr.Zero, 0, ref bufferSize, IntPtr.Zero); // Allocate some memory for the buffer detailDataBuffer = Marshal.AllocHGlobal(bufferSize); Marshal.WriteInt32(detailDataBuffer, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8); // Second call gets the detailed data buffer //Debug.WriteLine("usbGenericHidCommunication:findHidDevices() -> Getting details of the device"); SetupApi.SetupDiGetDeviceInterfaceDetail (deviceInfoSet, ref deviceInterfaceData, detailDataBuffer, bufferSize, ref bufferSize, IntPtr.Zero); // Skip over cbsize (4 bytes) to get the address of the devicePathName. var pDevicePathName = new IntPtr(detailDataBuffer.ToInt32() + 4); // Get the String containing the devicePathName. DevicePathNames.Add(Marshal.PtrToStringAuto(pDevicePathName)); //Debug.WriteLine(string.Format("usbGenericHidCommunication:findHidDevices() -> Found matching device (memberIndex {0})", memberIndex)); deviceFound = true; } listIndex += 1; }while (lastDevice != true); } catch (Exception) { // Something went badly wrong... output some debug and return false to indicated device discovery failure Debug.WriteLine("findHidDevices() -> EXCEPTION: Something went south whilst trying to get devices with matching GUIDs - giving up!"); return(false); } finally { // Clean up the unmanaged memory allocations if (detailDataBuffer != IntPtr.Zero) { // Free the memory allocated previously by AllocHGlobal. Marshal.FreeHGlobal(detailDataBuffer); } if (deviceInfoSet != IntPtr.Zero) { SetupApi.SetupDiDestroyDeviceInfoList(deviceInfoSet); } } if (deviceFound) { Debug.WriteLine(string.Format("findHidDevices() -> Found {0} devices with matching GUID", (DevicePathNames.Count).ToString(CultureInfo.InvariantCulture))); } else { Debug.WriteLine("findHidDevices() -> No matching devices found"); } return(deviceFound); }
public static bool FindHidDevices(ref string[] listOfDevicePathNames, ref int numberOfDevicesFound) { TmoShare.WriteLog("DeviceDiscovery:findHidDevices() -> 开始查找所有HID设备"); // Initialise the internal variables required for performing the search var bufferSize = 0; var detailDataBuffer = IntPtr.Zero; bool deviceFound; var deviceInfoSet = new IntPtr(); var lastDevice = false; int listIndex; var deviceInterfaceData = new SpDeviceInterfaceData(); // Get the required GUID var systemHidGuid = new Guid(); Hid.HidD_GetHidGuid(ref systemHidGuid); TmoShare.WriteLog(string.Format("DeviceDiscovery:findHidDevices() -> 找到HID设备全局 GUID {0}", systemHidGuid)); try { // Here we populate a list of plugged-in devices matching our class GUID (DIGCF_PRESENT specifies that the list // should only contain devices which are plugged in) TmoShare.WriteLog("DeviceDiscovery:findHidDevices() -> 获取所有HID设备句柄"); deviceInfoSet = SetupApi.SetupDiGetClassDevs(ref systemHidGuid, IntPtr.Zero, IntPtr.Zero, Constants.DigcfPresent | Constants.DigcfDeviceinterface); // Reset the deviceFound flag and the memberIndex counter deviceFound = false; listIndex = 0; deviceInterfaceData.cbSize = Marshal.SizeOf(deviceInterfaceData); // Look through the retrieved list of class GUIDs looking for a match on our interface GUID do { TmoShare.WriteLog("DeviceDiscovery:findHidDevices() -> 获取设备信息"); var success = SetupApi.SetupDiEnumDeviceInterfaces(deviceInfoSet, IntPtr.Zero, ref systemHidGuid, listIndex, ref deviceInterfaceData); if (!success) { TmoShare.WriteLog("DeviceDiscovery:findHidDevices() -> 已经找到最后一个-停止"); lastDevice = true; } else { // The target device has been found, now we need to retrieve the device path so we can open // the read and write handles required for USB communication // First call is just to get the required buffer size for the real request SetupApi.SetupDiGetDeviceInterfaceDetail (deviceInfoSet, ref deviceInterfaceData, IntPtr.Zero, 0, ref bufferSize, IntPtr.Zero); // Allocate some memory for the buffer detailDataBuffer = Marshal.AllocHGlobal(bufferSize); Marshal.WriteInt32(detailDataBuffer, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8); // Second call gets the detailed data buffer TmoShare.WriteLog("DeviceDiscovery:findHidDevices() -> 获取设备详细信息"); SetupApi.SetupDiGetDeviceInterfaceDetail (deviceInfoSet, ref deviceInterfaceData, detailDataBuffer, bufferSize, ref bufferSize, IntPtr.Zero); // Skip over cbsize (4 bytes) to get the address of the devicePathName. var pDevicePathName = new IntPtr(detailDataBuffer.ToInt32() + 4); // Get the String containing the devicePathName. listOfDevicePathNames[listIndex] = Marshal.PtrToStringAuto(pDevicePathName).ToUpper(); TmoShare.WriteLog(string.Format("DeviceDiscovery:findHidDevices() -> 将找到的设备添加进列表 (索引 {0})", listIndex)); deviceFound = true; listIndex++; } }while (lastDevice != true); } catch (Exception ex) { // Something went badly wrong... output some debug and return false to indicated device discovery failure TmoShare.WriteLog("DeviceDiscovery:findHidDevices() -> 发生异常: " + ex.Message); return(false); } finally { // Clean up the unmanaged memory allocations if (detailDataBuffer != IntPtr.Zero) { // Free the memory allocated previously by AllocHGlobal. Marshal.FreeHGlobal(detailDataBuffer); } if (deviceInfoSet != IntPtr.Zero) { SetupApi.SetupDiDestroyDeviceInfoList(deviceInfoSet); } } if (deviceFound) { TmoShare.WriteLog(String.Format("DeviceDiscovery:findHidDevices() -> 一共找到{0}个HID设备", listIndex)); numberOfDevicesFound = listIndex; } else { TmoShare.WriteLog("DeviceDiscovery:findHidDevices() -> 没有找到HID设备"); } return(deviceFound); }
private string FindDevicePath() { var hidGuid = HidGuid; var deviceInfoList = SetupApi.SetupDiGetClassDevs(ref hidGuid, null, IntPtr.Zero, DIGCF.DeviceInterface | DIGCF.Present); if (IntPtr.Zero == deviceInfoList) { return(null); } try { for (uint i = 0; ; i++) { var deviceInterfaceData = new SP_DEVICE_INTERFACE_DATA(); deviceInterfaceData.cbSize = (uint)Marshal.SizeOf(deviceInterfaceData); if (!SetupApi.SetupDiEnumDeviceInterfaces(deviceInfoList, IntPtr.Zero, ref hidGuid, i, ref deviceInterfaceData)) { break; // end of the list } var deviceInfoData = new SP_DEVINFO_DATA(); deviceInfoData.cbSize = (uint)Marshal.SizeOf(deviceInfoData); if (!SetupApi.SetupDiEnumDeviceInfo(deviceInfoList, i, ref deviceInfoData)) { continue; } const uint bufferSize = 1048; var propertyBuffer = Marshal.AllocHGlobal((int)bufferSize); try { uint requiredSize; uint propRegDataType; if (!SetupApi.SetupDiGetDeviceRegistryProperty( deviceInfoList, ref deviceInfoData, SPDRP.HardwareId, out propRegDataType, propertyBuffer, bufferSize, out requiredSize) ) { continue; } var deviceId = Marshal.PtrToStringAuto(propertyBuffer, (int)requiredSize); if (String.IsNullOrEmpty(deviceId) || !deviceId.ToUpperInvariant().Contains(_deviceIdUpper) ) { continue; } var deviceInterfaceDetailData = new SP_DEVICE_INTERFACE_DETAIL_DATA { cbSize = IntPtr.Size == 8 ? 8 : (uint)(4 + Marshal.SystemDefaultCharSize) }; var interfaceDetailOk = SetupApi.SetupDiGetDeviceInterfaceDetail( deviceInfoList, ref deviceInterfaceData, ref deviceInterfaceDetailData, SP_DEVICE_INTERFACE_DETAIL_DATA.BUFFER_SIZE, out requiredSize, ref deviceInfoData); if (interfaceDetailOk) { return(deviceInterfaceDetailData.devicePath); } } finally { Marshal.FreeHGlobal(propertyBuffer); } } } finally { SetupApi.SetupDiDestroyDeviceInfoList(deviceInfoList); } return(null); }
public static List <string> FindAllHidDevices() { var listOfDevicePathNames = new List <string>(); var detailDataBuffer = IntPtr.Zero; int listIndex = 0; var deviceInterfaceData = new SpDeviceInterfaceData(); int lasterror = 0; // Get the required HID class GUID var systemHidGuid = new Guid(); Hid.HidD_GetHidGuid(ref systemHidGuid); IntPtr deviceInfoSet = SetupDiGetClassDevs(ref systemHidGuid); deviceInterfaceData.cbSize = Marshal.SizeOf(deviceInterfaceData); try { // Look through the retrieved list of class GUIDs looking for a match on our interface GUID // SetupDiEnumDeviceInterfaces will return false if it fails for any reason, including when no more items are left // so we need to keep looping until the last thrown error is ERROR_NO_MORE_ITEMS // Note: we post increment lastIndex so each subsequent call refers to a new device while (SetupApi.SetupDiEnumDeviceInterfaces(deviceInfoSet, IntPtr.Zero, ref systemHidGuid, listIndex++, ref deviceInterfaceData) || (lasterror = Marshal.GetLastWin32Error()) != Constants.ERROR_NO_MORE_ITEMS) { if (lasterror != 0) { // SetupDiEnumDeviceInterfaces failed and it wasn't ERROR_NO_MORE_ITEMS as this would have stopped the loop Debug.WriteLine("SetupDiEnumDeviceInterfaces failed for run {0} with error {1}", listIndex, lasterror); continue; } int bufferSize = 0; // The target device has been found, now we need to retrieve the device path so we can open // the read and write handles required for USB communication // First call fails with ERROR_INSUFFICIENT_BUFFER and is used just to get the required buffer size for the real request var success = SetupApi.SetupDiGetDeviceInterfaceDetail( deviceInfoSet, ref deviceInterfaceData, IntPtr.Zero, 0, ref bufferSize, IntPtr.Zero ); // Allocate some memory for the buffer detailDataBuffer = Marshal.AllocHGlobal(bufferSize); Marshal.WriteInt32(detailDataBuffer, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8); // Second call gets the detailed data buffer success = SetupApi.SetupDiGetDeviceInterfaceDetail( deviceInfoSet, ref deviceInterfaceData, detailDataBuffer, bufferSize, ref bufferSize, IntPtr.Zero ); if (!success) { Debug.WriteLine("SetupDiGetDeviceInterfaceDetail failed for run {0} with error {1}", listIndex, Marshal.GetLastWin32Error()); continue; } // Skip over cbsize (4 bytes) to get the address of the devicePathName. var pDevicePathName = IntPtr.Add(detailDataBuffer, 4); // Get the String containing the devicePathName. listOfDevicePathNames.Add(Marshal.PtrToStringAuto(pDevicePathName)); } } catch (Exception) { // Something went badly wrong... listOfDevicePathNames.Clear(); } finally { // Clean up the unmanaged memory allocations and free resources held by the windows API Marshal.FreeHGlobal(detailDataBuffer); SetupApi.SetupDiDestroyDeviceInfoList(deviceInfoSet); } return(listOfDevicePathNames); }
public static IEnumerable <UsbController> GetControllers() { var hostGUID = new Guid(UsbConstants.GUID_DEVINTERFACE_HUBCONTROLLER); var h = SetupApi.SetupDiGetClassDevs(ref hostGUID, default(int), IntPtr.Zero, UsbConstants.DIGCF_PRESENT | UsbConstants.DIGCF_DEVICEINTERFACE); if (h.ToInt32() != UsbConstants.INVALID_HANDLE_VALUE) { var ptrBuf = Marshal.AllocHGlobal(UsbConstants.BUFFER_SIZE); var i = default(int); var success = default(bool); do { var host = new UsbController(null) { ControllerIndex = i, }; var dia = new SpDeviceInterfaceData(); dia.cbSize = Marshal.SizeOf(dia); success = SetupApi.SetupDiEnumDeviceInterfaces(h, IntPtr.Zero, ref hostGUID, i, ref dia); if (success) { var da = new SpDevinfoData(); da.cbSize = Marshal.SizeOf(da); var didd = new SpDeviceInterfaceDetailData { cbSize = 4 + Marshal.SystemDefaultCharSize, }; var nRequiredSize = default(int); var nBytes = UsbConstants.BUFFER_SIZE; if (SetupApi.SetupDiGetDeviceInterfaceDetail(h, ref dia, ref didd, nBytes, ref nRequiredSize, ref da)) { host.ControllerDevicePath = didd.DevicePath; var requiredSize = default(int); var regType = UsbConstants.REG_SZ; if (SetupApi.SetupDiGetDeviceRegistryProperty(h, ref da, UsbConstants.SPDRP_DEVICEDESC, ref regType, ptrBuf, UsbConstants.BUFFER_SIZE, ref requiredSize)) { host.ControllerDeviceDesc = Marshal.PtrToStringAuto(ptrBuf); } if (SetupApi.SetupDiGetDeviceRegistryProperty(h, ref da, UsbConstants.SPDRP_DRIVER, ref regType, ptrBuf, UsbConstants.BUFFER_SIZE, ref requiredSize)) { host.ControllerDriverKeyName = Marshal.PtrToStringAuto(ptrBuf); } } yield return(host); } i++; }while (success); Marshal.FreeHGlobal(ptrBuf); SetupApi.SetupDiDestroyDeviceInfoList(h); } }
public static UsbDevice FindDriveLetter(string driveName) { UsbDevice foundDevice = null; var instanceID = string.Empty; var devNum = UsbLogic.GetDeviceNumber($@"\\.\{driveName.TrimEnd('\\')}"); if (devNum < default(int)) { return(foundDevice); } var diskGUID = new Guid(UsbConstants.GUID_DEVINTERFACE_DISK); var h = SetupApi.SetupDiGetClassDevs(ref diskGUID, default(int), IntPtr.Zero, UsbConstants.DIGCF_PRESENT | UsbConstants.DIGCF_DEVICEINTERFACE); if (h.ToInt32() != UsbConstants.INVALID_HANDLE_VALUE) { var i = default(int); var success = true; do { var dia = new SpDeviceInterfaceData(); dia.cbSize = Marshal.SizeOf(dia); success = SetupApi.SetupDiEnumDeviceInterfaces(h, IntPtr.Zero, ref diskGUID, i, ref dia); if (success) { var da = new SpDevinfoData(); da.cbSize = Marshal.SizeOf(da); var didd = new SpDeviceInterfaceDetailData { cbSize = 4 + Marshal.SystemDefaultCharSize, }; var nRequiredSize = default(int); int nBytes = UsbConstants.BUFFER_SIZE; if (SetupApi.SetupDiGetDeviceInterfaceDetail(h, ref dia, ref didd, nBytes, ref nRequiredSize, ref da)) { if (UsbLogic.GetDeviceNumber(didd.DevicePath) == devNum) { SetupApi.CM_Get_Parent(out IntPtr ptrPrevious, da.DevInst, default(int)); var ptrInstanceBuf = Marshal.AllocHGlobal(nBytes); SetupApi.CM_Get_Device_ID(ptrPrevious, ptrInstanceBuf, nBytes, default(int)); instanceID = Marshal.PtrToStringAuto(ptrInstanceBuf); Marshal.FreeHGlobal(ptrInstanceBuf); break; } } } i++; } while (success); SetupApi.SetupDiDestroyDeviceInfoList(h); } if (instanceID.StartsWith("USB\\")) { foundDevice = UsbLogic.FindDeviceByInstanceID(instanceID, driveName); } return(foundDevice); }
private void _DeviceSearchThread() { _Logger.Info("Started"); while (_Running) { var loopStart = DateTime.Now; #region Device enumeration var devices = new List <UsbDevice>(); var detailDataBuffer = IntPtr.Zero; var deviceInfoSet = IntPtr.Zero; try { int listIndex = 0; int lastError = 0; var deviceInterfaceData = new SpDeviceInterfaceData(); var systemHidGuid = new Guid(); Hid.HidD_GetHidGuid(ref systemHidGuid); deviceInfoSet = SetupApi.SetupDiGetClassDevs(ref systemHidGuid, IntPtr.Zero, IntPtr.Zero, Constants.DigcfPresent | Constants.DigcfDeviceinterface); deviceInterfaceData.cbSize = Marshal.SizeOf(deviceInterfaceData); while (SetupApi.SetupDiEnumDeviceInterfaces(deviceInfoSet, IntPtr.Zero, ref systemHidGuid, listIndex++, ref deviceInterfaceData) || (lastError = Marshal.GetLastWin32Error()) != Constants.ERROR_NO_MORE_ITEMS) { if (lastError == 0) { int bufferSize = 0; SetupApi.SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref deviceInterfaceData, IntPtr.Zero, 0, ref bufferSize, IntPtr.Zero); detailDataBuffer = Marshal.AllocHGlobal(bufferSize); Marshal.WriteInt32(detailDataBuffer, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8); if (SetupApi.SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref deviceInterfaceData, detailDataBuffer, bufferSize, ref bufferSize, IntPtr.Zero)) { var pDevicePathName = IntPtr.Add(detailDataBuffer, 4); var devicePath = Marshal.PtrToStringAuto(pDevicePathName); // Get device capabilities (to determine usage page) using (var hidHandle = Kernel32.CreateFile(devicePath, 0, Constants.FileShareRead | Constants.FileShareWrite, IntPtr.Zero, Constants.OpenExisting, 0, 0)) { var preparsedData = IntPtr.Zero; try { preparsedData = new IntPtr(); Hid.HidD_GetPreparsedData(hidHandle, ref preparsedData); var caps = new HidpCaps(); Hid.HidP_GetCaps(preparsedData, ref caps); var attrs = new HiddAttributes(); Hid.HidD_GetAttributes(hidHandle, ref attrs); // Only add the device if it has our VID, PID, and RAW usage page var deviceClass = FindDeviceClass(attrs.VendorID, attrs.ProductID, attrs.VersionNumber, caps.UsagePage); if (deviceClass != null) { var manufacturer = new StringBuilder(STRING_SIZE_LIMIT); var product = new StringBuilder(STRING_SIZE_LIMIT); var serial = new StringBuilder(STRING_SIZE_LIMIT); Hid.HidD_GetManufacturerString(hidHandle, manufacturer, STRING_SIZE_LIMIT); Hid.HidD_GetProductString(hidHandle, product, STRING_SIZE_LIMIT); Hid.HidD_GetSerialNumberString(hidHandle, serial, STRING_SIZE_LIMIT); var device = new UsbDevice(new DeviceInstance(deviceClass, devicePath, manufacturer.ToString(), product.ToString(), serial.ToString()), caps); devices.Add(device); } } finally { // Free up the memory before finishing if (preparsedData != IntPtr.Zero) { Hid.HidD_FreePreparsedData(preparsedData); } } } } } } } catch (Exception ex) { _Logger.Error(ex, "Error scanning for devices:"); devices.Clear(); } finally { // Clean up the unmanaged memory allocations and free resources held by the windows API if (detailDataBuffer != IntPtr.Zero) { Marshal.FreeHGlobal(detailDataBuffer); } if (deviceInfoSet != IntPtr.Zero) { SetupApi.SetupDiDestroyDeviceInfoList(deviceInfoSet); } } var addedDevices = devices.Except(_CurrentDevices); var removedDevices = _CurrentDevices.Except(devices); _CurrentDevices = devices; if (DeviceRemoved != null) { foreach (var dev in removedDevices) { _Logger.Info("Device removed: {0}", dev); DeviceRemoved(this, new DeviceEventArgs(dev.Instance)); } } if (DeviceAdded != null) { foreach (var dev in addedDevices) { _Logger.Info("Device added: {0}", dev); DeviceAdded(this, new DeviceEventArgs(dev.Instance)); } } #endregion #region Active device I/O // If we receive a request to change the active device while we are processing messages, we need to stop immediately because they are about to become invalid { byte[] msg; while (true) { byte[] response = null; // Block until SetActiveDevice finishes lock (_LockObject) { // If we created a new message queue in the call to SetActiveDevice, this will return false and we'll break out of the loop if (_ActiveDevice == null || !_MessageQueue.TryDequeue(out msg)) { break; } try { response = SendDeviceRequest(_ActiveDevice, msg); } catch (Exception ex) { _Logger.Error(ex, "Error communicating with device: {0} (0x{1:X8})", ex.Message, ex.HResult); } } if (response != null) { ProcessResponse(msg, response); } else { _Logger.Error("Failed to read data from device. req = {0}", FormatByteArray(msg)); } } } // Get LED config (it may have changed) { byte[] response = null; byte[] msg = CreateSimpleMessage(hid_pkt_req.HID_PKT_REQ_CONFIG_LED_GET); // Block until SetActiveDevice finishes lock (_LockObject) { if (_ActiveDevice != null) { try { response = SendDeviceRequest(_ActiveDevice, msg); } catch (Exception ex) { _Logger.Error(ex, "Error communicating with device: {0} (0x{1:X8})", ex.Message, ex.HResult); } } } if (response != null) { ProcessResponse(msg, response); } } // Get LED status { byte[] response = null; byte[] msg = new byte[2]; msg[0] = (byte)hid_pkt_req.HID_PKT_REQ_LED_STATUS; msg[1] = 0; var ledStatuses = new List <LedColor>(); do { lock (_LockObject) { if (_ActiveDevice != null) { try { response = SendDeviceRequest(_ActiveDevice, msg); } catch (Exception ex) { _Logger.Error(ex, "Error communicating with device: {0} (0x{1:X8})", ex.Message, ex.HResult); } } } if (response != null) { // Parse response for (byte i = 0; i < response[1] && i < 10; i++) { var led = new LedColor( response[i * 3 + 2], response[i * 3 + 3], response[i * 3 + 4] ); ledStatuses.Add(led); } msg[1] += 10; } } while (response != null && response[0] == (byte)hid_pkt_res.HID_PKT_RES_MORE); LedStatusReceived?.Invoke(this, new LedStatusReceivedEventArgs(ledStatuses)); } #endregion // Wait until the entire loop execution is at least 100ms var loopTime = DateTime.Now - loopStart; if (loopTime < LOOP_DELAY) { var waitTime = LOOP_DELAY - loopTime; Thread.Sleep(waitTime); } } }