/// <summary>
        /// Gets a list of devices that match the filter criteria.
        /// </summary>
        /// <param name="deviceFilter">The device filter.</param>
        /// <returns>An array of DeviceInformation objects.</returns>
        public static DeviceInformation[] GetDevices(DeviceFilter deviceFilter)
        {
            List <DeviceInformation> result = new List <DeviceInformation>();

            Guid emptyGuid = Guid.Empty;

            int filter;

            if (deviceFilter == DeviceFilter.AllDevices || deviceFilter == DeviceFilter.AllPciDevices)
            {
                filter = (int)DIGCF.DIGCF_ALLCLASSES;
            }
            else
            {
                filter = (int)DIGCF.DIGCF_ALLCLASSES | (int)DIGCF.DIGCF_PRESENT;
            }

            IntPtr deviceInfoSet =
                Win32SetupApi.SetupDiGetClassDevs(
                    ref emptyGuid,
                    IntPtr.Zero,
                    IntPtr.Zero,
                    filter);

            SP_DEVINFO_DATA deviceInfoData =
                new SP_DEVINFO_DATA();

            deviceInfoData.Size = Marshal.SizeOf(typeof(SP_DEVINFO_DATA));

            for (int i = 0; Win32SetupApi.SetupDiEnumDeviceInfo(deviceInfoSet, i, ref deviceInfoData); i++)
            {
                DeviceInformation deviceInformation =
                    GetDeviceInformation(deviceInfoSet, deviceInfoData);

                switch (deviceFilter)
                {
                case DeviceFilter.PresentPciDevices:
                case DeviceFilter.AllPciDevices:
                    if (!deviceInformation.LocationInfo
                        .ToLowerInvariant().Contains("pci"))
                    {
                        continue; // relates to the for-loop
                    }
                    else
                    {
                        break; // relates to the switch
                    }

                case DeviceFilter.AllDevices:
                default:
                    break;
                }

                result.Add(deviceInformation);
            }

            Win32SetupApi.SetupDiDestroyDeviceInfoList(deviceInfoSet);

            return(result.ToArray());
        }
        /// <summary>
        /// Gets a device handle from matching.
        /// </summary>
        /// <param name="deviceInformation">The device information.</param>
        /// <param name="deviceInfoSet">The device info set.</param>
        /// <param name="deviceInfoData">The device info data.</param>
        private static void GetDeviceHandleFromMatch(
            DeviceInformation deviceInformation,
            out IntPtr deviceInfoSet,
            out SP_DEVINFO_DATA deviceInfoData)
        {
            Guid emptyGuid = Guid.Empty;

            deviceInfoSet = Win32SetupApi.SetupDiGetClassDevs(
                ref emptyGuid,
                IntPtr.Zero,
                IntPtr.Zero,
                (int)DIGCF.DIGCF_PRESENT | (int)DIGCF.DIGCF_ALLCLASSES);

            deviceInfoData      = new SP_DEVINFO_DATA();
            deviceInfoData.Size = Marshal.SizeOf(typeof(SP_DEVINFO_DATA));

            for (int i = 0; Win32SetupApi.SetupDiEnumDeviceInfo(deviceInfoSet, i, ref deviceInfoData); i++)
            {
                String matchSubjectDesc        = GetDescription(deviceInfoSet, deviceInfoData);
                String matchSubjectPhysDevName = GetPhysicalDeviceObjectName(deviceInfoSet, deviceInfoData);
                int    matchSubjectBus         = GetBusNumber(deviceInfoSet, deviceInfoData);

                if (
                    deviceInformation.Description.Equals(matchSubjectDesc) &&
                    deviceInformation.BusNumber.Equals(matchSubjectBus) &&
                    deviceInformation.PhysicalDeviceObjectName.Equals(matchSubjectPhysDevName))
                {
                    return;
                }
            }

            deviceInfoData = new SP_DEVINFO_DATA();
            deviceInfoSet  = IntPtr.Zero;
        }