public override void GatherUsbInformation(ref MachineInformation information)
        {
            using var mos = new ManagementObjectSearcher("select DeviceID from Win32_PnPEntity");
            var mbos = new ArrayList(mos.Get());
            var data = new Dictionary <string, string[]>();

            for (var i = 0; i < mbos.Count; i++)
            {
                var managementBaseObject = mbos[i] as ManagementBaseObject;

                if (managementBaseObject is null)
                {
                    continue;
                }

                var deviceId = managementBaseObject.Properties["DeviceID"].Value as string;

                if (deviceId is null || !deviceId.StartsWith("USB"))
                {
                    continue;
                }

                if (!data.ContainsKey(deviceId))
                {
                    data.Add(deviceId, new string[8]);
                }
                else if (data.ContainsKey(deviceId))
                {
                    continue;
                }

                // Win32_PnpDeviceProperty is only available with Windows 10
                if (!win10)
                {
                    continue;
                }

                var mo       = managementBaseObject as ManagementObject;
                var inParams = mo.GetMethodParameters("GetDeviceProperties");

                var result = mo.InvokeMethod(
                    "GetDeviceProperties",
                    inParams,
                    new InvokeMethodOptions()
                    );

                if (result?.Properties["deviceProperties"].Value is null)
                {
                    continue;
                }

                foreach (var deviceProperties in result.Properties["deviceProperties"].Value as ManagementBaseObject[])
                {
                    var keyName = deviceProperties.Properties["KeyName"].Value as string;
                    var value   = deviceProperties.Properties["Data"].Value as string;

                    if (string.IsNullOrWhiteSpace(value) || string.IsNullOrWhiteSpace(keyName))
                    {
                        MachineInformationGatherer.Logger.LogTrace(
                            $"KeyName {keyName} or Value {value} was null or whitespace for device ID {deviceId}");
                        continue;
                    }

                    switch (keyName)
                    {
                    case "DEVPKEY_Device_BusReportedDeviceDesc":
                    {
                        data[deviceId][0] = value;
                        break;
                    }

                    case "DEVPKEY_Device_DriverDesc":
                    {
                        data[deviceId][1] = value;
                        break;
                    }

                    case "DEVPKEY_Device_DriverVersion":
                    {
                        data[deviceId][2] = value;
                        break;
                    }

                    case "DEVPKEY_Device_DriverDate":
                    {
                        var year   = int.Parse(value.Substring(0, 4));
                        var month  = int.Parse(value.Substring(4, 2));
                        var day    = int.Parse(value.Substring(6, 2));
                        var hour   = int.Parse(value.Substring(8, 2));
                        var minute = int.Parse(value.Substring(10, 2));
                        var second = int.Parse(value.Substring(12, 2));

                        data[deviceId][3] =
                            new DateTime(year, month, day, hour, minute, second).ToString();
                        break;
                    }

                    case "DEVPKEY_Device_Class":
                    {
                        data[deviceId][4] = value;
                        break;
                    }

                    case "DEVPKEY_Device_DriverProvider":
                    {
                        data[deviceId][5] = value;
                        break;
                    }

                    case "DEVPKEY_NAME":
                    {
                        data[deviceId][6] = value;
                        break;
                    }

                    case "DEVPKEY_Device_Manufacturer":
                    {
                        data[deviceId][7] = value;
                        break;
                    }

                    case "DEVPKEY_Device_Children":
                    {
                        var children = deviceProperties.Properties["DEVPKEY_Device_Children"];
                        if (children.Value is not null)
                        {
                            if (children.IsArray)
                            {
                                foreach (var child in children.Value as string[])
                                {
                                    mos.Query = new ObjectQuery(
                                        $"select * from Win32_PnPEntity where DeviceID = {child}");
                                    var childs = mos.Get();

                                    foreach (var child1 in childs)
                                    {
                                        mbos.Add(child1);
                                    }
                                }
                            }
                        }

                        break;
                    }
                    }
                }
            }

            var realData = new Dictionary <string, USBDevice>();

            foreach (var stringse in data)
            {
                var deviceDesc = stringse.Value[0];
                var driverDesc = stringse.Value[1];

                if (deviceDesc is null || driverDesc is null)
                {
                    continue;
                }

                if (!realData.ContainsKey(deviceDesc))
                {
                    var(vid, pid) = GetVidAndPid(stringse.Key);
                    var(vendorName, productName) = USBVendorList.GetVendorAndProductName(vid, pid);

                    realData.Add(deviceDesc,
                                 new USBDevice
                    {
                        Name          = stringse.Value[6], BusReportedName = deviceDesc, DriverName = driverDesc,
                        DriverVersion = stringse.Value[2], DriverDate = DateTime.Parse(stringse.Value[3]),
                        Class         = stringse.Value[4], DriverProvider = stringse.Value[5],
                        Manufacturer  = stringse.Value[7],
                        DeviceID      = stringse.Key, VendorID = vid, ProductID = pid,
                        VendorName    = vendorName, ProductName = productName
                    });
                }
                else
                {
                    var device  = realData[deviceDesc];
                    var replace = false;

                    // Prefer composite over solely input
                    if (device.DriverName == "USB Input Device" && driverDesc == "USB Composite Device")
                    {
                        replace = true;
                    }
                    // Prefer composite over solely output
                    else if (device.DriverName == "USB Output Device" &&
                             driverDesc == "USB Composite Device")
                    {
                        replace = true;
                    }
                    // Prefer composite over solely audio
                    else if (device.DriverName == "USB Audio Device" &&
                             driverDesc == "USB Composite Device")
                    {
                        replace = true;
                    }
                    // Prefer different DriverProvider over Microsoft (standard)
                    else if (device.DriverProvider == "Microsoft" && stringse.Value[5] != "Microsoft")
                    {
                        replace = true;
                    }
                    // Prefer different (or any) Manufacturer over Microsoft
                    else if (device.Manufacturer is null or "Microsoft" &&
                             stringse.Value[7] is not null and not "Microsoft")
                    {
                        replace = true;
                    }
예제 #2
0
        private void GetUSBInformation(ref MachineInformation information)
        {
            if (information.UsbDevices.Count != 0)
            {
                return;
            }

            var usbs = new List <USBDevice>();

            try
            {
                using var p  = Util.StartProcess("lsusb", "");
                using var sr = p.StandardOutput;
                p.WaitForExit();

                var lines = sr.ReadToEnd().Trim()
                            .Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
                var data = new Dictionary <string, string>();

                foreach (var line in lines)
                {
                    try
                    {
                        var parts        = line.Split(' ');
                        var busNumber    = parts[1].Trim('0');
                        var deviceNumber = parts[3].Replace(":", "").Trim('0');
                        var deviceId     = parts[5];

                        data.Add($"{busNumber}-{deviceNumber}", deviceId);
                    }
                    catch
                    {
                        // Intentionally left blank
                    }
                }

                using var pr = Util.StartProcess("lsusb", "-t");
                using var so = pr.StandardOutput;
                pr.WaitForExit();

                lines = sr.ReadToEnd().Trim()
                        .Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
                var lastBusNumber = "";

                foreach (var line in lines)
                {
                    var    parts = line.Split(' ').ToList();
                    string busNumber;

                    // Sub-device
                    if (parts[0].StartsWith("|_"))
                    {
                        busNumber = lastBusNumber;
                    }
                    // Top-level HUB
                    else
                    {
                        busNumber     = parts[2].Split('.')[0].Trim('0');
                        lastBusNumber = busNumber;
                        parts.RemoveAt(1);
                    }

                    var deviceNumber   = parts[4].Trim(',');
                    var classSpecifier = parts[5].Split('=')[1].Trim(',');
                    var driverName     = parts[6].Split('=')[1].Trim(',');

                    if (data.TryGetValue($"{busNumber}-{deviceNumber}", out var deviceId))
                    {
                        var vendorId  = deviceId.Split(':')[0];
                        var productId = deviceId.Split(':')[1];
                        var(vendorName, productName) = USBVendorList.GetVendorAndProductName(vendorId, productId);

                        var usb = new USBDevice
                        {
                            Class     = classSpecifier, DriverName = driverName, VendorID = vendorId,
                            ProductID = productId, VendorName = vendorName, ProductName = productName
                        };

                        usbs.Add(usb);
                    }
                }
            }
            catch (Exception e)
            {
                MachineInformationGatherer.Logger.LogError(e, "Encountered while parsing USB info");
            }
            finally
            {
                information.UsbDevices = usbs.AsReadOnly();
            }
        }