1 /* 2 SPDX-FileCopyrightText: 2012 Lukáš Tinkl <ltinkl@redhat.com> 3 4 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 */ 6 7 #include "udisksblock.h" 8 9 #if defined(Q_OS_LINUX) 10 #include <linux/kdev_t.h> 11 #else 12 // taken from linux/kdev_t.h 13 #define MINORBITS 20 14 #define MINORMASK ((1U << MINORBITS) - 1) 15 #define MAJOR(dev) ((unsigned int)((dev) >> MINORBITS)) 16 #define MINOR(dev) ((unsigned int)((dev)&MINORMASK)) 17 #endif 18 19 #include <QDBusConnection> 20 #include <QDBusPendingReply> 21 #include <QDomDocument> 22 #include <QFile> 23 24 #include "udisks_debug.h" 25 26 using namespace Solid::Backends::UDisks2; 27 Block(Device * dev)28Block::Block(Device *dev) 29 : DeviceInterface(dev) 30 { 31 m_devNum = m_device->prop("DeviceNumber").toULongLong(); 32 m_devFile = QFile::decodeName(m_device->prop("Device").toByteArray()); 33 34 // we have a drive (non-block device for udisks), so let's find the corresponding (real) block device 35 if (m_devNum == 0 || m_devFile.isEmpty()) { 36 const QString path = "/org/freedesktop/UDisks2/block_devices"; 37 QDBusMessage call = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, path, DBUS_INTERFACE_INTROSPECT, "Introspect"); 38 QDBusPendingReply<QString> reply = QDBusConnection::systemBus().asyncCall(call); 39 reply.waitForFinished(); 40 41 if (reply.isValid()) { 42 QDomDocument dom; 43 dom.setContent(reply.value()); 44 QDomNodeList nodeList = dom.documentElement().elementsByTagName("node"); 45 for (int i = 0; i < nodeList.count(); i++) { 46 QDomElement nodeElem = nodeList.item(i).toElement(); 47 if (!nodeElem.isNull() && nodeElem.hasAttribute("name")) { 48 const QString udi = path + "/" + nodeElem.attribute("name"); 49 50 Device device(udi); 51 if (device.drivePath() == dev->udi()) { 52 m_devNum = device.prop("DeviceNumber").toULongLong(); 53 m_devFile = QFile::decodeName(device.prop("Device").toByteArray()); 54 break; 55 } 56 } 57 } 58 } else { 59 qCWarning(UDISKS2) << "Failed enumerating UDisks2 objects:" << reply.error().name() << "\n" << reply.error().message(); 60 } 61 } 62 63 // qDebug() << "devnum:" << m_devNum << "dev file:" << m_devFile; 64 } 65 ~Block()66Block::~Block() 67 { 68 } 69 device() const70QString Block::device() const 71 { 72 return m_devFile; 73 } 74 deviceMinor() const75int Block::deviceMinor() const 76 { 77 return MINOR(m_devNum); 78 } 79 deviceMajor() const80int Block::deviceMajor() const 81 { 82 return MAJOR(m_devNum); 83 } 84