private string GetPropertString(UInt32 deviceInstance, ConfigManagerAPI.DeviceInfo devPropInfo)
        {
            string property = "";

            UInt32 propertyType = 0;
            IntPtr buf          = new IntPtr();
            UInt32 bufSize      = 0;

            uint result = ConfigManagerAPI.CM_Get_DevNode_PropertyW(deviceInstance, ref devPropInfo, ref propertyType, buf, ref bufSize, 0);

            if (result == SMALL_BAFFER && propertyType == STRING_TYPE)
            {
                buf = Marshal.AllocHGlobal((int)bufSize * 2);

                result = ConfigManagerAPI.CM_Get_DevNode_PropertyW(deviceInstance, ref devPropInfo, ref propertyType, buf, ref bufSize, 0);

                if (result == 0)
                {
                    property = ReadNullTerminatedStringFromBuffer(buf, bufSize);
                }

                Marshal.FreeHGlobal(buf);
            }

            return(property);
        }
        public List <WindowsDevice> EnumerateDevices()
        {
            List <WindowsDevice> devices = new List <WindowsDevice>();

            uint result = 0;

            UInt32 size   = 0;                                                                          //size iz number of characters
            string filter = "";

            result = ConfigManagerAPI.CM_Get_Device_ID_List_SizeW(ref size, ref filter, 0);
            if (result == 0)
            {
                IntPtr buffer = Marshal.AllocHGlobal((int)size * 2);                                    //width of wchar is 2
                UInt32 flags  = 256;

                result = ConfigManagerAPI.CM_Get_Device_ID_ListW(ref filter, buffer, size, flags);
                if (result == 0)
                {
                    List <Tuple <string, int> > devicesList = ParseBuffer(buffer, size);

                    foreach (var device in devicesList)
                    {
                        UInt32 deviceInstance = 0;
                        IntPtr ptrToDeviceId  = IntPtr.Add(buffer, device.Item2);
                        result = ConfigManagerAPI.CM_Locate_DevNodeW(ref deviceInstance, ptrToDeviceId, 0);

                        if (result == 0)
                        {
                            string        id            = device.Item1;
                            string        deviceClass   = GetPropertString(deviceInstance, new ConfigManagerAPI.DeviceInfo(new Guid(DEV_INFO_DEVICE_CLASS_GUID), DEV_INFO_DEVICE_CLASS_PID));
                            string        parent        = GetPropertString(deviceInstance, new ConfigManagerAPI.DeviceInfo(new Guid(DEV_INFO_PARENT_ID_GUID), DEV_INFO_PARENT_ID_PID));
                            string        driverVersion = GetPropertString(deviceInstance, new ConfigManagerAPI.DeviceInfo(new Guid(DEV_INFO_DRIVER_VERSION_GUID), DEV_INFO_DRIVER_VERSION_PID));
                            List <string> children      = GetPropertStringList(deviceInstance, new ConfigManagerAPI.DeviceInfo(new Guid(DEV_INFO_CHILDREN_ID_GUID), DEV_INFO_CHILDREN_ID_PID));

                            WindowsDevice windowsDevice = new WindowsDevice(id, id, deviceClass, children, parent, driverVersion);
                            devices.Add(windowsDevice);
                        }
                    }
                }

                Marshal.FreeHGlobal(buffer);
            }

            InitializeDeviceSiblings(devices);

            return(devices);
        }
        private List <string> GetPropertStringList(UInt32 deviceInstance, ConfigManagerAPI.DeviceInfo devPropInfo)
        {
            List <string> property = new List <string>();

            UInt32 propertyType = 0;
            IntPtr buf          = new IntPtr();
            UInt32 bufSize      = 0;

            uint result = ConfigManagerAPI.CM_Get_DevNode_PropertyW(deviceInstance, ref devPropInfo, ref propertyType, buf, ref bufSize, 0);

            if (result == SMALL_BAFFER && propertyType == (STRING_TYPE + LIST_TYPE))
            {
                buf = Marshal.AllocHGlobal((int)bufSize * 2);

                result = ConfigManagerAPI.CM_Get_DevNode_PropertyW(deviceInstance, ref devPropInfo, ref propertyType, buf, ref bufSize, 0);

                if (result == 0)
                {
                    IntPtr pointer = buf;
                    while (bufSize > 0)
                    {
                        string element = ReadNullTerminatedStringFromBuffer(pointer, bufSize);
                        if (String.IsNullOrEmpty(element))
                        {
                            break;
                        }
                        int offset = element.Length + 1;
                        offset *= 2;
                        property.Add(element);
                        pointer = IntPtr.Add(pointer, offset);
                    }
                }

                Marshal.FreeHGlobal(buf);
            }

            return(property);
        }