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
26using namespace Solid::Backends::UDisks2;
27
28Block::Block(Device *dev)
29 : DeviceInterface(dev)
30 , m_devNum(m_device->prop(QStringLiteral("DeviceNumber")).toULongLong())
31 , m_devFile(QFile::decodeName(localFileName: m_device->prop(QStringLiteral("Device")).toByteArray()))
32{
33 // we have a drive (non-block device for udisks), so let's find the corresponding (real) block device
34 if (m_devNum == 0 || m_devFile.isEmpty()) {
35 QDBusMessage call = QDBusMessage::createMethodCall(QStringLiteral(UD2_DBUS_SERVICE),
36 QStringLiteral(UD2_DBUS_PATH_BLOCKDEVICES),
37 QStringLiteral(DBUS_INTERFACE_INTROSPECT),
38 QStringLiteral("Introspect"));
39 QDBusPendingReply<QString> reply = QDBusConnection::systemBus().asyncCall(message: call);
40 reply.waitForFinished();
41
42 if (reply.isValid()) {
43 QDomDocument dom;
44 dom.setContent(data: reply.value());
45 QDomNodeList nodeList = dom.documentElement().elementsByTagName(QStringLiteral("node"));
46 for (int i = 0; i < nodeList.count(); i++) {
47 QDomElement nodeElem = nodeList.item(index: i).toElement();
48 if (!nodeElem.isNull() && nodeElem.hasAttribute(QStringLiteral("name"))) {
49 const QString udi = QStringLiteral(UD2_DBUS_PATH_BLOCKDEVICES) + QLatin1Char('/') + nodeElem.attribute(QStringLiteral("name"));
50
51 Device device(udi);
52 if (device.drivePath() == dev->udi()) {
53 m_devNum = device.prop(QStringLiteral("DeviceNumber")).toULongLong();
54 m_devFile = QFile::decodeName(localFileName: device.prop(QStringLiteral("Device")).toByteArray());
55 m_hintSystem = device.prop(QStringLiteral("HintSystem")).toBool();
56 break;
57 }
58 }
59 }
60 } else {
61 qCWarning(UDISKS2) << "Failed enumerating UDisks2 objects:" << reply.error().name() << QStringLiteral("\n") << reply.error().message();
62 }
63 }
64
65 // qDebug() << "devnum:" << m_devNum << "dev file:" << m_devFile;
66}
67
68Block::~Block()
69{
70}
71
72QString Block::device() const
73{
74 return m_devFile;
75}
76
77int Block::deviceMinor() const
78{
79 return MINOR(m_devNum);
80}
81
82int Block::deviceMajor() const
83{
84 return MAJOR(m_devNum);
85}
86
87bool Block::isSystem() const
88{
89 return m_hintSystem;
90}
91
92#include "moc_udisksblock.cpp"
93

source code of solid/src/solid/devices/backends/udisks2/udisksblock.cpp