/// <summary> /// Initialises the device. This must be called before events start triggering. If device is allready initialized does nothing. /// </summary> /// <exception cref="HIDDeviceException">Is thrown if something unexpected happend during initialization</exception> /// <exception cref="DeviceAllreadyInUseException">Is thrown if device is allready in use somewhere else.</exception> public virtual void EnsureIsInitialized() { if (IsInitialized) { return; } // Create the file from the device path handle = CreateFile(DevicePath, GENERIC_READ | GENERIC_WRITE, 0, IntPtr.Zero, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, IntPtr.Zero); if (handle != InvalidHandleValue) // if the open worked... { IntPtr lpData; if (HidD_GetPreparsedData(handle, out lpData)) // get windows to read the device data into an internal buffer { try { HidCaps oCaps; HidP_GetCaps(lpData, out oCaps); // extract the device capabilities from the internal buffer inputReportLength = oCaps.InputReportByteLength; // get the input... outputReportLength = oCaps.OutputReportByteLength; // ... and output report lengths file = new FileStream(new SafeFileHandle(handle, false), FileAccess.Read | FileAccess.Write, inputReportLength, true); IsInitialized = true; BeginAsyncRead(); // kick off the first asynchronous read } catch (Exception) { throw HIDDeviceException.GenerateWithWinError("Failed to get the detailed data from the hid."); } finally { HidD_FreePreparsedData(ref lpData); // before we quit the funtion, we must free the internal buffer reserved in GetPreparsedData } } else // GetPreparsedData failed? Chuck an exception { throw HIDDeviceException.GenerateWithWinError("GetPreparsedData failed"); } } else // File open failed? Chuck an exception { handle = IntPtr.Zero; throw new DeviceAllreadyInUseException("Device you tried to initilized is allready in use."); } }
/// <summary> /// Finds devices of type. /// </summary> /// <typeparam name="TDevice">Type of device to look for.</typeparam> /// <returns>Enumeration of devices.</returns> public static IEnumerable <DeviceDescription <TDevice> > FindDevices <TDevice>() where TDevice : HIDDevice { var devices = new List <DeviceDescription <TDevice> >(); //Creating instance to get Vendor and product id's. var instance = (TDevice)Activator.CreateInstance(typeof(TDevice), new[] { "" }); var strSearch = string.Format("vid_{0:x4}&pid_{1:x4}", instance.VendorId, instance.ProductId); // first, build the path search string var gHid = HIDGuid; //HidD_GetHidGuid(out gHid); // next, get the GUID from Windows that it uses to represent the HID USB interface var hInfoSet = SetupDiGetClassDevs(ref gHid, null, IntPtr.Zero, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); // this gets a list of all HID devices currently connected to the computer (InfoSet) try { var oInterface = new DeviceInterfaceData(); // build up a device interface data block oInterface.Size = Marshal.SizeOf(oInterface); // Now iterate through the InfoSet memory block assigned within Windows in the call to SetupDiGetClassDevs // to get device details for each device connected var nIndex = 0; while (SetupDiEnumDeviceInterfaces(hInfoSet, 0, ref gHid, (uint)nIndex, ref oInterface)) // this gets the device interface information for a device at index 'nIndex' in the memory block { string strDevicePath = GetDevicePath(hInfoSet, ref oInterface); // get the device path (see helper method 'GetDevicePath') if (strDevicePath.IndexOf(strSearch) >= 0) // do a string search, if we find the VID/PID string then we found our device! { // Creating instance and adding device path as constructor parameter. var oNewDevice = (DeviceDescription <TDevice>)Activator.CreateInstance(typeof(DeviceDescription <TDevice>), new[] { strDevicePath }); devices.Add(oNewDevice); } nIndex++; // if we get here, we didn't find our device. So move on to the next one. } } catch (Exception ex) { throw HIDDeviceException.GenerateError(ex.ToString()); } finally { // Before we go, we have to free up the InfoSet memory reserved by SetupDiGetClassDevs SetupDiDestroyDeviceInfoList(hInfoSet); } return(devices); }