From 8f76b98ccc30b7d0b574ce50ba602de4f2126cb6 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Sat, 7 Apr 2012 18:21:15 -0500 Subject: [PATCH] Classify power and backlight devices Parse ACPI device types --- tdecore/hwlibdata/CMakeLists.txt | 1 + tdecore/hwlibdata/pnpdev/CMakeLists.txt | 17 ++ tdecore/hwlibdata/pnpdev/pnp.ids | 155 +++++++++++++++ tdecore/tdehardwaredevices.cpp | 239 ++++++++++++++++++++++-- tdecore/tdehardwaredevices.h | 31 +++ 5 files changed, 426 insertions(+), 17 deletions(-) create mode 100644 tdecore/hwlibdata/pnpdev/CMakeLists.txt create mode 100644 tdecore/hwlibdata/pnpdev/pnp.ids diff --git a/tdecore/hwlibdata/CMakeLists.txt b/tdecore/hwlibdata/CMakeLists.txt index d18877c5f..fe7cee67d 100644 --- a/tdecore/hwlibdata/CMakeLists.txt +++ b/tdecore/hwlibdata/CMakeLists.txt @@ -11,3 +11,4 @@ add_subdirectory( classrules ) +add_subdirectory( pnpdev ) diff --git a/tdecore/hwlibdata/pnpdev/CMakeLists.txt b/tdecore/hwlibdata/pnpdev/CMakeLists.txt new file mode 100644 index 000000000..61b1df38e --- /dev/null +++ b/tdecore/hwlibdata/pnpdev/CMakeLists.txt @@ -0,0 +1,17 @@ +################################################# +# +# (C) 2012 Timothy Pearson +# kb9vqf (AT) pearsoncomputing.net +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + + +##### other data ################################ + +install( FILES + pnp.ids + DESTINATION ${DATA_INSTALL_DIR}/tdehwlib/pnpdev ) diff --git a/tdecore/hwlibdata/pnpdev/pnp.ids b/tdecore/hwlibdata/pnpdev/pnp.ids new file mode 100644 index 000000000..8fabfe093 --- /dev/null +++ b/tdecore/hwlibdata/pnpdev/pnp.ids @@ -0,0 +1,155 @@ +# The information provided in this PNP ID to friendly name mapping table was obtained from +# multiple public sources, as well as this authoritative publicly accessible file: +# ftp://ftpmicrosoftcom/developr/drg/plug-and-play/devidstxt +# +# This file is provided soley in the interest of cross platform compatibility +# It only contains information on certain generic core system devices that cannot be looked up via another method +# All marks are the property of their owners +# +# A typical PNP ID takes the form of PNPxxxx:yy +# +# Some additional information that may be useful for applications parsing PNP device ID strings: +# PNP0xxx System devices +# PNP8xxx Network adapters +# PNPAxxx SCSI, proprietary CD adapters +# PNPBxxx Sound, video capture, multimedia +# PNPCxxx - PNPDxxx Modems +# +# The two digit code yy appears to be a PCI device type code followed by a subtype code and should be parsed as such + +PNP0802 Microsoft® Sound System-compatible device + +PNP0000 AT Interrupt Controller +PNP0001 EISA Interrupt Controller +PNP0002 MCA Interrupt Controller +PNP0003 APIC +PNP0004 Cyrix SLiC MP Interrupt Controller + +PNP0100 AT Timer +PNP0101 EISA Timer +PNP0102 MCA Timer +PNP0103 High Precision Event Timer + +PNP0200 AT DMA Controller +PNP0201 EISA DMA Controller +PNP0202 MCA DMA Controller + +PNP0300 IBM PC/XT keyboard controller (83-key) +PNP0301 IBM PC/AT keyboard controller (86-key) +PNP0302 IBM PC/XT keyboard controller (84-key) +PNP0303 IBM Enhanced (101/102-key, PS/2 mouse support) +PNP0304 Olivetti Keyboard (83-key) +PNP0305 Olivetti Keyboard (102-key) +PNP0306 Olivetti Keyboard (86-key) +PNP0307 Microsoft® Windows(R) Keyboard +PNP0308 General Input Device Emulation Interface (GIDEI) legacy +PNP0309 Olivetti Keyboard (A101/102 key) +PNP030A AT&T 302 keyboard +PNP030B Reserved by Microsoft® +PNP0320 Japanese 106-key keyboard A01 +PNP0321 Japanese 101-key keyboard +PNP0322 Japanese AX keyboard +PNP0323 Japanese 106-key keyboard 002/003 +PNP0324 Japanese 106-key keyboard 001 +PNP0325 Japanese Toshiba Desktop keyboard +PNP0326 Japanese Toshiba Laptop keyboard +PNP0327 Japanese Toshiba Notebook keyboard +PNP0340 Korean 84-key keyboard +PNP0341 Korean 86-key keyboard +PNP0342 Korean Enhanced keyboard +PNP0343 Korean Enhanced keyboard 101b +PNP0343 Korean Enhanced keyboard 101c +PNP0344 Korean Enhanced keyboard 103 + +PNP0400 Standard LPT Printer Port +PNP0401 ECP Printer Port + +PNP0500 Standard PC Serial Port +PNP0501 16550A-compatible Serial Port +PNP0502 Multiport Serial Device (non-intelligent 16550) +PNP0510 Generic IRDA-compatible Device +PNP0511 Generic IRDA-compatible Device + +PNP0600 Generic ESDI/IDE/ATA Compatible Hard Disk Controller +PNP0603 Generic IDE supporting Microsoft® Device Bay Specification +PNP0700 PC Standard Floppy Disk Controller +PNP0701 Microsoft® Device Bay Compatible Floppy Controller + +PNP0802 Microsoft® Sound System compatible device + +PNP0900 VGA Compatible Display Controller +PNP09FF Plug and Play Monitor (VESA DDC) + +PNP0A00 ISA Bus +PNP0A01 EISA Bus +PNP0A02 MCA Bus +PNP0A03 PCI Bus +PNP0A04 VESA/VL Bus +PNP0A05 Generic ACPI Bus +PNP0A06 Generic ACPI Extended-IO Bus (EIO bus) + +PNP0800 AT-style Speaker +PNP0B00 AT Real-Time Clock +PNP0C00 Plug and Play BIOS +PNP0C01 System Board +PNP0C02 Plug and Play Motherboard Register Resource +PNP0C03 Plug and Play BIOS Event Notification Interrupt +PNP0C04 Math Coprocessor +PNP0C05 APM BIOS +PNP0C06 Early Plug and Play BIOS +PNP0C07 Early Plug and Play BIOS +PNP0C08 ACPI System Board +PNP0C09 ACPI Embedded Controller +PNP0C0A ACPI Control Method Battery +PNP0C0B ACPI Fan +PNP0C0C ACPI Power Button +PNP0C0D ACPI Lid Switch +PNP0C0E ACPI Sleep Button +PNP0C0F PCI Interrupt Link +PNP0C10 ACPI System Indicator +PNP0C11 ACPI Thermal Zone +PNP0C12 Device Bay Controller +PNP0C13 Plug and Play BIOS + +PNP0E00 Intel 82365-Compatible PCMCIA Controller +PNP0E01 Cirrus Logic CL-PD6720 PCMCIA Controller +PNP0E02 VLSI VL82C146 PCMCIA Controller +PNP0E03 Intel 82365-compatible CardBus controller + +PNP0F00 Microsoft® Bus Mouse +PNP0F01 Microsoft® Serial Mouse +PNP0F02 Microsoft® InPort Mouse +PNP0F03 Microsoft® PS/2-style Mouse +PNP0F04 Mouse Systems Mouse +PNP0F05 Mouse Systems 3-Button Mouse +PNP0F06 Genius Mouse +PNP0F07 Genius Mouse +PNP0F08 Logitech Serial Mouse +PNP0F09 Microsoft® BallPoint Serial Mouse +PNP0F0A Microsoft® Plug and Play Mouse +PNP0F0B Microsoft® Plug and Play BallPoint Mouse +PNP0F0C Microsoft®-compatible Serial Mouse +PNP0F0D Microsoft®-compatible InPort-compatible Mouse +PNP0F0E Microsoft®-compatible PS/2-style Mouse +PNP0F0F Microsoft®-compatible Serial BallPoint-compatible Mouse +PNP0F10 Texas Instruments QuickPort Mouse +PNP0F11 Microsoft®-compatible Bus Mouse +PNP0F12 Logitech PS/2-style Mouse +PNP0F13 PS/2 Port for PS/2-style Mice +PNP0F14 Microsoft® Kids Mouse +PNP0F15 Logitech bus mouse +PNP0F16 Logitech SWIFT device +PNP0F17 Logitech-compatible serial mouse +PNP0F18 Logitech-compatible bus mouse +PNP0F19 Logitech-compatible PS/2-style Mouse +PNP0F1A Logitech-compatible SWIFT Device +PNP0F1B HP Omnibook Mouse +PNP0F1C Compaq LTE Trackball PS/2-style Mouse +PNP0F1D Compaq LTE Trackball Serial Mouse +PNP0F1E Microsoft® Kids Trackball Mouse +PNP0F1F Reserved by Microsoft® Input Device Group +PNP0F20 Reserved by Microsoft® Input Device Group +PNP0F21 Reserved by Microsoft® Input Device Group +PNP0F22 Reserved by Microsoft® Input Device Group +PNP0F23 Reserved by Microsoft® Input Device Group +PNP0FFF Reserved by Microsoft® Systems \ No newline at end of file diff --git a/tdecore/tdehardwaredevices.cpp b/tdecore/tdehardwaredevices.cpp index ba2fc5bfb..c73acc748 100644 --- a/tdecore/tdehardwaredevices.cpp +++ b/tdecore/tdehardwaredevices.cpp @@ -37,6 +37,18 @@ #include #include +// BEGIN BLOCK +// Copied from include/linux/genhd.h +#define GENHD_FL_REMOVABLE 1 +#define GENHD_FL_MEDIA_CHANGE_NOTIFY 4 +#define GENHD_FL_CD 8 +#define GENHD_FL_UP 16 +#define GENHD_FL_SUPPRESS_PARTITION_INFO 32 +#define GENHD_FL_EXT_DEVT 64 +#define GENHD_FL_NATIVE_CAPACITY 128 +#define GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE 256 +// END BLOCK + // NOTE TO DEVELOPERS // This command will greatly help when attempting to find properties to distinguish one device from another // udevadm info --query=all --path=/sys/.... @@ -128,6 +140,22 @@ void TDEGenericDevice::setModelID(TQString id) { m_modelID.replace("0x", ""); } +TQString &TDEGenericDevice::vendorEncoded() { + return m_vendorenc; +} + +void TDEGenericDevice::setVendorEncoded(TQString id) { + m_vendorenc = id; +} + +TQString &TDEGenericDevice::modelEncoded() { + return m_modelenc; +} + +void TDEGenericDevice::setModelEncoded(TQString id) { + m_modelenc = id; +} + TQString &TDEGenericDevice::subVendorID() { return m_subvendorID; } @@ -223,6 +251,14 @@ TQString TDEGenericDevice::friendlyName() { else if (m_modAlias.lower().startsWith("usb")) { m_friendlyName = KGlobal::hardwareDevices()->findUSBDeviceName(m_vendorID, m_modelID, m_subvendorID, m_submodelID); } + else { + TQString pnpgentype = systemPath(); + pnpgentype.remove(0, pnpgentype.findRev("/")+1); + pnpgentype.truncate(pnpgentype.find(":")); + if (pnpgentype.startsWith("PNP")) { + m_friendlyName = KGlobal::hardwareDevices()->findPNPDeviceName(pnpgentype); + } + } } if (m_friendlyName.isNull()) { @@ -345,6 +381,27 @@ void TDEStorageDevice::setSlaveDevices(TQStringList sd) { } TQString TDEStorageDevice::friendlyName() { + // Return the actual storage device name + TQString devicevendorid = vendorEncoded(); + TQString devicemodelid = modelEncoded(); + + devicevendorid.replace("\\x20", " "); + devicemodelid.replace("\\x20", " "); + + devicevendorid = devicevendorid.stripWhiteSpace(); + devicemodelid = devicemodelid.stripWhiteSpace(); + devicevendorid = devicevendorid.simplifyWhiteSpace(); + devicemodelid = devicemodelid.simplifyWhiteSpace(); + + TQString devicename = devicevendorid + " " + devicemodelid; + + devicename = devicename.stripWhiteSpace(); + devicename = devicename.simplifyWhiteSpace(); + + if (devicename != "") { + return devicename; + } + if (isDiskOfType(TDEDiskDeviceType::Floppy)) { return friendlyDeviceType(); } @@ -352,7 +409,7 @@ TQString TDEStorageDevice::friendlyName() { TQString label = diskLabel(); if (label.isNull()) { if (deviceSize() > 0) { - if (checkDiskStatus(TDEDiskDeviceStatus::Removable)) { + if (checkDiskStatus(TDEDiskDeviceStatus::Hotpluggable)) { label = i18n("%1 Removable Device").arg(deviceFriendlySize()); } else { @@ -399,7 +456,7 @@ TQString TDEStorageDevice::friendlyDeviceType() { if (isDiskOfType(TDEDiskDeviceType::HDD)) { ret = i18n("Hard Disk Drive"); - if (checkDiskStatus(TDEDiskDeviceStatus::Removable)) { + if (checkDiskStatus(TDEDiskDeviceStatus::Hotpluggable)) { ret = i18n("Removable Storage"); } if (isDiskOfType(TDEDiskDeviceType::CompactFlash)) { @@ -447,7 +504,7 @@ TQPixmap TDEStorageDevice::icon(KIcon::StdSizes size) { if (isDiskOfType(TDEDiskDeviceType::HDD)) { ret = DesktopIcon("hdd_unmount", size); - if (checkDiskStatus(TDEDiskDeviceStatus::Removable)) { + if (checkDiskStatus(TDEDiskDeviceStatus::Hotpluggable)) { ret = DesktopIcon("usbpendrive_unmount", size); } if (isDiskOfType(TDEDiskDeviceType::CompactFlash)) { @@ -714,6 +771,7 @@ TDEHardwareDevices::TDEHardwareDevices() { // Initialize members pci_id_map = 0; usb_id_map = 0; + pnp_id_map = 0; // Set up device list m_deviceList.setAutoDelete( TRUE ); // the list owns the objects @@ -769,6 +827,9 @@ TDEHardwareDevices::~TDEHardwareDevices() { if (usb_id_map) { delete usb_id_map; } + if (pnp_id_map) { + delete pnp_id_map; + } } void TDEHardwareDevices::rescanDeviceInformation(TDEGenericDevice* hwdevice) { @@ -1479,12 +1540,13 @@ TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TD TQString systempath(udev_device_get_syspath(dev)); TQString devicevendorid(udev_device_get_property_value(dev, "ID_VENDOR_ID")); TQString devicemodelid(udev_device_get_property_value(dev, "ID_MODEL_ID")); + TQString devicevendoridenc(udev_device_get_property_value(dev, "ID_VENDOR_ENC")); + TQString devicemodelidenc(udev_device_get_property_value(dev, "ID_MODEL_ENC")); TQString devicesubvendorid(udev_device_get_property_value(dev, "ID_SUBVENDOR_ID")); TQString devicesubmodelid(udev_device_get_property_value(dev, "ID_SUBMODEL_ID")); TQString devicetypestring(udev_device_get_property_value(dev, "ID_TYPE")); TQString devicetypestring_alt(udev_device_get_property_value(dev, "DEVTYPE")); TQString devicepciclass(udev_device_get_property_value(dev, "PCI_CLASS")); - bool removable = false; TDEGenericDevice* device = existingdevice; // FIXME @@ -1597,7 +1659,38 @@ TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TD } else if (devicetype.isNull()) { if (devicesubsystem == "acpi") { - if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherACPI); + // If the ACPI device exposes a system path ending in /PNPxxxx:yy, the device type can be precisely determined + // See ftp://ftp.microsoft.com/developr/drg/plug-and-play/devids.txt for more information + TQString pnpgentype = systempath; + pnpgentype.remove(0, pnpgentype.findRev("/")+1); + pnpgentype.truncate(pnpgentype.find(":")); + if (pnpgentype.startsWith("PNP")) { + // We support a limited number of specific PNP IDs here + if (pnpgentype == "PNP0C0A") { + if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Battery); + } + else if (pnpgentype == "PNP0C0B") { + if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::ThermalControl); + } + else if (pnpgentype == "PNP0C0C") { + if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Power); + } + else if (pnpgentype == "PNP0C0D") { + if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Power); + } + else if (pnpgentype == "PNP0C0E") { + if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Power); + } + else if (pnpgentype == "PNP0C11") { + if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::ThermalSensor); + } + else { + if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherACPI); + } + } + else { + if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::OtherACPI); + } } else if (devicesubsystem == "input") { // Figure out if this device is a mouse, keyboard, or something else @@ -1712,6 +1805,18 @@ TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TD || (devicesubsystem == "hidraw")) { if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::HID); } + if (devicesubsystem == "power_supply") { + TQString powersupplyname(udev_device_get_property_value(dev, "POWER_SUPPLY_NAME")); + if (powersupplyname.upper().startsWith("AC")) { + if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Power); + } + else { + if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Battery); + } + } + if (devicesubsystem == "backlight") { + if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Power); + } // Moderate accuracy classification, if PCI device class is available // See http://www.acm.uiuc.edu/sigops/roll_your_own/7.c.1.html for codes and meanings @@ -1773,6 +1878,8 @@ TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TD device->setSystemPath(systempath); device->setVendorID(devicevendorid); device->setModelID(devicemodelid); + device->setVendorEncoded(devicevendoridenc); + device->setModelEncoded(devicemodelidenc); device->setSubVendorID(devicesubvendorid); device->setSubModelID(devicesubmodelid); device->setModuleAlias(devicemodalias); @@ -1788,18 +1895,37 @@ TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TD } if (device->type() == TDEGenericDeviceType::Disk) { - // Determine if disk is removable - TQString removablenodename = udev_device_get_syspath(dev); - removablenodename.append("/removable"); - FILE *fp = fopen(removablenodename.ascii(),"r"); - if (fp) { - if (fgetc(fp) == '1') { - removable = true; - } - fclose(fp); + bool removable = false; + bool hotpluggable = false; + + // We can get the removable flag, but we have no idea if the device has the ability to notify on media insertion/removal + // If there is no such notification possible, then we should not set the removable flag + // udev can be such an amazing pain at times + // It exports a /capabilities node with no info on what the bits actually mean + // This information is very poorly documented as a set of #defines in include/linux/genhd.h + // We are specifically interested in GENHD_FL_REMOVABLE and GENHD_FL_MEDIA_CHANGE_NOTIFY + // The "removable" flag should also really be renamed to "hotpluggable", as that is far more precise... + TQString capabilitynodename = systempath; + capabilitynodename.append("/capability"); + TQFile capabilityfile( capabilitynodename ); + unsigned int capabilities = 0; + if ( capabilityfile.open( IO_ReadOnly ) ) { + TQTextStream stream( &capabilityfile ); + TQString capabilitystring; + capabilitystring = stream.readLine(); + capabilities = capabilitystring.toUInt(); + capabilityfile.close(); + } + if (capabilities & GENHD_FL_REMOVABLE) { + // FIXME + // For added fun this is not always true; i.e. GENHD_FL_REMOVABLE can be set when the device cannot be hotplugged (floppy drives). + hotpluggable = true; + } + if (capabilities & GENHD_FL_MEDIA_CHANGE_NOTIFY) { + removable = true; } - // See if any other devices are exclusively using this device, such as the Device Mapper| + // See if any other devices are exclusively using this device, such as the Device Mapper TQStringList holdingDeviceNodes; TQString holdersnodename = udev_device_get_syspath(dev); holdersnodename.append("/holders/"); @@ -1955,6 +2081,9 @@ TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TD if (removable) { diskstatus = diskstatus | TDEDiskDeviceStatus::Removable; } + if (hotpluggable) { + diskstatus = diskstatus | TDEDiskDeviceStatus::Hotpluggable; + } if ((filesystemtype.upper() != "CRYPTO_LUKS") && (filesystemtype.upper() != "CRYPTO") && (!filesystemtype.isNull())) { diskstatus = diskstatus | TDEDiskDeviceStatus::ContainsFilesystem; @@ -1962,7 +2091,7 @@ TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TD // Set mountable flag if device is likely to be mountable diskstatus = diskstatus | TDEDiskDeviceStatus::Mountable; - if ((!devicetypestring.upper().isNull()) && (disktype & TDEDiskDeviceType::HDD)) { + if ((devicetypestring.upper().isNull()) && (disktype & TDEDiskDeviceType::HDD)) { diskstatus = diskstatus & ~TDEDiskDeviceStatus::Mountable; } if (removable) { @@ -2041,6 +2170,8 @@ TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TD device->setSystemPath(systempath); device->setVendorID(devicevendorid); device->setModelID(devicemodelid); + device->setVendorEncoded(devicevendoridenc); + device->setModelEncoded(devicemodelidenc); device->setSubVendorID(devicesubvendorid); device->setSubModelID(devicesubmodelid); device->setDeviceDriver(devicedriver); @@ -2189,12 +2320,13 @@ void TDEHardwareDevices::addCoreSystemDevices() { while ( !stream.atEnd() ) { line = stream.readLine(); // WARNING This routine assumes that "processor" is always the first entry in /proc/cpuinfo! + // FIXME Parse all available information, such as frequency, etc. if (line.startsWith("processor")) { line.remove(0, line.find(":")+1); line = line.stripWhiteSpace(); processorNumber = line.toInt(); hwdevice = new TDEGenericDevice(TDEGenericDeviceType::CPU); - hwdevice->setSystemPath(TQString("/sys/devices/cpu/cpu%1").arg(processorNumber)); // FIXME: A system path is required, but I can't give a real, extant, unique path to the hardware manager due to kernel limitations + hwdevice->setSystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber)); m_deviceList.append(hwdevice); } if (line.startsWith("model name")) { @@ -2206,6 +2338,9 @@ void TDEHardwareDevices::addCoreSystemDevices() { } file.close(); } + + // FIXME + // For each CPU, look for cpufreq and parse as much information as possible } TQString TDEHardwareDevices::findPCIDeviceName(TQString vendorid, TQString modelid, TQString subvendorid, TQString submodelid) { @@ -2428,6 +2563,76 @@ TQString TDEHardwareDevices::findUSBDeviceName(TQString vendorid, TQString model } } +TQString TDEHardwareDevices::findPNPDeviceName(TQString pnpid) { + TQString friendlyName = TQString::null; + + if (!pnp_id_map) { + pnp_id_map = new TDEDeviceIDMap; + + TQStringList hardware_info_directories(KGlobal::dirs()->resourceDirs("data")); + TQString hardware_info_directory_suffix("tdehwlib/pnpdev/"); + TQString hardware_info_directory; + TQString database_filename; + + for ( TQStringList::Iterator it = hardware_info_directories.begin(); it != hardware_info_directories.end(); ++it ) { + hardware_info_directory = (*it); + hardware_info_directory += hardware_info_directory_suffix; + + if (KGlobal::dirs()->exists(hardware_info_directory)) { + database_filename = hardware_info_directory + "pnp.ids"; + if (TQFile::exists(database_filename)) { + break; + } + } + } + + if (!TQFile::exists(database_filename)) { + printf("[tdehardwaredevices] Unable to locate PNP information database pnp.ids\n\r"); fflush(stdout); + return i18n("Unknown PNP Device"); + } + + TQFile database(database_filename); + if (database.open(IO_ReadOnly)) { + TQTextStream stream(&database); + TQString line; + TQString pnpID; + TQString vendorName; + TQString deviceMapKey; + TQStringList devinfo; + while (!stream.atEnd()) { + line = stream.readLine(); + if ((!line.upper().startsWith("\t")) && (!line.upper().startsWith("#"))) { + devinfo = TQStringList::split('\t', line, false); + if (devinfo.count() > 1) { + pnpID = *(devinfo.at(0)); + vendorName = *(devinfo.at(1));; + vendorName = vendorName.stripWhiteSpace(); + deviceMapKey = pnpID.upper().stripWhiteSpace(); + if (!deviceMapKey.isNull()) { + pnp_id_map->insert(deviceMapKey, vendorName, true); + } + } + } + } + database.close(); + } + else { + printf("[tdehardwaredevices] Unable to open PNP information database %s\n\r", database_filename.ascii()); fflush(stdout); + } + } + + if (pnp_id_map) { + TQString deviceName; + + deviceName = (*pnp_id_map)[pnpid]; + + return deviceName; + } + else { + return i18n("Unknown PNP Device"); + } +} + TQString TDEHardwareDevices::getFriendlyDeviceTypeStringFromType(TDEGenericDeviceType::TDEGenericDeviceType query) { TQString ret = "Unknown Device"; diff --git a/tdecore/tdehardwaredevices.h b/tdecore/tdehardwaredevices.h index f284a7d0c..d30c125c2 100644 --- a/tdecore/tdehardwaredevices.h +++ b/tdecore/tdehardwaredevices.h @@ -149,6 +149,7 @@ enum TDEDiskDeviceStatus { UsedByDevice = 0x00000010, UsesDevice = 0x00000020, ContainsFilesystem = 0x00000040, + Hotpluggable = 0x00000080, Other = 0x80000000 }; @@ -298,6 +299,26 @@ class TDECORE_EXPORT TDEGenericDevice */ void setModelID(TQString id); + /** + * @return a TQString with the encoded vendor, if any + */ + TQString &vendorEncoded(); + + /** + * @param a TQString with the encoded vendor, if any + */ + void setVendorEncoded(TQString id); + + /** + * @return a TQString with the encoded model, if any + */ + TQString &modelEncoded(); + + /** + * @param a TQString with the encoded model, if any + */ + void setModelEncoded(TQString id); + /** * @return a TQString with the subvendor ID, if any */ @@ -396,6 +417,8 @@ class TDECORE_EXPORT TDEGenericDevice TQString m_uniqueID; TQString m_vendorID; TQString m_modelID; + TQString m_vendorenc; + TQString m_modelenc; TQString m_subvendorID; TQString m_submodelID; TQString m_pciClass; @@ -696,6 +719,13 @@ class TDECORE_EXPORT TDEHardwareDevices : public TQObject */ TQString findUSBDeviceName(TQString vendorid, TQString modelid, TQString subvendorid, TQString submodelid); + /** + * Look up the device in the system PNP database + * @param pnpid a TQString containing the PNP ID + * @return a TQString containing the device name, if found + */ + TQString findPNPDeviceName(TQString pnpid); + /** * Get a friendly string describing a device type * @param query a TDEGenericDeviceType::TDEGenericDeviceType specifying a device type @@ -746,6 +776,7 @@ class TDECORE_EXPORT TDEHardwareDevices : public TQObject TDEDeviceIDMap* pci_id_map; TDEDeviceIDMap* usb_id_map; + TDEDeviceIDMap* pnp_id_map; friend class TDEGenericDevice; friend class TDEStorageDevice;