C# Checking for Cameras and Disabling them

Software Code to enable and disable Hardware Camera’s



using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
using System.Text;
namespace CSharpTestCode
{
    class DisableHardware
    {
        static DisableHardware()
        {
            DisableHardware.DEVPKEY_Device_DeviceDesc = new DEVPROPKEY();
            DEVPKEY_Device_DeviceDesc.fmtid = new Guid(
                    0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67,
                    0xd1, 0x46, 0xa8, 0x50, 0xe0);
            DEVPKEY_Device_DeviceDesc.pid = 2;
            DEVPKEY_Device_HardwareIds = new DEVPROPKEY();
            DEVPKEY_Device_HardwareIds.fmtid = new Guid(
                0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67,
                0xd1, 0x46, 0xa8, 0x50, 0xe0);
            DEVPKEY_Device_HardwareIds.pid = 3;
        }
        const uint DIF_PROPERTYCHANGE = 0x12;
        const uint DICS_ENABLE = 1;
        const uint DICS_DISABLE = 2;  // disable device
        const uint DICS_FLAG_GLOBAL = 1; // not profile-specific
        const uint DIGCF_ALLCLASSES = 4;
        const uint DIGCF_PRESENT = 2;
        const uint ERROR_INVALID_DATA = 13;
        const uint ERROR_NO_MORE_ITEMS = 259;
        const uint ERROR_ELEMENT_NOT_FOUND = 1168;
        static DEVPROPKEY DEVPKEY_Device_DeviceDesc;
        static DEVPROPKEY DEVPKEY_Device_HardwareIds;
        [StructLayout(LayoutKind.Sequential)]
        struct SP_CLASSINSTALL_HEADER
        {
            public UInt32 cbSize;
            public UInt32 InstallFunction;
        }
        [StructLayout(LayoutKind.Sequential)]
        struct SP_PROPCHANGE_PARAMS
        {
            public SP_CLASSINSTALL_HEADER ClassInstallHeader;
            public UInt32 StateChange;
            public UInt32 Scope;
            public UInt32 HwProfile;
        }
        [StructLayout(LayoutKind.Sequential)]
        struct DEVPROPKEY
        {
            public Guid fmtid;
            public UInt32 pid;
        }
        [DllImport("setupapi.dll", SetLastError = true)]
        static extern IntPtr SetupDiGetClassDevsW(
            [In] ref Guid ClassGuid,
            [MarshalAs(UnmanagedType.LPWStr)]
            string Enumerator,
            IntPtr parent,
            UInt32 flags);
        [DllImport("setupapi.dll", SetLastError = true)]
        static extern bool SetupDiDestroyDeviceInfoList(IntPtr handle);
        [DllImport("setupapi.dll", SetLastError = true)]
        static extern bool SetupDiEnumDeviceInfo(IntPtr deviceInfoSet,
            UInt32 memberIndex,
            [Out] out SP_DEVINFO_DATA deviceInfoData);
        [DllImport("setupapi.dll", SetLastError = true)]
        static extern bool SetupDiSetClassInstallParams(
            IntPtr deviceInfoSet,
            [In] ref SP_DEVINFO_DATA deviceInfoData,
            [In] ref SP_PROPCHANGE_PARAMS classInstallParams,
            UInt32 ClassInstallParamsSize);
        [DllImport("setupapi.dll", SetLastError = true)]
        static extern bool SetupDiChangeState(
            IntPtr deviceInfoSet,
            [In] ref SP_DEVINFO_DATA deviceInfoData);
        [DllImport("setupapi.dll", SetLastError = true)]
        static extern bool SetupDiGetDevicePropertyW(
                IntPtr deviceInfoSet,
                [In] ref SP_DEVINFO_DATA DeviceInfoData,
                [In] ref DEVPROPKEY propertyKey,
                [Out] out UInt32 propertyType,
                IntPtr propertyBuffer,
                UInt32 propertyBufferSize,
                out UInt32 requiredSize,
                UInt32 flags);
        [DllImport("setupapi.dll", SetLastError = true)]
        static extern bool SetupDiGetDeviceRegistryPropertyW(
          IntPtr DeviceInfoSet,
          [In] ref SP_DEVINFO_DATA DeviceInfoData,
          UInt32 Property,
          [Out] out UInt32 PropertyRegDataType,
          IntPtr PropertyBuffer,
          UInt32 PropertyBufferSize,
          [Out] out UInt32 RequiredSize
        );
        [DllImport("shell32")]
        static extern bool IsUserAnAdmin();
        enum SetupDiGetDeviceRegistryPropertyEnum : uint
        {
            SPDRP_DEVICEDESC = 0x00000000, // DeviceDesc (R/W)
            SPDRP_HARDWAREID = 0x00000001, // HardwareID (R/W)
            SPDRP_COMPATIBLEIDS = 0x00000002, // CompatibleIDs (R/W)
            SPDRP_UNUSED0 = 0x00000003, // unused
            SPDRP_SERVICE = 0x00000004, // Service (R/W)
            SPDRP_UNUSED1 = 0x00000005, // unused
            SPDRP_UNUSED2 = 0x00000006, // unused
            SPDRP_CLASS = 0x00000007, // Class (R--tied to ClassGUID)
            SPDRP_CLASSGUID = 0x00000008, // ClassGUID (R/W)
            SPDRP_DRIVER = 0x00000009, // Driver (R/W)
            SPDRP_CONFIGFLAGS = 0x0000000A, // ConfigFlags (R/W)
            SPDRP_MFG = 0x0000000B, // Mfg (R/W)
            SPDRP_FRIENDLYNAME = 0x0000000C, // FriendlyName (R/W)
            SPDRP_LOCATION_INFORMATION = 0x0000000D, // LocationInformation (R/W)
            SPDRP_PHYSICAL_DEVICE_OBJECT_NAME = 0x0000000E, // PhysicalDeviceObjectName (R)
            SPDRP_CAPABILITIES = 0x0000000F, // Capabilities (R)
            SPDRP_UI_NUMBER = 0x00000010, // UiNumber (R)
            SPDRP_UPPERFILTERS = 0x00000011, // UpperFilters (R/W)
            SPDRP_LOWERFILTERS = 0x00000012, // LowerFilters (R/W)
            SPDRP_BUSTYPEGUID = 0x00000013, // BusTypeGUID (R)
            SPDRP_LEGACYBUSTYPE = 0x00000014, // LegacyBusType (R)
            SPDRP_BUSNUMBER = 0x00000015, // BusNumber (R)
            SPDRP_ENUMERATOR_NAME = 0x00000016, // Enumerator Name (R)
            SPDRP_SECURITY = 0x00000017, // Security (R/W, binary form)
            SPDRP_SECURITY_SDS = 0x00000018, // Security (W, SDS form)
            SPDRP_DEVTYPE = 0x00000019, // Device Type (R/W)
            SPDRP_EXCLUSIVE = 0x0000001A, // Device is exclusive-access (R/W)
            SPDRP_CHARACTERISTICS = 0x0000001B, // Device Characteristics (R/W)
            SPDRP_ADDRESS = 0x0000001C, // Device Address (R)
            SPDRP_UI_NUMBER_DESC_FORMAT = 0X0000001D, // UiNumberDescFormat (R/W)
            SPDRP_DEVICE_POWER_DATA = 0x0000001E, // Device Power Data (R)
            SPDRP_REMOVAL_POLICY = 0x0000001F, // Removal Policy (R)
            SPDRP_REMOVAL_POLICY_HW_DEFAULT = 0x00000020, // Hardware Removal Policy (R)
            SPDRP_REMOVAL_POLICY_OVERRIDE = 0x00000021, // Removal Policy Override (RW)
            SPDRP_INSTALL_STATE = 0x00000022, // Device Install State (R)
            SPDRP_LOCATION_PATHS = 0x00000023, // Device Location Paths (R)
            SPDRP_BASE_CONTAINERID = 0x00000024  // Base ContainerID (R)
        }
        //https://stackoverflow.com/questions/45045670/reliably-know-if-a-volume-is-removable-or-not-with-winapi
        [DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SetupDiGetDeviceRegistryProperty(IntPtr deviceInfoSet, ref SP_DEVINFO_DATA deviceInfoData, uint property, out UInt32 propertyRegDataType, byte[] propertyBuffer, uint propertyBufferSize, out UInt32 requiredSize);
        [DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SetupDiGetDeviceRegistryProperty(IntPtr deviceInfoSet, ref SP_DEVINFO_DATA deviceInfoData, uint property, IntPtr propertyRegDataType, byte[] propertyBuffer, uint propertyBufferSize, out UInt32 requiredSize);
        public enum RegType : uint
        {
            REG_BINARY = 3,
            REG_DWORD = 4,
            REG_EXPAND_SZ = 2,
            REG_MULTI_SZ = 7,
            REG_SZ = 1
        }
        const int BUFFER_SIZE = 1024;
        static string getStringProp(IntPtr h, SP_DEVINFO_DATA da, SetupDiGetDeviceRegistryPropertyEnum prop)
        {
            UInt32 requiredSize;
            UInt32 regType;
            byte[] ptrBuf = new byte[BUFFER_SIZE];
            if (!SetupDiGetDeviceRegistryProperty(h, ref da, (uint)prop, out regType, ptrBuf, BUFFER_SIZE, out requiredSize))
                throw new InvalidOperationException("Error getting string property");
            if (regType != (uint)RegType.REG_SZ || (requiredSize & 1) != 0)
                throw new InvalidOperationException("Property is not a REG_SZ");
            if (requiredSize == 0)
                return "";
            return Encoding.Unicode.GetString(ptrBuf, 0, (int)requiredSize - 2);
        }
        static uint getDWORDProp(IntPtr h, SP_DEVINFO_DATA da, SetupDiGetDeviceRegistryPropertyEnum prop)
        {
            UInt32 requiredSize;
            UInt32 regType;
            byte[] ptrBuf = new byte[4];
            if (!SetupDiGetDeviceRegistryProperty(h, ref da, (uint)prop, out regType, ptrBuf, 4, out requiredSize))
                throw new InvalidOperationException("Error getting DWORD property");
            if (regType != (uint)RegType.REG_DWORD || requiredSize != 4)
                throw new InvalidOperationException("Property is not a REG_DWORD");
            return BitConverter.ToUInt32(ptrBuf, 0);
        }
        [Flags]
        public enum DiGetClassFlags : uint
        {
            DIGCF_DEFAULT = 0x00000001, // only valid with DIGCF_DEVICEINTERFACE
            DIGCF_PRESENT = 0x00000002,
            DIGCF_ALLCLASSES = 0x00000004,
            DIGCF_PROFILE = 0x00000008,
            DIGCF_DEVICEINTERFACE = 0x00000010,
        }
        [Flags]
        enum DEVPROPTYPE : ulong
        {
            DEVPROP_TYPEMOD_ARRAY = 0x00001000,
            DEVPROP_TYPEMOD_LIST = 0x00002000,
            DEVPROP_TYPE_EMPTY = 0x00000000,  // nothing, no property data
            DEVPROP_TYPE_NULL = 0x00000001,  // null property data
            DEVPROP_TYPE_SBYTE = 0x00000002,  // 8-bit signed int (SBYTE)
            DEVPROP_TYPE_BYTE = 0x00000003,  // 8-bit unsigned int (BYTE)
            DEVPROP_TYPE_INT16 = 0x00000004,  // 16-bit signed int (SHORT)
            DEVPROP_TYPE_UINT16 = 0x00000005,  // 16-bit unsigned int (USHORT)
            DEVPROP_TYPE_INT32 = 0x00000006,  // 32-bit signed int (LONG)
            DEVPROP_TYPE_UINT32 = 0x00000007,  // 32-bit unsigned int (ULONG)
            DEVPROP_TYPE_INT64 = 0x00000008,  // 64-bit signed int (LONG64)
            DEVPROP_TYPE_UINT64 = 0x00000009,  // 64-bit unsigned int (ULONG64)
            DEVPROP_TYPE_FLOAT = 0x0000000A,  // 32-bit floating-point (FLOAT)
            DEVPROP_TYPE_DOUBLE = 0x0000000B,  // 64-bit floating-point (DOUBLE)
            DEVPROP_TYPE_DECIMAL = 0x0000000C,  // 128-bit data (DECIMAL)
            DEVPROP_TYPE_GUID = 0x0000000D,  // 128-bit unique identifier (GUID)
            DEVPROP_TYPE_CURRENCY = 0x0000000E,  // 64 bit signed int currency value (CURRENCY)
            DEVPROP_TYPE_DATE = 0x0000000F,  // date (DATE)
            DEVPROP_TYPE_FILETIME = 0x00000010,  // filetime (FILETIME)
            DEVPROP_TYPE_BOOLEAN = 0x00000011,  // 8-bit boolean (DEVPROP_BOOLEAN)
            DEVPROP_TYPE_STRING = 0x00000012,  // null-terminated string
            DEVPROP_TYPE_STRING_LIST = (DEVPROP_TYPE_STRING | DEVPROP_TYPEMOD_LIST), // multi-sz string list
            DEVPROP_TYPE_SECURITY_DESCRIPTOR = 0x00000013,  // self-relative binary SECURITY_DESCRIPTOR
            DEVPROP_TYPE_SECURITY_DESCRIPTOR_STRING = 0x00000014,  // security descriptor string (SDDL format)
            DEVPROP_TYPE_DEVPROPKEY = 0x00000015,  // device property key (DEVPROPKEY)
            DEVPROP_TYPE_DEVPROPTYPE = 0x00000016,  // device property type (DEVPROPTYPE)
            DEVPROP_TYPE_BINARY = (DEVPROP_TYPE_BYTE | DEVPROP_TYPEMOD_ARRAY),  // custom binary data
            DEVPROP_TYPE_ERROR = 0x00000017,  // 32-bit Win32 system error code
            DEVPROP_TYPE_NTSTATUS = 0x00000018, // 32-bit NTSTATUS code
            DEVPROP_TYPE_STRING_INDIRECT = 0x00000019, // string resource (@[path\]<dllname>,-<strId>)
            MAX_DEVPROP_TYPE = 0x00000019,
            MAX_DEVPROP_TYPEMOD = 0x00002000,
            DEVPROP_MASK_TYPE = 0x00000FFF,
            DEVPROP_MASK_TYPEMOD = 0x0000F000
        }
        /*
        [DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern bool SetupDiEnumDeviceInfo([In] IntPtr hDevInfo, [In] uint memberIndex, [In, Out] ref SP_DEVINFO_DATA deviceInfoData);
         */
        [DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern bool SetupDiGetDeviceProperty([In] IntPtr hDevInfo, [In] ref SP_DEVINFO_DATA deviceInfoData, [In] ref DEVPROPKEY propertyKey, [In, Out] ref DEVPROPTYPE propertyType, [In, Out] byte[] propertyBuffer, [In] uint propertyBufferSize, [In, Out] ref uint requiredSize, [In] uint flags = 0);
        static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
        public const int CM_DEVCAP_HARDWAREDISABLED = 0x100;
        public const int DIGCF_DEVICEINTERFACE = 0x00000010;
        public const int ERROR_INSUFFICIENT_BUFFER = 122;
        //https://docs.microsoft.com/en-us/windows-hardware/drivers/install/system-defined-device-setup-classes-available-to-vendors
        public static Guid GUID_Camera_Device = new Guid("ca3e7ab9-b4c3-4ae6-8251-579ef933890f");
        public static Guid GUID_DEVCLASS_MOUSE = new Guid("4D36E96F-E325-11CE-BFC1-08002BE10318");
        public static Guid GUID_DEVINTERFACE_MOUSE = new Guid("378DE44C-56EF-11D1-BC8C-00A0C91405DD");
        public static Guid GUID_DEVCLASS_KEYBOARD = new Guid("4d36e96b-e325-11ce-bfc1-08002be10318");
        public static Guid GUID_DEVINTERFACE_DISK = new Guid("53f56307-b6bf-11d0-94f2-00a0c91efb8b");
        public static Guid GUID_DEVCLASS_PORTS = new Guid("4d36e978-e325-11ce-bfc1-08002be10318");
        //public static guid GUID_DEVINTERFACE_USB_DEVICE = { 0xA5DCBF10, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } };
        /*
        [DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern IntPtr SetupDiGetClassDevs(ref Guid classGuid, [MarshalAs(UnmanagedType.LPTStr)] string enumerator, IntPtr hwndParent, DiGetClassFlags flags);
        */
        [DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern IntPtr SetupDiGetClassDevs(ref Guid classGuid, IntPtr Enumerator, IntPtr hwndParent, DiGetClassFlags flags);
        /*
        [DllImport("Setupapi.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        public static extern IntPtr SetupDiGetClassDevs(ref Guid ClassGuid, IntPtr Enumerator, IntPtr hWndParent, int Flags);
        */
        [DllImport("Setupapi.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        public static extern bool SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet, int MemberIndex, ref SP_DEVINFO_DATA DeviceInfoData);
        [DllImport("Setupapi.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        public static extern bool SetupDiGetDeviceRegistryProperty(IntPtr DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData, uint Property,
    uint PropertyRegDataType, StringBuilder PropertyBuffer, uint PropertyBufferSize, IntPtr RequiredSize);
        public const int SPDRP_DEVICEDESC = (0x00000000);  // DeviceDesc (R/W)
        public const int SPDRP_FRIENDLYNAME = (0x0000000C); // FriendlyName (R/W)
        public const int SPDRP_LOCATION_INFORMATION = (0x0000000D);  // LocationInformation (R/W)
#if WIN64
        public const int PACK_SIZE = 8;
#else
        public const int PACK_SIZE = 1;
#endif
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = PACK_SIZE)]
        public struct SP_DEVINFO_DATA
        {
            public UInt32 cbSize;
            public Guid ClassGuid;
            public int DevInst;
            public IntPtr Reserved;
        }
        /*
        [StructLayout(LayoutKind.Sequential)]
        public struct SP_DEVINFO_DATA
        {
            public UInt32 cbSize;
            public Guid classGuid;
            public UInt32 devInst;
            public IntPtr reserved;     // CHANGE #1 - was UInt32
        }
        */
        [DllImport("CfgMgr32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern int CM_Get_DevNode_Registry_Property(IntPtr dnDevInst, uint ulProperty, ref uint pulRegDataType, IntPtr Buffer, ref uint pulLength, uint ulFlags);
        [DllImport("CfgMgr32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern int CM_Get_DevNode_Status(ref uint pulStatus, ref uint pulProblemNumber, IntPtr dnDevInst, uint ulFlags);
        public const int CR_SUCCESS = (0x00000000);
        public const int CM_PROB_DISABLED = (0x00000016);   // devinst is disabled
        public const int CM_PROB_HARDWARE_DISABLED = (0x0000001D);    // device disabled
        static void Main(string[] args)
        {
            Guid NullGuid = Guid.Empty;
            // add some values to the collection here
            List<KeyValuePair<string, string>> listToReturn = ReturnDevices(ref NullGuid);
            for (int i = 0; i < listToReturn.Count; i++)
            {
                Debug.WriteLine("Key: " + listToReturn[i].Key);
                Debug.WriteLine("Value:" + listToReturn[i].Value);
                Debug.WriteLine(IsDeviceEnabled(listToReturn[i].Key, ref NullGuid));
            }
            Debug.WriteLine("-=-=-=-=-=-=-=-=-=-= All Devices =-=-=-=-=-=-=-=-=-=-");
            List<KeyValuePair<string, string>> WebcamlistToReturn = ReturnDevices(ref GUID_Camera_Device);
            for (int i = 0; i < WebcamlistToReturn.Count; i++)
            {
                Debug.WriteLine("Key: " + WebcamlistToReturn[i].Key);
                Debug.WriteLine("Value:" + WebcamlistToReturn[i].Value);
                Debug.WriteLine(IsDeviceEnabled(WebcamlistToReturn[i].Key, ref GUID_Camera_Device));
                ToggleDeviceEnabledStatusByInstanceID(n => n.ToUpperInvariant().Contains(WebcamlistToReturn[i].Value), true); //WebcamlistToReturn[i].Value //true disables
                //USB\\VID_13D3&PID_56A2&MI_00
            }
            //DisableHardware.ToggleDeviceEnabledStatus(n => n.ToUpperInvariant().Contains(WebcamDeviceID), false); //USB\VID_13D3&PID_56A2&REV_1902&MI_00
        }
        [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern bool SetupDiGetDeviceInstanceId(
           IntPtr DeviceInfoSet,
           ref SP_DEVINFO_DATA DeviceInfoData,
           StringBuilder DeviceInstanceId,
           int DeviceInstanceIdSize,
           out int RequiredSize
        );
        enum DeviceReturnValue : ushort
        {
            notfound = 0,
            disabled = 1,
            enabled = 2
        }
        static List<KeyValuePair<string, string>> ReturnDevices(ref Guid FilterGuid)
        {
            //Dictionary<string, string> DictionaryToReturn = new Dictionary<string, string>();
            List<KeyValuePair<string, string>> listToReturn = new List<KeyValuePair<string, string>>();
            //IntPtr hDeviceInfo = SetupDiGetClassDevs(ref GUID_DEVCLASS_KEYBOARD, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT);
            IntPtr hDeviceInfo = IntPtr.Zero;
            if (FilterGuid == Guid.Empty)
            {
                hDeviceInfo = SetupDiGetClassDevs(ref FilterGuid, IntPtr.Zero, IntPtr.Zero, DiGetClassFlags.DIGCF_ALLCLASSES);
            }
            else
            {
                hDeviceInfo = SetupDiGetClassDevs(ref FilterGuid, IntPtr.Zero, IntPtr.Zero, DiGetClassFlags.DIGCF_PRESENT);
            }
            if (hDeviceInfo != IntPtr.Zero)
            {
                var DeviceInfoData = new SP_DEVINFO_DATA() { cbSize = (uint)Marshal.SizeOf(typeof(SP_DEVINFO_DATA)) };
                int nNumberOfDevicesPresent = 0;
                while (SetupDiEnumDeviceInfo(hDeviceInfo, nNumberOfDevicesPresent, ref DeviceInfoData))
                {
                    StringBuilder DeviceName = new StringBuilder(260);
                    DeviceName.Capacity = 260;
                    bool bRet = SetupDiGetDeviceRegistryProperty(hDeviceInfo, ref DeviceInfoData, SPDRP_FRIENDLYNAME, 0, DeviceName, (uint)DeviceName.Capacity, IntPtr.Zero);
                    if (bRet)
                    {
                        //Console.WriteLine(DeviceInfoData.ClassGuid); //Device class and in this case "Camera"
                        //Console.WriteLine("Device Name : {0}", DeviceName.ToString());
                        int RequiredSize = 0;
                        bool ret = SetupDiGetDeviceInstanceId(hDeviceInfo, ref DeviceInfoData, null, 0, out RequiredSize);
                        StringBuilder sb = new StringBuilder(RequiredSize);
                        ret = SetupDiGetDeviceInstanceId(hDeviceInfo, ref DeviceInfoData, sb, RequiredSize, out RequiredSize);
                        //Console.WriteLine("DeviceID: " + sb.ToString());
                        listToReturn.Add(new KeyValuePair<string, string>(DeviceName.ToString(), sb.ToString()));
                        /*
                        if (!listToReturn.ContainsKey(DeviceName.ToString()))
                        {
                            listToReturn.Add(DeviceName.ToString(), sb.ToString());
                        }
                        else
                        {
                            Debug.WriteLine("Unable to add:" + DeviceName.ToString());
                        }
                        */
                    }
                    else
                    {
                        bRet = SetupDiGetDeviceRegistryProperty(hDeviceInfo, ref DeviceInfoData, SPDRP_DEVICEDESC, 0, DeviceName, (uint)DeviceName.Capacity, IntPtr.Zero);
                        if (bRet)
                        {
                            Console.WriteLine(DeviceInfoData.ClassGuid);
                            Console.WriteLine("Device Description : {0}", DeviceName.ToString());
                        }
                    }
                    nNumberOfDevicesPresent++;
                }
            }
            return listToReturn;
        }
        static DeviceReturnValue IsDeviceEnabled(string DeviceNameFilter, ref Guid FilterGuid)
        {
            //IntPtr hDeviceInfo = SetupDiGetClassDevs(ref GUID_DEVCLASS_KEYBOARD, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT);
            IntPtr hDeviceInfo = IntPtr.Zero;
            if (FilterGuid == Guid.Empty)
            {
                hDeviceInfo = SetupDiGetClassDevs(ref FilterGuid, IntPtr.Zero, IntPtr.Zero, DiGetClassFlags.DIGCF_ALLCLASSES);
            }
            else
            {
                hDeviceInfo = SetupDiGetClassDevs(ref FilterGuid, IntPtr.Zero, IntPtr.Zero, DiGetClassFlags.DIGCF_PRESENT);
            }
            if (hDeviceInfo != IntPtr.Zero)
            {
                var DeviceInfoData = new SP_DEVINFO_DATA() { cbSize = (uint)Marshal.SizeOf(typeof(SP_DEVINFO_DATA)) };
                int nNumberOfDevicesPresent = 0;
                while (SetupDiEnumDeviceInfo(hDeviceInfo, nNumberOfDevicesPresent, ref DeviceInfoData))
                {
                    StringBuilder DeviceName = new StringBuilder(260);
                    DeviceName.Capacity = 260;
                    bool bRet = SetupDiGetDeviceRegistryProperty(hDeviceInfo, ref DeviceInfoData, SPDRP_FRIENDLYNAME, 0, DeviceName, (uint)DeviceName.Capacity, IntPtr.Zero);
                    if (bRet)
                    {
                        if (DeviceNameFilter == DeviceName.ToString())
                        {
                            Console.WriteLine(DeviceInfoData.ClassGuid); //Device class and in this case "Camera"
                            Console.WriteLine("Device Name : {0}", DeviceName.ToString());
                            int RequiredSize = 0;
                            bool ret = SetupDiGetDeviceInstanceId(hDeviceInfo, ref DeviceInfoData, null, 0, out RequiredSize);
                            StringBuilder sb = new StringBuilder(RequiredSize);
                            ret = SetupDiGetDeviceInstanceId(hDeviceInfo, ref DeviceInfoData, sb, RequiredSize, out RequiredSize);
                            Console.WriteLine("DeviceID: " + sb.ToString());
                            uint nStatus = 0;
                            uint nProblem = 0;
                            int nRet = CM_Get_DevNode_Status(ref nStatus, ref nProblem, (IntPtr)DeviceInfoData.DevInst, 0);
                            bool bDisabled = false;
                            if (nRet == CR_SUCCESS)
                            {
                                bDisabled = (nProblem == CM_PROB_DISABLED) || (nProblem == CM_PROB_HARDWARE_DISABLED);
                            }
                            Console.WriteLine("Disabled : {0}", bDisabled);
                            if (bDisabled)
                            {
                                return DeviceReturnValue.disabled;
                            }
                            else
                            {
                                return DeviceReturnValue.enabled;
                            }
                        }
                    }
                    else
                    {
                        bRet = SetupDiGetDeviceRegistryProperty(hDeviceInfo, ref DeviceInfoData, SPDRP_DEVICEDESC, 0, DeviceName, (uint)DeviceName.Capacity, IntPtr.Zero);
                        if (bRet)
                        {
                            Console.WriteLine(DeviceInfoData.ClassGuid);
                            Console.WriteLine("Device Description : {0}", DeviceName.ToString());
                        }
                    }
                    nNumberOfDevicesPresent++;
                }
            }
            return DeviceReturnValue.notfound;
        }
        public static bool GetDeviceState(Func<string, bool> filter) //https://www.codeproject.com/script/Content/ViewAssociatedFile.aspx?rzp=%2FKB%2Fsystem%2FDevMgr%2Fdevmgr-src.zip&zep=GetTypeInfo.c&obid=14469&obtid=2&ovid=1
        {
            /*
            var dpk = new DEVPROPKEY();
            dpk.fmtid = new Guid("60b193cb-5276-4d0f-96fc-f173abad3ec6");
            dpk.pid = 2;
            var displayDevClass = new Guid("{ca3e7ab9-b4c3-4ae6-8251-579ef933890f}".ToString());
            var hDevInfo = SetupDiGetClassDevs(ref displayDevClass, null, IntPtr.Zero, DiGetClassFlags.DIGCF_PRESENT | DiGetClassFlags.DIGCF_DEVICEINTERFACE);
            if (hDevInfo != INVALID_HANDLE_VALUE)
            {
                uint i = 0;
                while (true)
                {
                    var did = new SP_DEVINFO_DATA();
                    did.cbSize = (uint)Marshal.SizeOf(did);
                    if (!SetupDiEnumDeviceInfo(hDevInfo, i, out did)) break;
                    uint required = 0;
                    DEVPROPTYPE dpt = 0;
                    var temp = new byte[0];
                    SetupDiGetDeviceProperty(hDevInfo, ref did, ref dpk, ref dpt, temp, 0, ref required);
                    if (required > 0)
                    {
                        var data = new byte[required];
                        if (SetupDiGetDeviceProperty(hDevInfo, ref did, ref dpk, ref dpt, data, required, ref required))
                        {
                            Debug.WriteLine(BitConverter.ToString(data));
                        }
                    }
                }
            }
            */
            IntPtr info = IntPtr.Zero;
            Guid NullGuid = Guid.Empty;
            try
            {
                info = SetupDiGetClassDevsW(ref NullGuid, null, IntPtr.Zero, DIGCF_ALLCLASSES);
                CheckError("SetupDiGetClassDevs");
                SP_DEVINFO_DATA devdata = new SP_DEVINFO_DATA();
                devdata.cbSize = (UInt32)Marshal.SizeOf(devdata);
                // Get first device matching device criterion.
                for (uint i = 0; ; i++)
                {
                    SetupDiEnumDeviceInfo(info, i, out devdata);
                    // if no items match filter, throw
                    if (Marshal.GetLastWin32Error() == ERROR_NO_MORE_ITEMS)
                        CheckError("No device found matching filter.", 0xcffff);
                    CheckError("SetupDiEnumDeviceInfo");
                    string devicepath = GetStringPropertyForDevice(info, devdata, 1); // SPDRP_HARDWAREID
                    //uint CM_DEVCAP_HARDWAREDISABLED = 16384u;
                    uint proptype, outsize;
                    IntPtr buffer = IntPtr.Zero;
                    SetupDiGetDeviceRegistryPropertyW(info, ref devdata, (uint)SetupDiGetDeviceRegistryPropertyEnum.SPDRP_CAPABILITIES, out proptype, IntPtr.Zero, 0, out outsize); //ref outside
                    uint buflen = outsize;
                    buffer = Marshal.AllocHGlobal((int)buflen);
                    outsize = 0;
                    SetupDiGetDeviceRegistryPropertyW(info, ref devdata, (uint)SetupDiGetDeviceRegistryPropertyEnum.SPDRP_CAPABILITIES, out proptype, buffer, (uint)buflen, out outsize); //ref outside
                    byte[] Mybuffer = new byte[63];
                    SetupDiGetDeviceRegistryProperty(info, ref devdata, (uint)SetupDiGetDeviceRegistryPropertyEnum.SPDRP_CAPABILITIES, IntPtr.Zero, Mybuffer, 63, out outsize); //ref outside
                    uint cap2 = BitConverter.ToUInt32(Mybuffer, 0);
                    //Encoding.Unicode.GetString(lbuffer);
                    /*
                    byte[] lbuffer = new byte[outsize];
                    Marshal.Copy(buffer, lbuffer, 0, (int)outsize);
                    int errcode = Marshal.GetLastWin32Error();
                    if (errcode == ERROR_INVALID_DATA) throw new Exception("ERROR_INVALID_DATA");
                    CheckError("SetupDiGetDeviceRegistryPropertyW", errcode);
                    */
                    byte[] lbuffer = new byte[outsize];
                    Marshal.Copy(buffer, lbuffer, 0, (int)outsize);
                    int errcode = Marshal.GetLastWin32Error();
                    if (errcode == ERROR_INVALID_DATA) return false;
                    CheckError("SetupDiGetDeviceProperty", errcode);
                    //return Encoding.Unicode.GetBytes(lbuffer);
                    uint capabilities = BitConverter.ToUInt32(lbuffer, 0); // always 128
                    capabilities = getDWORDProp(info, devdata, SetupDiGetDeviceRegistryPropertyEnum.SPDRP_CAPABILITIES);
                    uint bitwise = capabilities & CM_DEVCAP_HARDWAREDISABLED; // always 0
                    bool isHardwareDisabled = bitwise > 0;
                    Debug.WriteLine(devicepath);
                    Debug.WriteLine(" - HARDWAREDISABLED: " + isHardwareDisabled.ToString().Trim() + " - " + bitwise + " | " + cap2 + " Compat: " + capabilities.ToString());
                    // Uncomment to print name/path
                    //Console.WriteLine(GetStringPropertyForDevice(info,
                    //                         devdata, DEVPKEY_Device_DeviceDesc));
                    //Console.WriteLine("   {0}", devicepath);
                    if (devicepath != null && filter(devicepath)) break;
                }
            }
            finally
            {
                if (info != IntPtr.Zero)
                    SetupDiDestroyDeviceInfoList(info);
            }
            return true; //Need to be fixed
        }
        public static void ToggleDeviceEnabledStatusByInstanceID(Func<string, bool> filter, bool disable = true)
        {
            IntPtr info = IntPtr.Zero;
            Guid NullGuid = Guid.Empty;
            try
            {
                info = SetupDiGetClassDevsW(
                    ref NullGuid,
                    null,
                    IntPtr.Zero,
                    DIGCF_ALLCLASSES);
                CheckError("SetupDiGetClassDevs");
                SP_DEVINFO_DATA devdata = new SP_DEVINFO_DATA();
                devdata.cbSize = (UInt32)Marshal.SizeOf(devdata);
                // Get first device matching device criterion.
                for (uint i = 0; ; i++)
                {
                    SetupDiEnumDeviceInfo(info, i, out devdata);
                    // if no items match filter, throw
                    if (Marshal.GetLastWin32Error() == ERROR_NO_MORE_ITEMS)
                    {
                        CheckError("No device found matching filter.", 0xcffff);
                        CheckError("SetupDiEnumDeviceInfo");
                        return;
                    }
                    StringBuilder DeviceName = new StringBuilder(260);
                    DeviceName.Capacity = 260;
                    bool bRet = SetupDiGetDeviceRegistryProperty(info, ref devdata, SPDRP_FRIENDLYNAME, 0, DeviceName, (uint)DeviceName.Capacity, IntPtr.Zero);
                    if (bRet)
                    {
                        //Console.WriteLine(DeviceInfoData.ClassGuid); //Device class and in this case "Camera"
                        //Console.WriteLine("Device Name : {0}", DeviceName.ToString());
                        int RequiredSize = 0;
                        bool ret = SetupDiGetDeviceInstanceId(info, ref devdata, null, 0, out RequiredSize);
                        StringBuilder sb = new StringBuilder(RequiredSize);
                        ret = SetupDiGetDeviceInstanceId(info, ref devdata, sb, RequiredSize, out RequiredSize);
                        Console.WriteLine("Device Name : {0}", DeviceName.ToString());
                        Console.WriteLine("DeviceID: " + sb.ToString());
                        if (sb.ToString() != null && filter(sb.ToString())) break;
                    }
                    else
                    {
                        bRet = SetupDiGetDeviceRegistryProperty(info, ref devdata, SPDRP_DEVICEDESC, 0, DeviceName, (uint)DeviceName.Capacity, IntPtr.Zero);
                        if (bRet)
                        {
                            Console.WriteLine(devdata.ClassGuid);
                            Console.WriteLine("Device Description : {0}", DeviceName.ToString());
                            if (DeviceName.ToString() != null && filter(DeviceName.ToString())) break;
                        }
                    }
                    string devicepath = GetStringPropertyForDevice(info, devdata, 1); // SPDRP_HARDWAREID
                    // Uncomment to print name/path
                    //Console.WriteLine(GetStringPropertyForDevice(info,
                    //                         devdata, DEVPKEY_Device_DeviceDesc));
                    //Console.WriteLine("   {0}", devicepath);
                    if (devicepath != null && filter(devicepath)) break;
                }
                SP_CLASSINSTALL_HEADER header = new SP_CLASSINSTALL_HEADER();
                header.cbSize = (UInt32)Marshal.SizeOf(header);
                header.InstallFunction = DIF_PROPERTYCHANGE;
                SP_PROPCHANGE_PARAMS propchangeparams = new SP_PROPCHANGE_PARAMS();
                propchangeparams.ClassInstallHeader = header;
                propchangeparams.StateChange = disable ? DICS_DISABLE : DICS_ENABLE;
                propchangeparams.Scope = DICS_FLAG_GLOBAL;
                propchangeparams.HwProfile = 0;
                SetupDiSetClassInstallParams(info,
                    ref devdata,
                    ref propchangeparams,
                    (UInt32)Marshal.SizeOf(propchangeparams));
                CheckError("SetupDiSetClassInstallParams");
                SetupDiChangeState(
                    info,
                    ref devdata);
                CheckError("SetupDiChangeState");
            }
            finally
            {
                if (info != IntPtr.Zero)
                    SetupDiDestroyDeviceInfoList(info);
            }
        }
        public static void ToggleDeviceEnabledStatusByHWID(Func<string, bool> filter, bool disable = true)
        {
            IntPtr info = IntPtr.Zero;
            Guid NullGuid = Guid.Empty;
            try
            {
                info = SetupDiGetClassDevsW(
                    ref NullGuid,
                    null,
                    IntPtr.Zero,
                    DIGCF_ALLCLASSES);
                CheckError("SetupDiGetClassDevs");
                SP_DEVINFO_DATA devdata = new SP_DEVINFO_DATA();
                devdata.cbSize = (UInt32)Marshal.SizeOf(devdata);
                // Get first device matching device criterion.
                for (uint i = 0; ; i++)
                {
                    SetupDiEnumDeviceInfo(info, i, out devdata);
                    // if no items match filter, throw
                    if (Marshal.GetLastWin32Error() == ERROR_NO_MORE_ITEMS)
                    {
                        CheckError("No device found matching filter.", 0xcffff);
                        CheckError("SetupDiEnumDeviceInfo");
                        return;
                    }
                    string devicepath = GetStringPropertyForDevice(info, devdata, 1); // SPDRP_HARDWAREID
                    // Uncomment to print name/path
                    //Console.WriteLine(GetStringPropertyForDevice(info,
                    //                         devdata, DEVPKEY_Device_DeviceDesc));
                    //Console.WriteLine("   {0}", devicepath);
                    if (devicepath != null && filter(devicepath)) break;
                }
                SP_CLASSINSTALL_HEADER header = new SP_CLASSINSTALL_HEADER();
                header.cbSize = (UInt32)Marshal.SizeOf(header);
                header.InstallFunction = DIF_PROPERTYCHANGE;
                SP_PROPCHANGE_PARAMS propchangeparams = new SP_PROPCHANGE_PARAMS();
                propchangeparams.ClassInstallHeader = header;
                propchangeparams.StateChange = disable ? DICS_DISABLE : DICS_ENABLE;
                propchangeparams.Scope = DICS_FLAG_GLOBAL;
                propchangeparams.HwProfile = 0;
                SetupDiSetClassInstallParams(info,
                    ref devdata,
                    ref propchangeparams,
                    (UInt32)Marshal.SizeOf(propchangeparams));
                CheckError("SetupDiSetClassInstallParams");
                SetupDiChangeState(
                    info,
                    ref devdata);
                CheckError("SetupDiChangeState");
            }
            finally
            {
                if (info != IntPtr.Zero)
                    SetupDiDestroyDeviceInfoList(info);
            }
        }
        private static void CheckError(string message, int lasterror = -1)
        {
            int code = lasterror == -1 ? Marshal.GetLastWin32Error() : lasterror;
            if (code != 0)
            {
                Debug.WriteLine("Error disabling hardware device (Code {0}): {1}", code, message);
            }
        }
        private static string GetStringPropertyForDevice(IntPtr info, SP_DEVINFO_DATA devdata, uint propId)
        {
            uint proptype, outsize;
            IntPtr buffer = IntPtr.Zero;
            try
            {
                uint buflen = 512;
                buffer = Marshal.AllocHGlobal((int)buflen);
                outsize = 0;
                // CHANGE #2 - Use this instead of SetupDiGetDeviceProperty
                SetupDiGetDeviceRegistryPropertyW(
                    info,
                    ref devdata,
                    propId,
                    out proptype,
                    buffer,
                    buflen,
                    out outsize);
                byte[] lbuffer = new byte[outsize];
                Marshal.Copy(buffer, lbuffer, 0, (int)outsize);
                int errcode = Marshal.GetLastWin32Error();
                if (errcode == ERROR_INVALID_DATA) return null;
                CheckError("SetupDiGetDeviceProperty", errcode);
                return Encoding.Unicode.GetString(lbuffer);
            }
            finally
            {
                if (buffer != IntPtr.Zero)
                    Marshal.FreeHGlobal(buffer);
            }
        }
    }
}

Popular Posts