示例#1
0
        /// <summary>
        /// Scans the computer for any USB devices matching th specified VID/PID DeviceID.
        /// Throws an exception if none are found
        /// </summary>
        public void Connect()
        {
            var deviceInterfaceDetailData = new SetupAPI.SP_DEVICE_INTERFACE_DETAIL_DATA();
            var deviceInterfaceData       = new SetupAPI.SP_DEVICE_INTERFACE_DATA();
            var deviceInfoData            = new SetupAPI.SP_DEVINFO_DATA();

            UInt32 interfaceIndex = 0;
            UInt32 dwRegType;
            UInt32 dwRegSize;
            UInt32 structureSize = 0;
            bool   matchFound    = false;

            //First populate a list of plugged in devices (by specifying "DIGCF_PRESENT"), which are of the specified class GUID.
            IntPtr pDeviceInfoTable = SetupAPI.SetupDiGetClassDevs(
                ref InterfaceClassGuid,
                null,
                IntPtr.Zero,
                SetupAPI.DIGCF_PRESENT | SetupAPI.DIGCF_DEVICEINTERFACE
                );

            try
            {
                //Now look through the list we just populated.  We are trying to see if any of them match our device.
                while (true)
                {
                    deviceInterfaceData.cbSize = (UInt32)Marshal.SizeOf(typeof(SetupAPI.SP_DEVICE_INTERFACE_DATA));

                    if (!SetupAPI.SetupDiEnumDeviceInterfaces(pDeviceInfoTable, IntPtr.Zero, ref InterfaceClassGuid, interfaceIndex, ref deviceInterfaceData))
                    {
                        int error = Marshal.GetLastWin32Error();
                        if (error == SetupAPI.ERROR_NO_MORE_ITEMS)
                        {
                            throw new HidDeviceException(String.Format("No HID devices found matching {0}", this.DeviceId));
                        }
                        else
                        {
                            throw new Win32Exception(error);
                        }
                    }

                    //Now retrieve the hardware ID from the registry.  The hardware ID contains the VID and PID, which we will then
                    //check to see if it is the correct device or not.

                    //Initialize an appropriate SP_DEVINFO_DATA structure.  We need this structure for SetupDiGetDeviceRegistryProperty().
                    deviceInfoData.cbSize = (UInt32)Marshal.SizeOf(typeof(SetupAPI.SP_DEVINFO_DATA));
                    if (!SetupAPI.SetupDiEnumDeviceInfo(pDeviceInfoTable, interfaceIndex, ref deviceInfoData))
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }

                    //Retrieve the hardware IDs for the current device we are looking at.  PropertyValueBuffer gets filled with a
                    //REG_MULTI_SZ (array of null terminated strings).  To find a device, we only care about the very first string in the
                    //buffer, which will be the "device ID".  The device ID is a string which contains the VID and PID, in the example
                    //format "Vid_04d8&Pid_003f".
                    String deviceIdFromRegistry = SetupAPI.SetupDiGetDeviceRegistryProperty(pDeviceInfoTable, ref deviceInfoData, SetupAPI.SPDRP_HARDWAREID);
                    if (deviceIdFromRegistry == null)
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }

                    //Now check if the first string in the hardware ID matches the device ID of my USB device.

                    //Convert both strings to lower case.  This makes the code more robust/portable across OS Versions
                    deviceIdFromRegistry = deviceIdFromRegistry.ToLowerInvariant();
                    var deviceIdToFind = this.DeviceId.ToLowerInvariant();

                    //Now check if the hardware ID we are looking at contains the correct VID/PID
                    matchFound = deviceIdFromRegistry.Contains(deviceIdToFind);
                    if (matchFound == true)
                    {
                        //Device must have been found.  (Goal: Open read and write handles)  In order to do this, we will need the actual device path first.
                        //We can get the path by calling SetupDiGetDeviceInterfaceDetail(), however, we have to call this function twice:  The first
                        //time to get the size of the required structure/buffer to hold the detailed interface data, then a second time to actually
                        //get the structure (after we have allocated enough memory for the structure.)
                        deviceInterfaceDetailData = new SetupAPI.SP_DEVICE_INTERFACE_DETAIL_DATA();

                        if (IntPtr.Size == 8) // for 64 bit operating systems
                        {
                            deviceInterfaceDetailData.cbSize = 8;
                        }
                        else
                        {
                            deviceInterfaceDetailData.cbSize = (UInt32)(4 + Marshal.SystemDefaultCharSize); // for 32 bit systems
                        }
                        UInt32 bufferSize = 1000;
                        if (!SetupAPI.SetupDiGetDeviceInterfaceDetail(pDeviceInfoTable, ref deviceInterfaceData, ref deviceInterfaceDetailData, bufferSize, out structureSize, ref deviceInfoData))
                        {
                            throw new Win32Exception(Marshal.GetLastWin32Error());
                        }

                        // Finally set the devicePath
                        this.DevicePath = deviceInterfaceDetailData.DevicePath;

                        // Also get the device description
                        this.DeviceDescription = SetupAPI.SetupDiGetDeviceRegistryProperty(pDeviceInfoTable, ref deviceInfoData, SetupAPI.SPDRP_FRIENDLYNAME);
                        if (this.DeviceDescription == null)
                        {
                            this.DeviceDescription = SetupAPI.SetupDiGetDeviceRegistryProperty(pDeviceInfoTable, ref deviceInfoData, SetupAPI.SPDRP_DEVICEDESC);
                        }
                        return;
                    }

                    interfaceIndex++;
                    if (interfaceIndex == 10000000)                     //Surely there aren't more than 10 million interfaces attached to a single PC.
                    {
                        //If execution gets to here, it is probably safe to assume some kind of unanticipated problem occurred.
                        //In this case, bug out, to avoid infinite blocking while(true) loop.
                        throw new Exception("Unknown Error in HidDevice.Open()");
                    }

                    //Keep looping until we either find a device with matching VID and PID, or until we run out of items, or some error is encountered.
                }
            }
            finally
            {
                //Clean up the old structure we no longer need.
                SetupAPI.SetupDiDestroyDeviceInfoList(pDeviceInfoTable);
            }
        }
