Beispiel #1
0
    public static InterfaceDetails[] getConnectedDevices()
    {
        InterfaceDetails[] devices = new InterfaceDetails[0];

        //Create structs to hold interface information
        SP_DEVINFO_DATA          devInfo  = new SP_DEVINFO_DATA();
        SP_DEVICE_INTERFACE_DATA devIface = new SP_DEVICE_INTERFACE_DATA();

        devInfo.cbSize  = (uint)Marshal.SizeOf(devInfo);
        devIface.cbSize = (uint)(Marshal.SizeOf(devIface));

        Guid G = new Guid();

        HID.HidD_GetHidGuid(ref G); //Get the guid of the HID device class

        IntPtr i = SetupAPI.SetupDiGetClassDevs(ref G, IntPtr.Zero, IntPtr.Zero, SetupAPI.DIGCF_DEVICEINTERFACE | SetupAPI.DIGCF_PRESENT);

        //Loop through all available entries in the device list, until false
        SP_DEVICE_INTERFACE_DETAIL_DATA didd = new SP_DEVICE_INTERFACE_DETAIL_DATA();

        if (IntPtr.Size == 8) // for 64 bit operating systems
        {
            didd.cbSize = 8;
        }
        else
        {
            didd.cbSize = 4 + Marshal.SystemDefaultCharSize;             // for 32 bit systems
        }

        int            j = -1;
        bool           b = true;
        SafeFileHandle tempHandle;

        while (b)
        {
            ++j;
            b = SetupAPI.SetupDiEnumDeviceInterfaces(i, IntPtr.Zero, ref G, (uint)j, ref devIface);
            if (b == false)
            {
                break;
            }

            uint requiredSize = 0;
            SetupAPI.SetupDiGetDeviceInterfaceDetail(i, ref devIface, ref didd, 256, out requiredSize, ref devInfo);
            string devicePath = didd.DevicePath;

            //create file handles using CT_CreateFile
            tempHandle = Kernel32.CreateFile(devicePath, Kernel32.GENERIC_READ | Kernel32.GENERIC_WRITE, Kernel32.FILE_SHARE_READ | Kernel32.FILE_SHARE_WRITE,
                                             IntPtr.Zero, Kernel32.OPEN_EXISTING, 0, IntPtr.Zero);

            //get capabilites - use getPreParsedData, and getCaps
            //store the reportlengths
            IntPtr ptrToPreParsedData = new IntPtr();
            bool   ppdSucsess         = HID.HidD_GetPreparsedData(tempHandle, ref ptrToPreParsedData);
            if (ppdSucsess == false)
            {
                continue;
            }

            HIDP_CAPS capabilities = new HIDP_CAPS();
            HID.HidP_GetCaps(ptrToPreParsedData, ref capabilities);

            HIDD_ATTRIBUTES attributes = new HIDD_ATTRIBUTES();
            HID.HidD_GetAttributes(tempHandle, ref attributes);

            string productName = "";
            string SN          = "";
            string manfString  = "";
            IntPtr buffer      = Marshal.AllocHGlobal(126);//max alloc for string;
            if (HID.HidD_GetProductString(tempHandle, buffer, 126))
            {
                productName = Marshal.PtrToStringAuto(buffer);
            }
            if (HID.HidD_GetSerialNumberString(tempHandle, buffer, 126))
            {
                SN = Marshal.PtrToStringAuto(buffer);
            }
            if (HID.HidD_GetManufacturerString(tempHandle, buffer, 126))
            {
                manfString = Marshal.PtrToStringAuto(buffer);
            }
            Marshal.FreeHGlobal(buffer);

            //Call freePreParsedData to release some stuff
            HID.HidD_FreePreparsedData(ref ptrToPreParsedData);

            //If connection was sucsessful, record the values in a global struct
            InterfaceDetails productInfo = new InterfaceDetails();
            productInfo.devicePath           = devicePath;
            productInfo.manufacturer         = manfString;
            productInfo.product              = productName;
            productInfo.PID                  = (ushort)attributes.ProductID;
            productInfo.VID                  = (ushort)attributes.VendorID;
            productInfo.versionNumber        = (ushort)attributes.VersionNumber;
            productInfo.IN_reportByteLength  = (int)capabilities.InputReportByteLength;
            productInfo.OUT_reportByteLength = (int)capabilities.OutputReportByteLength;
            productInfo.serialNumber         = SN; //Check that serial number is actually a number

            int newSize = devices.Length + 1;
            Array.Resize(ref devices, newSize);
            devices[newSize - 1] = productInfo;
        }
        SetupAPI.SetupDiDestroyDeviceInfoList(i);

        return(devices);
    }
Beispiel #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);
            }
        }
