public void reEnableDevice(string deviceInstanceId) { bool success; Guid hidGuid = NativeMethods.HidD_GetHidGuid(); NativeMethods.HDEVINFO deviceInfoSet = NativeMethods.SetupDiGetClassDevs(hidGuid, deviceInstanceId, IntPtr.Zero, NativeMethods.DIGCF.Present | NativeMethods.DIGCF.DeviceInterface); NativeMethods.SP_DEVINFO_DATA deviceInfoData = new NativeMethods.SP_DEVINFO_DATA(); deviceInfoData.Size = Marshal.SizeOf(deviceInfoData); success = NativeMethods.SetupDiEnumDeviceInfo(deviceInfoSet, 0, ref deviceInfoData); if (!success) { throw new Exception("Error getting device info data, error code = " + Marshal.GetLastWin32Error()); } success = NativeMethods.SetupDiEnumDeviceInfo(deviceInfoSet, 1, ref deviceInfoData); // Checks that we have a unique device if (success) { throw new Exception("Can't find unique device"); } NativeMethods.SP_PROPCHANGE_PARAMS propChangeParams = new NativeMethods.SP_PROPCHANGE_PARAMS(); propChangeParams.classInstallHeader.cbSize = Marshal.SizeOf(propChangeParams.classInstallHeader); propChangeParams.classInstallHeader.installFunction = NativeMethods.DIF_PROPERTYCHANGE; propChangeParams.stateChange = NativeMethods.DICS_DISABLE; propChangeParams.scope = NativeMethods.DICS_FLAG_GLOBAL; propChangeParams.hwProfile = 0; success = NativeMethods.SetupDiSetClassInstallParams(deviceInfoSet, ref deviceInfoData, ref propChangeParams, Marshal.SizeOf(propChangeParams)); if (!success) { throw new Exception("Error setting class install params, error code = " + Marshal.GetLastWin32Error()); } success = NativeMethods.SetupDiCallClassInstaller(NativeMethods.DIF_PROPERTYCHANGE, deviceInfoSet, ref deviceInfoData); // TEST: If previous SetupDiCallClassInstaller fails, just continue // otherwise device will likely get permanently disabled. /*if (!success) * { * throw new Exception("Error disabling device, error code = " + Marshal.GetLastWin32Error()); * } */ //System.Threading.Thread.Sleep(50); sw.Restart(); while (sw.ElapsedMilliseconds < 50) { // Use SpinWait to keep control of current thread. Using Sleep could potentially // cause other events to get run out of order System.Threading.Thread.SpinWait(100); } sw.Stop(); propChangeParams.stateChange = NativeMethods.DICS_ENABLE; success = NativeMethods.SetupDiSetClassInstallParams(deviceInfoSet, ref deviceInfoData, ref propChangeParams, Marshal.SizeOf(propChangeParams)); if (!success) { throw new Exception("Error setting class install params, error code = " + Marshal.GetLastWin32Error()); } success = NativeMethods.SetupDiCallClassInstaller(NativeMethods.DIF_PROPERTYCHANGE, deviceInfoSet, ref deviceInfoData); if (!success) { throw new Exception("Error enabling device, error code = " + Marshal.GetLastWin32Error()); } //System.Threading.Thread.Sleep(50); sw.Restart(); while (sw.ElapsedMilliseconds < 50) { // Use SpinWait to keep control of current thread. Using Sleep could potentially // cause other events to get run out of order System.Threading.Thread.SpinWait(100); } sw.Stop(); NativeMethods.SetupDiDestroyDeviceInfoList(deviceInfoSet); }
protected override string GetStreamPath(OpenConfiguration openConfig) { var service = GetService(openConfig); if (service == null) { throw DeviceException.CreateIOException(this, "BLE service not specified."); } if (service.Device != this) { throw DeviceException.CreateIOException(this, "BLE service is on a different device."); } uint devInst; if (0 == NativeMethods.CM_Locate_DevNode(out devInst, _id)) { if (0 == NativeMethods.CM_Get_Child(out devInst, devInst)) { do { string serviceDeviceID; if (0 == NativeMethods.CM_Get_Device_ID(devInst, out serviceDeviceID)) { NativeMethods.HDEVINFO devInfo = NativeMethods.SetupDiGetClassDevs( service.Uuid, serviceDeviceID, IntPtr.Zero, NativeMethods.DIGCF.DeviceInterface | NativeMethods.DIGCF.Present ); if (devInfo.IsValid) { try { NativeMethods.SP_DEVINFO_DATA dvi = new NativeMethods.SP_DEVINFO_DATA(); dvi.Size = Marshal.SizeOf(dvi); for (int j = 0; NativeMethods.SetupDiEnumDeviceInfo(devInfo, j, ref dvi); j++) { NativeMethods.SP_DEVICE_INTERFACE_DATA did = new NativeMethods.SP_DEVICE_INTERFACE_DATA(); did.Size = Marshal.SizeOf(did); for (int k = 0; NativeMethods.SetupDiEnumDeviceInterfaces(devInfo, ref dvi, service.Uuid, k, ref did); k++) { string devicePath; if (NativeMethods.SetupDiGetDeviceInterfaceDevicePath(devInfo, ref did, out devicePath)) { // FIXME: Take the attribute handle into account as well. // Right now, if there are multiple services with the same GUID, we do not distinguish between them. return(devicePath); } } } } finally { NativeMethods.SetupDiDestroyDeviceInfoList(devInfo); } } } }while (0 == NativeMethods.CM_Get_Sibling(out devInst, devInst)); } } throw DeviceException.CreateIOException(this, string.Format("BLE service {0} not found.", service.Uuid)); }