示例#2
0
        /// <summary>
        /// Modifies the device registry entry to use the specified name
        /// in the windows device manager.
        /// REQUIRES ADMINISTRATOR PRIVILEGE
        /// </summary>
        /// <param name="name">The name to display in the windows device manager</param>
        public void SetFriendlyName(string name)
        {
            WindowsIdentity  identity  = WindowsIdentity.GetCurrent();
            WindowsPrincipal principal = new WindowsPrincipal(identity);

            if (!principal.IsInRole(WindowsBuiltInRole.Administrator))
            {
                throw new Exception("This function requires administrator privileges");
            }

            var deviceInterfaceData = new SetupAPI.SP_DEVICE_INTERFACE_DATA();
            var deviceInfoData      = new SetupAPI.SP_DEVINFO_DATA();

            UInt32 interfaceIndex = 0;

            // Populate a list of plugged in devices (by specifying "DIGCF_PRESENT"), which are of the specified class GUID.
            IntPtr pDeviceInfoTable = SetupAPI.SetupDiGetClassDevs(
                ref InterfaceClassGuid,
                null,
                IntPtr.Zero,
                SetupAPI.DIGCF_PRESENT | SetupAPI.DIGCF_DEVICEINTERFACE
                );

            try
            {
                while (true)
                {
                    deviceInterfaceData.cbSize = (UInt32)Marshal.SizeOf(typeof(SetupAPI.SP_DEVICE_INTERFACE_DATA));

                    if (!SetupAPI.SetupDiEnumDeviceInterfaces(pDeviceInfoTable, IntPtr.Zero, ref InterfaceClassGuid, interfaceIndex, ref deviceInterfaceData))
                    {
                        int error = Marshal.GetLastWin32Error();
                        if (error == SetupAPI.ERROR_NO_MORE_ITEMS)
                        {
                            return;
                        }
                        else
                        {
                            throw new Win32Exception(error);
                        }
                    }

                    //Initialize an appropriate SP_DEVINFO_DATA structure.  We need this structure for SetupDiGetDeviceRegistryProperty().
                    deviceInfoData.cbSize = (UInt32)Marshal.SizeOf(typeof(SetupAPI.SP_DEVINFO_DATA));
                    if (!SetupAPI.SetupDiEnumDeviceInfo(pDeviceInfoTable, interfaceIndex, ref deviceInfoData))
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }

                    String deviceIdFromRegistry = SetupAPI.SetupDiGetDeviceRegistryProperty(pDeviceInfoTable, ref deviceInfoData, SetupAPI.SPDRP_HARDWAREID);
                    if (deviceIdFromRegistry != null)
                    {
                        deviceIdFromRegistry = deviceIdFromRegistry.ToLowerInvariant();;
                        String deviceIdToFind = this.DeviceId.ToLowerInvariant();

                        if (deviceIdFromRegistry.Contains(deviceIdToFind))
                        {
                            // Set the friendly name that's displayed in the device manager
                            SetupAPI.SetupDiSetDeviceRegistryProperty(pDeviceInfoTable, ref deviceInfoData, SetupAPI.SPDRP_FRIENDLYNAME, name);

                            this.DeviceDescription = SetupAPI.SetupDiGetDeviceRegistryProperty(pDeviceInfoTable, ref deviceInfoData, SetupAPI.SPDRP_FRIENDLYNAME);
                            if (this.DeviceDescription == null)
                            {
                                this.DeviceDescription = SetupAPI.SetupDiGetDeviceRegistryProperty(pDeviceInfoTable, ref deviceInfoData, SetupAPI.SPDRP_DEVICEDESC);
                            }
                        }
                    }


                    interfaceIndex++;
                    if (interfaceIndex == 10000000)     //Surely there aren't more than 10 million interfaces attached to a single PC.
                    {
                        return;
                    }
                }
            }
            finally
            {
                //Clean up the old structure we no longer need.
                SetupAPI.SetupDiDestroyDeviceInfoList(pDeviceInfoTable);
            }
        }