This repository has been archived on 2025-07-17. You can view files and clone it, but cannot push or open issues or pull requests.
usbFilter/exFilter/utils.py
2025-07-08 15:54:23 +08:00

131 lines
4.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import usb.core
import usb.util
import json
import os
import subprocess
import re
def enum_usb_devices():
devices = usb.core.find(find_all=True)
result = []
for dev in devices:
vendor_id = hex(dev.idVendor)
product_id = hex(dev.idProduct)
# 获取设备名称,部分设备可能没有字符串描述符
try:
device_name = usb.util.get_string(dev, dev.iProduct) or "Unknown" # 必须以sudo的方式运行脚本
except Exception:
device_name = "Unknown"
# 获取设备路径
try:
bus = dev.bus
address = dev.address
device_path = f"/dev/bus/usb/{bus:03d}/{address:03d}"
except Exception:
device_path = "Unknown"
result.append({
"deviceName": device_name,
"vendorID": vendor_id,
"productID": product_id,
"devicePath": device_path,
"subSystem": "USB"
})
return json.dumps(result, indent=2, ensure_ascii=False)
def enum_pcie_devices():
result = []
pci_devices_path = "/sys/bus/pci/devices"
if not os.path.exists(pci_devices_path):
return json.dumps(result, indent=2, ensure_ascii=False)
for device_dir in os.listdir(pci_devices_path):
device_path = os.path.join(pci_devices_path, device_dir)
try:
# 读取vendor ID和product ID
with open(os.path.join(device_path, "vendor"), "r") as f:
vendor_id = f.read().strip()
with open(os.path.join(device_path, "device"), "r") as f:
product_id = f.read().strip()
# 获取设备名称
device_name = "Unknown"
try:
# 尝试从modalias获取设备信息
modalias_path = os.path.join(device_path, "modalias")
if os.path.exists(modalias_path):
with open(modalias_path, "r") as f:
modalias = f.read().strip()
# 尝试从driver获取驱动名称作为设备名称
driver_path = os.path.join(device_path, "driver")
if os.path.islink(driver_path):
driver_name = os.path.basename(os.readlink(driver_path))
device_name = f"PCIe Device ({driver_name})"
# 尝试从subsystem_device和subsystem_vendor获取更详细信息
subsystem_device_path = os.path.join(device_path, "subsystem_device")
if os.path.exists(subsystem_device_path):
with open(subsystem_device_path, "r") as f:
subsystem_device = f.read().strip()
if device_name == "Unknown":
device_name = f"PCIe Device ({subsystem_device})"
except Exception:
device_name = "Unknown"
# 构建设备路径 (PCI设备路径格式)
pci_device_path = f"/sys/bus/pci/devices/{device_dir}"
result.append({
"deviceName": device_name,
"vendorID": vendor_id,
"productID": product_id,
"devicePath": pci_device_path,
"subSystem": "PCIe"
})
except Exception as e:
# 如果读取某个设备信息失败,跳过该设备
continue
return json.dumps(result, indent=2, ensure_ascii=False)
def checkPid(devPath, logger):
processPid = -1
# 通过device_path查看当前占用该设备的进程pid号
try:
# 首先检查设备路径是否存在
if not os.path.exists(devPath):
return processPid
# 添加-w参数禁用警告使用2>/dev/null重定向标准错误
result = subprocess.run(['lsof', '-w', devPath],
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL,
text=True)
if result.returncode == 0:
output = result.stdout.strip()
if output:
# 使用正则表达式提取PID
# lsof输出格式: COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
pid_match = re.search(r'^\S+\s+(\d+)\s+', output, re.MULTILINE)
if pid_match:
processPid = int(pid_match.group(1))
logger.debug(f"Device {devPath} is currently used by process with PID: {processPid}")
except FileNotFoundError:
logger.error("lsof command not found. Please install lsof: sudo apt-get install lsof")
except Exception as e:
logger.error(f"An error occurred while checking the device: {str(e)}")
return processPid