mirror of
https://github.com/outbackdingo/Hardware-Sniffer.git
synced 2026-01-27 10:19:09 +00:00
626 lines
24 KiB
Python
Executable File
626 lines
24 KiB
Python
Executable File
from ..datasets import chipset_data
|
|
from ..datasets import pci_data
|
|
from .. import cpu_identifier
|
|
from .. import cpuid
|
|
from .. import device_locator
|
|
from .. import gpu_identifier
|
|
from .. import utils
|
|
import time
|
|
import re
|
|
import wmi
|
|
import winreg
|
|
|
|
c = wmi.WMI()
|
|
|
|
class WindowsHardwareInfo:
|
|
def __init__(self):
|
|
self.lookup_codename = cpu_identifier.CPUIdentifier().lookup_codename
|
|
self.classify_gpu = gpu_identifier.GPUIdentifier().classify_gpu
|
|
self.get_device_location_paths = device_locator.WindowsDeviceLocator().get_device_location_paths
|
|
self.utils = utils.Utils()
|
|
self.usb_ids = self.utils.read_file(self.utils.get_full_path("Scripts", "datasets", "usb.ids"))
|
|
self.pci_ids = self.utils.read_file(self.utils.get_full_path("Scripts", "datasets", "pci.ids"))
|
|
|
|
def parse_device_path(self, device_path):
|
|
device_info = {}
|
|
|
|
parts = device_path.split("\\")
|
|
|
|
device_info["Bus Type"] = parts[0]
|
|
|
|
if "&" not in parts[1]:
|
|
device_info["Device"] = parts[1]
|
|
return device_info
|
|
|
|
vendor_id, device_id, product_id, hid_id, subsystem_id = None, None, None, None, None
|
|
|
|
for segment in parts[1].replace("_", "").split("&"):
|
|
if segment.startswith("VEN"):
|
|
vendor_id = segment.split("VEN")[-1].zfill(4)
|
|
elif segment.startswith("DEV"):
|
|
device_id = segment.split("DEV")[-1]
|
|
elif segment.startswith("VID"):
|
|
vendor_id = segment.split("VID")[-1].zfill(4)
|
|
elif segment.startswith("PID"):
|
|
product_id = segment.split("PID")[-1]
|
|
elif segment.startswith("HID"):
|
|
hid_id = segment.split("HID")[-1]
|
|
elif segment.startswith("SUBSYS"):
|
|
subsystem_id = segment.split("SUBSYS")[-1]
|
|
|
|
if vendor_id and (device_id or product_id or hid_id):
|
|
device_info["Device ID"] = "{}-{}".format(vendor_id, device_id or product_id or hid_id)
|
|
elif len(parts[1].split("&")[0]) in (7, 8):
|
|
device_info["Device"] = parts[1].split("&")[0]
|
|
|
|
if subsystem_id:
|
|
device_info["Subsystem ID"] = subsystem_id
|
|
|
|
return device_info
|
|
|
|
def unknown_class_device(self, device_id):
|
|
if device_id in pci_data.BluetoothIDs:
|
|
return "Bluetooth"
|
|
elif device_id in pci_data.NetworkIDs:
|
|
return "Net"
|
|
elif device_id in pci_data.RealtekCardReaderIDs:
|
|
return "SDHost"
|
|
elif self.classify_gpu(device_id).get("Codename") != "Unknown":
|
|
return "Display"
|
|
|
|
return "Unknown"
|
|
|
|
def pnp_devices(self):
|
|
self.devices_by_class = {
|
|
"Display": [],
|
|
"Monitor": [],
|
|
"Net": [],
|
|
"MEDIA": [],
|
|
"AudioEndpoint": [],
|
|
"USB": [],
|
|
"HIDClass": [],
|
|
"Keyboard": [],
|
|
"Mouse": [],
|
|
"HDC": [],
|
|
"SCSIAdapter": [],
|
|
"Biometric": [],
|
|
"Bluetooth": [],
|
|
"SDHost": [],
|
|
"MTD": [],
|
|
"System": []
|
|
}
|
|
|
|
for device in c.Win32_PnPEntity():
|
|
device_class = device.PNPClass or "Unknown"
|
|
pnp_device_id = device.PNPDeviceID or None
|
|
|
|
if pnp_device_id:
|
|
device_info = self.parse_device_path(pnp_device_id)
|
|
|
|
if device_info.get("Device ID"):
|
|
if device_class in "Unknown":
|
|
device_class = self.unknown_class_device(device_info.get("Device ID"))
|
|
elif device_class in "System" and chipset_data.chipset_controllers.get(device_info.get("Device ID")):
|
|
self.chipset_model = chipset_data.chipset_controllers.get(device_info.get("Device ID"))
|
|
|
|
if device_class in self.devices_by_class:
|
|
self.devices_by_class[device_class].append(device)
|
|
|
|
def motherboard(self):
|
|
manufacturer = model = "Unknown"
|
|
|
|
try:
|
|
base_board = c.Win32_BaseBoard()[0]
|
|
manufacturer = base_board.Manufacturer
|
|
model = base_board.Product
|
|
except: pass
|
|
|
|
try:
|
|
computer_system = c.Win32_ComputerSystem()[0]
|
|
manufacturer = computer_system.Manufacturer
|
|
model = computer_system.Model
|
|
except: pass
|
|
|
|
manufacturer = manufacturer.split(" ")[0]
|
|
system_name = (" ".join(item for item in (manufacturer, model) if not "unknown" in item.lower()) or model).upper()
|
|
|
|
try:
|
|
for chipset_name in chipset_data.amd_chipsets:
|
|
if chipset_name in system_name:
|
|
self.chipset_model = chipset_name
|
|
break
|
|
|
|
self.chipset_model
|
|
except:
|
|
chipset_model = "Unknown"
|
|
|
|
system_platform = computer_system.PCSystemType
|
|
|
|
if system_platform == "Unspecified":
|
|
pass
|
|
elif system_platform in (2, 8, 9, 10):
|
|
system_platform = "Laptop"
|
|
else:
|
|
system_platform = "Desktop"
|
|
|
|
return {
|
|
"Name": system_name,
|
|
"Chipset": chipset_model,
|
|
"Platform": system_platform
|
|
}
|
|
|
|
def is_set(self, cpu, leaf, subleaf, reg_idx, bit):
|
|
regs = cpu(leaf, subleaf)
|
|
|
|
if (1 << bit) & regs[reg_idx]:
|
|
return True
|
|
|
|
return False
|
|
|
|
def get_simd_features(self):
|
|
simd_features_map = {
|
|
"SSE": (1, 0, 3, 25),
|
|
"SSE2": (1, 0, 3, 26),
|
|
"SSE3": (1, 0, 2, 0),
|
|
"SSSE3": (1, 0, 2, 9),
|
|
"SSE4.1": (1, 0, 2, 19),
|
|
"SSE4.2": (1, 0, 2, 20),
|
|
"SSE4a": (0x80000001, 0, 2, 6),
|
|
"AVX": (1, 0, 2, 28),
|
|
"AVX2": (7, 0, 1, 5)
|
|
}
|
|
|
|
cpu = cpuid.CPUID()
|
|
simd_feature_support = []
|
|
|
|
for feature, address in simd_features_map.items():
|
|
if self.is_set(cpu, *address):
|
|
simd_feature_support.append(feature)
|
|
|
|
return ", ".join(simd_feature_support) if simd_feature_support else "SIMD Capabilities Unknown"
|
|
|
|
def cpu(self):
|
|
cpus = c.Win32_Processor()
|
|
|
|
cpu_brand = cpus[-1].Manufacturer
|
|
cpu_model = cpus[-1].Name.split("with")[0].split("@")[0].strip()
|
|
cpu_description = cpus[-1].Description
|
|
number_of_cores = cpus[-1].NumberOfCores or 0
|
|
|
|
if "Intel" in cpu_brand:
|
|
cpu_brand = "Intel"
|
|
elif "AMD" in cpu_brand:
|
|
cpu_brand = "AMD"
|
|
|
|
return {
|
|
"Manufacturer": cpu_brand,
|
|
"Processor Name": cpu_model,
|
|
"Codename": self.lookup_codename(cpu_model, cpu_description),
|
|
"Core Count": str(number_of_cores * len(cpus)).zfill(2),
|
|
"CPU Count": str(len(cpus)).zfill(2),
|
|
"SIMD Features": self.get_simd_features()
|
|
}
|
|
|
|
def gpu(self):
|
|
gpu_info = {}
|
|
|
|
registry_path = r"SYSTEM\ControlSet001\Control\Class\{4d36e968-e325-11ce-bfc1-08002be10318}"
|
|
resize_bar_status = {}
|
|
|
|
try:
|
|
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, registry_path) as base_key:
|
|
index = 0
|
|
|
|
while True:
|
|
try:
|
|
subkey_name = winreg.EnumKey(base_key, index)
|
|
index += 1
|
|
subkey_path = f"{registry_path}\\{subkey_name}"
|
|
|
|
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, subkey_path) as gpu_key:
|
|
is_resize_bar_enabled = False
|
|
value_index = 0
|
|
|
|
while True:
|
|
try:
|
|
reg_key, value, reg_type = winreg.EnumValue(gpu_key, value_index)
|
|
value_index += 1
|
|
|
|
if reg_key == "KMD_RebarControlMode" and value == 1:
|
|
is_resize_bar_enabled = True
|
|
elif reg_key == "MatchingDeviceId":
|
|
pnp_device_id = value.upper()
|
|
except OSError:
|
|
break
|
|
|
|
if resize_bar_status.get(pnp_device_id, False) == True:
|
|
continue
|
|
|
|
resize_bar_status[pnp_device_id] = is_resize_bar_enabled
|
|
except OSError:
|
|
break
|
|
except FileNotFoundError:
|
|
pass
|
|
except Exception as e:
|
|
pass
|
|
|
|
for device in self.devices_by_class.get("Display"):
|
|
device_name = device.Name or "Unknown"
|
|
device_class = device.PNPClass or "Unknown"
|
|
pnp_device_id = device.PNPDeviceID
|
|
|
|
if not pnp_device_id or not pnp_device_id.startswith("PCI"):
|
|
continue
|
|
|
|
device_info = self.parse_device_path(pnp_device_id)
|
|
del device_info["Bus Type"]
|
|
device_info = {**self.classify_gpu(device_info.get("Device ID")), **device_info}
|
|
|
|
if "Unknown" in (device_name, device_class):
|
|
try:
|
|
device_name = self.pci_ids.get(device_info.get("Device ID")[:4]).get("devices")[device_info.get("Device ID")[5:]]
|
|
except:
|
|
pass
|
|
|
|
device_info.update(self.get_device_location_paths(device))
|
|
|
|
def extract_key_parts(device_id):
|
|
match = re.search(r"VEN_(\w+)&DEV_(\w+)", device_id)
|
|
return match.groups() if match else None
|
|
|
|
for gpu_id, resize_bar_enabled in resize_bar_status.items():
|
|
gpu_parts = extract_key_parts(gpu_id)
|
|
pnp_parts = extract_key_parts(pnp_device_id)
|
|
|
|
if gpu_parts and pnp_parts and gpu_parts == pnp_parts:
|
|
device_info["Resizable BAR"] = "Enabled" if resize_bar_enabled else "Disabled"
|
|
|
|
gpu_info[self.utils.get_unique_key(device_name, gpu_info)] = device_info
|
|
|
|
return dict(sorted(gpu_info.items(), key=lambda item: item[1].get("Device Type", "")))
|
|
|
|
def monitor(self):
|
|
monitor_info = {}
|
|
|
|
monitor_properties = self.devices_by_class.get("Monitor")
|
|
|
|
try:
|
|
wmi_service = wmi.WMI(namespace="root\\wmi")
|
|
|
|
monitor_ids = wmi_service.WmiMonitorID()
|
|
connection_params = wmi_service.WmiMonitorConnectionParams()
|
|
source_modes = wmi_service.WmiMonitorListedSupportedSourceModes()
|
|
except:
|
|
monitor_ids = connection_params = source_modes = []
|
|
|
|
for monitor_property in monitor_properties:
|
|
try:
|
|
monitor_id = next((monitor_id for monitor_id in monitor_ids if monitor_property.PNPDeviceID in monitor_id.InstanceName.upper()), None)
|
|
user_friendly_name = monitor_id.UserFriendlyName
|
|
monitor_name = bytes(user_friendly_name).decode('ascii').rstrip('\x00')
|
|
except:
|
|
monitor_name = monitor_property.PNPDeviceID.split("\\")[1]
|
|
|
|
try:
|
|
connection_param = next((connection_param for connection_param in connection_params if monitor_property.PNPDeviceID in connection_param.InstanceName.upper()), None)
|
|
video_output_type = connection_param.VideoOutputTechnology
|
|
|
|
if video_output_type == 0:
|
|
video_output_type = "VGA"
|
|
elif video_output_type == 4:
|
|
video_output_type = "DVI"
|
|
elif video_output_type == 5:
|
|
video_output_type = "HDMI"
|
|
elif video_output_type == 6:
|
|
video_output_type = "LVDS"
|
|
elif video_output_type == 10:
|
|
video_output_type = "DP"
|
|
elif video_output_type == 11:
|
|
video_output_type = "eDP"
|
|
elif video_output_type == -2147483648:
|
|
video_output_type = "Internal"
|
|
else:
|
|
video_output_type = "Uninitialized"
|
|
except:
|
|
video_output_type = "Uninitialized"
|
|
|
|
max_h_active = 0
|
|
max_v_active = 0
|
|
|
|
try:
|
|
source_mode = next((source_mode for source_mode in source_modes if monitor_property.PNPDeviceID in source_mode.InstanceName.upper()), None)
|
|
monitor_source_modes = source_mode.MonitorSourceModes
|
|
|
|
for monitor_source_mode in monitor_source_modes:
|
|
max_h_active = max(max_h_active, monitor_source_mode.HorizontalActivePixels)
|
|
max_v_active = max(max_v_active, monitor_source_mode.VerticalActivePixels)
|
|
except:
|
|
pass
|
|
|
|
connected_gpu = None
|
|
parent_device_id = monitor_property.GetDeviceProperties(["DEVPKEY_Device_Parent"])[0][0].Data
|
|
for device in self.devices_by_class.get("Display"):
|
|
device_name = device.Name or "Unknown"
|
|
pnp_device_id = device.PNPDeviceID
|
|
|
|
if pnp_device_id and pnp_device_id.startswith("PCI") and pnp_device_id.upper() == parent_device_id.upper():
|
|
connected_gpu = device_name
|
|
break
|
|
|
|
unique_monitor_name = self.utils.get_unique_key(monitor_name, monitor_info)
|
|
monitor_info[unique_monitor_name] = {
|
|
"Connector Type": video_output_type,
|
|
"Resolution": "{}x{}".format(max_h_active, max_v_active)
|
|
}
|
|
if connected_gpu:
|
|
monitor_info[unique_monitor_name]["Connected GPU"] = connected_gpu
|
|
|
|
return monitor_info
|
|
|
|
def network(self):
|
|
network_info = {}
|
|
|
|
for device in self.devices_by_class.get("Net"):
|
|
device_name = device.Name or "Unknown"
|
|
pnp_device_id = device.PNPDeviceID
|
|
|
|
if not pnp_device_id:
|
|
continue
|
|
|
|
device_info = self.parse_device_path(pnp_device_id)
|
|
|
|
if device_info.get("Bus Type") == "PCI":
|
|
device_info.update(self.get_device_location_paths(device))
|
|
elif device_info.get("Bus Type") == "USB":
|
|
pass
|
|
else:
|
|
continue
|
|
|
|
network_info[self.utils.get_unique_key(device_name, network_info)] = device_info
|
|
|
|
return network_info
|
|
|
|
def sound(self):
|
|
audio_endpoints = {}
|
|
|
|
for endpoint in self.devices_by_class.get("AudioEndpoint"):
|
|
endpoint_name = (endpoint.Name or "Unknown").split(" (")[0]
|
|
parent_device_id = endpoint.GetDeviceProperties(["DEVPKEY_Device_Parent"])[0][0].Data.upper()
|
|
|
|
if parent_device_id not in audio_endpoints:
|
|
audio_endpoints[parent_device_id] = []
|
|
|
|
audio_endpoints[parent_device_id].append(endpoint_name)
|
|
|
|
sound_info = {}
|
|
|
|
for device in self.devices_by_class.get("MEDIA"):
|
|
device_name = device.Name or "Unknown"
|
|
pnp_device_id = device.PNPDeviceID
|
|
|
|
if not pnp_device_id:
|
|
continue
|
|
|
|
device_info = self.parse_device_path(pnp_device_id)
|
|
|
|
if not device_info.get("Bus Type").endswith(("AUDIO", "USB", "ACP")):
|
|
continue
|
|
|
|
if audio_endpoints.get(pnp_device_id):
|
|
device_info["Audio Endpoints"] = audio_endpoints.get(pnp_device_id)
|
|
|
|
system_device_id = device.GetDeviceProperties(["DEVPKEY_Device_Parent"])[0][0].Data.upper()
|
|
|
|
device_info["Controller Device ID"] = self.parse_device_path(system_device_id).get("Device ID")
|
|
|
|
sound_info[self.utils.get_unique_key(device_name, sound_info)] = device_info
|
|
|
|
return sound_info
|
|
|
|
def usb_controllers(self):
|
|
usb_controller_info = {}
|
|
|
|
for device in self.devices_by_class.get("USB"):
|
|
device_name = device.Name or "Unknown"
|
|
pnp_device_id = device.PNPDeviceID
|
|
|
|
if not pnp_device_id:
|
|
continue
|
|
|
|
device_info = self.parse_device_path(pnp_device_id)
|
|
|
|
if device_info.get("Bus Type") != "PCI":
|
|
continue
|
|
|
|
device_info.update(self.get_device_location_paths(device))
|
|
usb_controller_info[self.utils.get_unique_key(device_name, usb_controller_info)] = device_info
|
|
|
|
return usb_controller_info
|
|
|
|
def input(self):
|
|
input_info = {}
|
|
|
|
device_type_by_service = {
|
|
"i8042prt": "PS/2",
|
|
"kbdclass": "PS/2",
|
|
"kbdhid": "USB",
|
|
"mouhid": "USB",
|
|
"HidUsb": "USB"
|
|
}
|
|
|
|
self.devices_by_class["HIDClass"] = sorted(self.devices_by_class.get("HIDClass"), key=lambda item:item.PNPDeviceID.split("\\")[1])
|
|
acpi_device = None
|
|
seen_ids = set()
|
|
|
|
for device in self.devices_by_class.get("HIDClass") + self.devices_by_class.get("Keyboard") + self.devices_by_class.get("Mouse"):
|
|
device_name = device.Name or "Unknown"
|
|
pnp_device_id = device.PNPDeviceID
|
|
|
|
device_info = self.parse_device_path(pnp_device_id)
|
|
|
|
device_id = (device_info.get("Device") or device_info.get("Device ID") or "").replace("-", "")
|
|
|
|
if self.utils.contains_any(("wireless radio controls", "vendor-defined device", "consumer control device", "system controller"), device_name) or device.ConfigManagerErrorCode != 0 or not device_id:
|
|
continue
|
|
|
|
try:
|
|
device_info["Device Type"] = device_type_by_service[device.Service]
|
|
except:
|
|
if device.PNPClass == "Keyboard":
|
|
device_info["Device Type"] = "Keyboard"
|
|
elif device.PNPClass == "Mouse":
|
|
device_info["Device Type"] = "Mouse"
|
|
|
|
if device.PNPClass == "HIDClass":
|
|
if device_info.get("Bus Type") == "ACPI":
|
|
acpi_device = {
|
|
"Bus Type": device_info.get("Bus Type"),
|
|
"Device": device_id,
|
|
"Device Type": device_name
|
|
}
|
|
continue
|
|
elif acpi_device and device_id == acpi_device.get("Device"):
|
|
device_info.update(acpi_device)
|
|
|
|
if device_id in seen_ids or not device_info.get("Bus Type") in ("ACPI", "USB", "HID") or not device_info.get("Device Type"):
|
|
continue
|
|
|
|
seen_ids.add(device_id)
|
|
|
|
if not device_info.get("Bus Type") in ("ACPI"):
|
|
try:
|
|
device_name = self.usb_ids.get(device_info.get("Device ID")[:4]).get("devices")[device_info.get("Device ID")[5:]]
|
|
except:
|
|
pass
|
|
device_info["Bus Type"] = "USB"
|
|
del device_info["Device Type"]
|
|
|
|
input_info[self.utils.get_unique_key(device_name, input_info)] = device_info
|
|
|
|
return input_info
|
|
|
|
def storage_controllers(self):
|
|
storage_controller_info = {}
|
|
|
|
for device in self.devices_by_class.get("HDC") + self.devices_by_class.get("SCSIAdapter"):
|
|
device_name = device.Name or "Unknown"
|
|
pnp_device_id = device.PNPDeviceID
|
|
|
|
if not pnp_device_id:
|
|
continue
|
|
|
|
device_info = self.parse_device_path(pnp_device_id)
|
|
if not device_info.get("Bus Type") in ("PCI", "VID") or " SD " in device_name or "MMC" in device_name:
|
|
continue
|
|
|
|
try:
|
|
device_name = self.pci_ids.get(device_info.get("Device ID")[:4]).get("devices")[device_info.get("Device ID")[5:]]
|
|
except:
|
|
pass
|
|
|
|
device_info.update(self.get_device_location_paths(device))
|
|
storage_controller_info[self.utils.get_unique_key(device_name, storage_controller_info)] = device_info
|
|
|
|
return storage_controller_info
|
|
|
|
def biometric(self):
|
|
biometric_info = {}
|
|
|
|
for device in self.devices_by_class.get("Biometric"):
|
|
device_name = device.Name or "Unknown"
|
|
pnp_device_id = device.PNPDeviceID
|
|
|
|
if not pnp_device_id:
|
|
continue
|
|
|
|
device_info = self.parse_device_path(pnp_device_id)
|
|
if device_info.get("Bus Type") in ("ROOT", "USB"):
|
|
biometric_info[self.utils.get_unique_key(device_name, biometric_info)] = device_info
|
|
|
|
return biometric_info
|
|
|
|
def bluetooth(self):
|
|
bluetooth_info = {}
|
|
|
|
for device in self.devices_by_class.get("Bluetooth"):
|
|
device_name = device.Name or "Unknown"
|
|
pnp_device_id = device.PNPDeviceID
|
|
|
|
if not pnp_device_id:
|
|
continue
|
|
|
|
device_info = self.parse_device_path(pnp_device_id)
|
|
if device_info.get("Bus Type") in "USB":
|
|
bluetooth_info[self.utils.get_unique_key(device_name, bluetooth_info)] = device_info
|
|
|
|
return bluetooth_info
|
|
|
|
def sd_controller(self):
|
|
sd_controller_info = {}
|
|
|
|
for device in self.devices_by_class.get("SDHost") + self.devices_by_class.get("MTD"):
|
|
device_name = device.Name or "Unknown"
|
|
pnp_device_id = device.PNPDeviceID
|
|
|
|
if not pnp_device_id:
|
|
continue
|
|
|
|
device_info = self.parse_device_path(pnp_device_id)
|
|
sd_controller_info[self.utils.get_unique_key(device_name, sd_controller_info)] = device_info
|
|
|
|
return sd_controller_info
|
|
|
|
def system_devices(self):
|
|
system_device_info = {}
|
|
|
|
for device in self.devices_by_class.get("System"):
|
|
device_name = device.Name or "Unknown"
|
|
pnp_device_id = device.PNPDeviceID
|
|
|
|
if not pnp_device_id:
|
|
continue
|
|
|
|
device_info = self.parse_device_path(pnp_device_id)
|
|
device_info.update(self.get_device_location_paths(device))
|
|
system_device_info[self.utils.get_unique_key(device_name, system_device_info)] = device_info
|
|
|
|
return system_device_info
|
|
|
|
def hardware_collector(self):
|
|
self.utils.head("Hardware Information Collection")
|
|
print("")
|
|
print("Please wait while we gather your hardware details")
|
|
print("")
|
|
self.result = {}
|
|
|
|
steps = [
|
|
('Gathering PnP devices', self.pnp_devices, None),
|
|
('Gathering motherboard information', self.motherboard, "Motherboard"),
|
|
('Gathering CPU information', self.cpu, "CPU"),
|
|
('Gathering GPU information', self.gpu, "GPU"),
|
|
('Gathering monitor information', self.monitor, "Monitor"),
|
|
('Gathering network information', self.network, "Network"),
|
|
('Gathering sound information', self.sound, "Sound"),
|
|
('Gathering USB controllers', self.usb_controllers, "USB Controllers"),
|
|
('Gathering input devices', self.input, "Input"),
|
|
('Gathering storage controllers', self.storage_controllers, "Storage Controllers"),
|
|
('Gathering biometric information', self.biometric, "Biometric"),
|
|
('Gathering bluetooth information', self.bluetooth, "Bluetooth"),
|
|
('Gathering sd controller information', self.sd_controller, "SD Controller"),
|
|
('Gathering system devices', self.system_devices, "System Devices")
|
|
]
|
|
|
|
total_steps = len(steps)
|
|
for index, (message, function, attribute) in enumerate(steps, start=1):
|
|
print(f"[{index}/{total_steps}] {message}...")
|
|
value = function()
|
|
if not attribute:
|
|
continue
|
|
if value:
|
|
self.result[attribute] = value
|
|
else:
|
|
print(" - No {} found.".format(attribute.lower()))
|
|
|
|
print("")
|
|
print("Hardware information collection complete.")
|
|
time.sleep(1) |