Beispiel #3
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);
            }
        }
    public static InterfaceDetails[] getConnectedDevices()
    {
        InterfaceDetails[] devices = new InterfaceDetails[0];

        //Create structs to hold interface information
        SP_DEVINFO_DATA devInfo = new SP_DEVINFO_DATA();

        devInfo.cbSize = (uint)Marshal.SizeOf(devInfo);
        SP_DEVICE_INTERFACE_DATA devIface = new SP_DEVICE_INTERFACE_DATA();

        devIface.cbSize = (uint)(Marshal.SizeOf(devIface));

        Guid G = Guid.Empty;

        HID.HidD_GetHidGuid(ref G); //Get the guid of the HID device class

        IntPtr deviceInfo = SetupAPI.SetupDiGetClassDevs(ref G, IntPtr.Zero, IntPtr.Zero, SetupAPI.DIGCF_DEVICEINTERFACE | SetupAPI.DIGCF_PRESENT);
        //Loop through all available entries in the device list, until false
        int j = 0;

        while (true)
        {
            if (!SetupAPI.SetupDiEnumDeviceInterfaces(deviceInfo, IntPtr.Zero, ref G, (uint)j, ref devIface))
            {
                break;
            }
            uint   requiredSize = 0;
            IntPtr detailMemory = Marshal.AllocHGlobal((int)requiredSize);
            SP_DEVICE_INTERFACE_DETAIL_DATA functionClassDeviceData = (SP_DEVICE_INTERFACE_DETAIL_DATA)Marshal.PtrToStructure(detailMemory, Typeof <SP_DEVICE_INTERFACE_DETAIL_DATA>());
            functionClassDeviceData.cbSize = Marshal.SizeOf(functionClassDeviceData);
            if (!SetupAPI.SetupDiGetDeviceInterfaceDetail(deviceInfo, ref devIface, ref functionClassDeviceData, requiredSize, out requiredSize, ref devInfo))
            {
                Marshal.FreeHGlobal(detailMemory);
                break;
            }
            string devicePath = functionClassDeviceData.DevicePath;
            Marshal.FreeHGlobal(detailMemory);

            //create file handles using CT_CreateFile
            uint           desiredAccess = Kernel32.GENERIC_READ | Kernel32.GENERIC_WRITE;
            uint           shareMode     = Kernel32.FILE_SHARE_READ | Kernel32.FILE_SHARE_WRITE;
            SafeFileHandle tempHandle    = Kernel32.CreateFile(devicePath, desiredAccess, shareMode,
                                                               IntPtr.Zero, Kernel32.OPEN_EXISTING, 0, IntPtr.Zero);
            //get capabilites - use getPreParsedData, and getCaps
            //store the reportlengths
            IntPtr ptrToPreParsedData = new IntPtr();
            bool   ppdSucsess         = HID.HidD_GetPreparsedData(tempHandle, ref ptrToPreParsedData);
            if (!ppdSucsess)
            {
                continue;
            }

            HIDP_CAPS capability = new HIDP_CAPS();
            HID.HidP_GetCaps(ptrToPreParsedData, ref capability);

            HIDD_ATTRIBUTES attributes = new HIDD_ATTRIBUTES();
            HID.HidD_GetAttributes(tempHandle, ref attributes);

            string    productName = EMPTY;
            string    SN          = EMPTY;
            string    manfString  = EMPTY;
            const int bufferLen   = 128;
            IntPtr    buffer      = Marshal.AllocHGlobal(bufferLen);
            if (HID.HidD_GetProductString(tempHandle, buffer, bufferLen))
            {
                productName = Marshal.PtrToStringAuto(buffer);
            }
            if (HID.HidD_GetSerialNumberString(tempHandle, buffer, bufferLen))
            {
                SN = Marshal.PtrToStringAuto(buffer);
            }
            if (HID.HidD_GetManufacturerString(tempHandle, buffer, bufferLen))
            {
                manfString = Marshal.PtrToStringAuto(buffer);
            }
            Marshal.FreeHGlobal(buffer);

            //Call freePreParsedData to release some stuff
            HID.HidD_FreePreparsedData(ref ptrToPreParsedData);

            //If connection was sucsessful, record the values in a global struct
            InterfaceDetails productInfo = new InterfaceDetails();
            productInfo.devicePath           = devicePath;
            productInfo.manufacturer         = manfString;
            productInfo.product              = productName;
            productInfo.PID                  = (ushort)attributes.ProductID;
            productInfo.VID                  = (ushort)attributes.VendorID;
            productInfo.versionNumber        = (ushort)attributes.VersionNumber;
            productInfo.IN_reportByteLength  = capability.InputReportByteLength;
            productInfo.OUT_reportByteLength = capability.OutputReportByteLength;
            productInfo.serialNumber         = SN; //Check that serial number is actually a number

            int newSize = devices.Length + 1;
            Array.Resize(ref devices, newSize);
            devices[newSize - 1] = productInfo;
            ++j;
        }
        SetupAPI.SetupDiDestroyDeviceInfoList(deviceInfo);
        return(devices);
    }