8#include "iokitdevice.h"
9#include "iokitbattery.h"
10#include "iokitgenericinterface.h"
11#include "iokitopticaldisc.h"
12#include "iokitopticaldrive.h"
13#include "iokitprocessor.h"
14#include "iokitstorage.h"
15#include "iokitstorageaccess.h"
16#include "iokitvolume.h"
22#include <sys/sysctl.h>
25#include <IOKit/network/IOEthernetInterface.h>
26#include <IOKit/usb/IOUSBLib.h>
28#include <CoreFoundation/CoreFoundation.h>
32extern bool q_sysctlbyname(
const char *name,
QString &result);
46 mainType = Solid::DeviceInterface::Unknown;
47 if (IOObjectConformsTo(entry,
"AppleACPICPU")) {
48 mainType = Solid::DeviceInterface::Processor;
51 if (IOObjectConformsTo(entry,
"AppleSmartBattery")) {
52 mainType = Solid::DeviceInterface::Battery;
55 const QString bsdName = QStringLiteral(
"BSD Name");
56 const QString leaf = QStringLiteral(
"Leaf");
57 if (IOObjectConformsTo(entry,
"IOCDMedia")
58 || IOObjectConformsTo(entry,
"IODVDMedia")
59 || IOObjectConformsTo(entry,
"IOBDMedia")) {
60 mainType = Solid::DeviceInterface::OpticalDrive;
61 types << mainType << Solid::DeviceInterface::OpticalDisc;
63 if (
properties.contains(bsdName) &&
properties.value(bsdName).toString().startsWith(QStringLiteral(
"disk"))) {
65 || mainType == Solid::DeviceInterface::OpticalDrive) {
66 if (mainType == Solid::DeviceInterface::Unknown) {
67 mainType = Solid::DeviceInterface::StorageDrive;
69 types << Solid::DeviceInterface::StorageDrive;
70 }
else if (mainType == Solid::DeviceInterface::Unknown) {
71 mainType = Solid::DeviceInterface::StorageVolume;
73 types << Solid::DeviceInterface::StorageVolume;
87 CFMutableDictionaryRef propertyDict = 0;
89 if (IORegistryEntryCreateCFProperties(entry, &propertyDict, kCFAllocatorDefault, kNilOptions) != KERN_SUCCESS) {
95 CFRelease(propertyDict);
98 IOObjectGetClass(entry, className);
105static QString getParentDeviceUdi(
const io_registry_entry_t &entry)
107 io_registry_entry_t parent = 0;
108 kern_return_t ret = IORegistryEntryGetParentEntry(entry, kIOServicePlane, &parent);
109 if (ret != KERN_SUCCESS) {
114 CFStringRef
path = IORegistryEntryCopyPath(parent, kIOServicePlane);
119 IOObjectRelease(parent);
124static const QString computerModel()
127 q_sysctlbyname(
"hw.model", qModel);
131class IOKitDevicePrivate
134 inline IOKitDevicePrivate()
135 : type({Solid::DeviceInterface::Unknown})
136 , parentDevice(
nullptr)
139 ~IOKitDevicePrivate()
143 parentDevice =
nullptr;
147 void init(
const QString &udiString,
const io_registry_entry_t &entry);
148 IOKitDevice *getParentDevice();
155 IOKitDevice *parentDevice;
158void IOKitDevicePrivate::init(
const QString &udiString,
const io_registry_entry_t &entry)
160 Q_ASSERT(entry != MACH_PORT_NULL);
166 parentUdi = getParentDeviceUdi(entry);
167 type = typesFromEntry(entry, properties, mainType);
168 if (udi.
contains(QStringLiteral(
"IOBD")) || udi.
contains(QStringLiteral(
"BD PX"))) {
169 qWarning() <<
"Solid: BlueRay entry" << entry <<
"mainType=" << mainType <<
"typeList:" << type <<
"with properties" <<
properties;
171 if (mainType != Solid::DeviceInterface::Unknown) { }
173 IOObjectRelease(entry);
176IOKitDevice *IOKitDevicePrivate::getParentDevice()
179 parentDevice =
new IOKitDevice(parentUdi);
184IOKitDevice::IOKitDevice(
const QString &udi,
const io_registry_entry_t &entry)
185 : d(new IOKitDevicePrivate)
190IOKitDevice::IOKitDevice(
const QString &udi)
191 : d(new IOKitDevicePrivate)
194 qWarning() << Q_FUNC_INFO <<
"Tried to create Device from empty UDI";
199 io_registry_entry_t entry = IORegistryEntryCopyFromPath(kIOMasterPortDefault, path);
202 if (entry == MACH_PORT_NULL) {
203 qWarning() << Q_FUNC_INFO <<
"Tried to create Device from invalid UDI" << udi;
210IOKitDevice::IOKitDevice(
const IOKitDevice &device)
211 : d(new IOKitDevicePrivate)
213 if (device.udi().isEmpty()) {
214 qWarning() << Q_FUNC_INFO <<
"Tried to create Device from empty UDI";
218 CFStringRef path = device.udi().toCFString();
219 io_registry_entry_t entry = IORegistryEntryCopyFromPath(kIOMasterPortDefault, path);
222 if (entry == MACH_PORT_NULL) {
223 qWarning() << Q_FUNC_INFO <<
"Tried to create Device from invalid UDI" << device.udi();
227 d->init(device.udi(), entry);
230IOKitDevice::~IOKitDevice()
235bool IOKitDevice::conformsToIOKitClass(
const QString &className)
const
237 bool conforms =
false;
240 io_registry_entry_t entry = IORegistryEntryCopyFromPath(kIOMasterPortDefault, path);
242 if (entry != MACH_PORT_NULL) {
244 IOObjectRelease(entry);
250QString IOKitDevice::udi()
const
255QString IOKitDevice::parentUdi()
const
260QString IOKitDevice::vendor()
const
262 if (parentUdi().isEmpty()) {
263 return QStringLiteral(
"Apple");
265 switch (d->mainType) {
266 case Solid::DeviceInterface::Processor:
267 return Processor::vendor();
269 case Solid::DeviceInterface::Battery:
270 return property(QStringLiteral(
"Manufacturer")).toString();
272 case Solid::DeviceInterface::StorageDrive:
273 case Solid::DeviceInterface::OpticalDrive:
274 case Solid::DeviceInterface::OpticalDisc:
275 return IOKitStorage(
this).vendor();
277 case Solid::DeviceInterface::StorageVolume:
278 return IOKitVolume(
this).vendor();
287QString IOKitDevice::product()
const
289 if (parentUdi().isEmpty()) {
290 return computerModel();
292 switch (d->mainType) {
293 case Solid::DeviceInterface::Processor:
294 return Processor::product();
296 case Solid::DeviceInterface::Battery:
297 return property(QStringLiteral(
"DeviceName")).toString();
299 case Solid::DeviceInterface::StorageDrive:
300 case Solid::DeviceInterface::OpticalDrive:
301 case Solid::DeviceInterface::OpticalDisc:
302 return IOKitStorage(
this).product();
304 case Solid::DeviceInterface::StorageVolume:
305 return IOKitVolume(
this).product();
311QString IOKitDevice::description()
const
313 switch (d->mainType) {
314 case Solid::DeviceInterface::Processor:
315 return QStringLiteral(
"Processor");
317 case Solid::DeviceInterface::Battery:
318 return QStringLiteral(
"Apple Smart Battery");
320 case Solid::DeviceInterface::StorageDrive:
321 case Solid::DeviceInterface::OpticalDrive:
322 case Solid::DeviceInterface::OpticalDisc:
323 return IOKitStorage(
this).description();
325 case Solid::DeviceInterface::StorageVolume: {
326 const QString volLabel = IOKitVolume(
this).description();
327 const QString mountPoint = IOKitStorageAccess(
this).filePath();
330 }
else if (mountPoint.
startsWith(QStringLiteral(
"/Volumes/"))) {
341QString IOKitDevice::icon()
const
344 if (parentUdi().isEmpty()) {
345 if (computerModel().contains(QStringLiteral(
"MacBook"))) {
346 return QStringLiteral(
"computer-laptop");
348 return QStringLiteral(
"computer");
351 }
else if (d->type.contains(Solid::DeviceInterface::StorageDrive)) {
352 IOKitStorage drive(
this);
356 case Solid::StorageDrive::Floppy:
358 return QStringLiteral(
"media-floppy");
360 case Solid::StorageDrive::CdromDrive: {
361 const IOKitOpticalDisc disc(
this);
362 if (disc.availableContent() == Solid::OpticalDisc::Audio) {
363 return QStringLiteral(
"media-optical-audio");
365 switch (disc.discType()) {
366 case Solid::OpticalDisc::CdRom:
367 return QStringLiteral(
"media-optical-data");
369 case Solid::OpticalDisc::CdRecordable:
370 case Solid::OpticalDisc::CdRewritable:
371 return QStringLiteral(
"media-optical-recordable");
373 case Solid::OpticalDisc::BluRayRom:
374 case Solid::OpticalDisc::BluRayRecordable:
375 case Solid::OpticalDisc::BluRayRewritable:
376 return QStringLiteral(
"media-optical-blu-ray");
381 case Solid::StorageDrive::SdMmc:
382 return QStringLiteral(
"media-flash-sd-mmc");
384 case Solid::StorageDrive::CompactFlash:
385 return QStringLiteral(
"media-flash-cf");
388 if (drive.bus() == Solid::StorageDrive::Usb) {
389 return QStringLiteral(
"drive-removable-media-usb");
391 if (drive.isRemovable()) {
392 return QStringLiteral(
"drive-removable-media");
394 return QStringLiteral(
"drive-harddisk");
396 }
else if (d->mainType == Solid::DeviceInterface::StorageVolume) {
397 }
else if (d->mainType == Solid::DeviceInterface::Battery) {
398 return QStringLiteral(
"battery");
399 }
else if (d->mainType == Solid::DeviceInterface::Processor) {
400 return QStringLiteral(
"cpu");
402 QString iconName = d->getParentDevice()->icon();
408 return QStringLiteral(
"drive-harddisk");
420 if (!d->properties.contains(key)) {
423 return d->properties.
value(key);
428 return d->properties;
431bool IOKitDevice::iOKitPropertyExists(
const QString &key)
const
439 case Solid::DeviceInterface::GenericInterface:
442 case Solid::DeviceInterface::StorageAccess:
443 if (d->type.contains(Solid::DeviceInterface::StorageDrive)
444 || d->type.contains(Solid::DeviceInterface::StorageVolume)) {
449 return d->type.contains(type);
460 case Solid::DeviceInterface::GenericInterface:
461 iface =
new GenericInterface(
this);
463 case Solid::DeviceInterface::Processor:
464 if (d->type.contains(Solid::DeviceInterface::Processor)) {
465 iface =
new Processor(
this);
468 case Solid::DeviceInterface::Battery:
469 if (d->type.contains(Solid::DeviceInterface::Battery)) {
470 iface =
new Battery(
this);
473 case Solid::DeviceInterface::OpticalDrive:
474 if (d->type.contains(Solid::DeviceInterface::OpticalDrive)) {
475 iface =
new IOKitOpticalDrive(
this);
478 case Solid::DeviceInterface::OpticalDisc:
479 if (d->type.contains(Solid::DeviceInterface::OpticalDisc)) {
480 iface =
new IOKitOpticalDisc(
this);
483 case Solid::DeviceInterface::StorageDrive:
484 if (d->type.contains(Solid::DeviceInterface::StorageDrive)) {
485 iface =
new IOKitStorage(
this);
488 case Solid::DeviceInterface::Block:
489 if (d->type.contains(Solid::DeviceInterface::OpticalDisc)) {
490 iface =
new IOKitOpticalDisc(
this);
491 }
else if (d->type.contains(Solid::DeviceInterface::OpticalDrive)) {
492 iface =
new IOKitOpticalDrive(
this);
493 }
else if (d->type.contains(Solid::DeviceInterface::StorageVolume)) {
494 iface =
new IOKitVolume(
this);
495 }
else if (d->type.contains(Solid::DeviceInterface::StorageDrive)) {
496 iface =
new IOKitStorage(
this);
499 case Solid::DeviceInterface::StorageVolume:
500 if (d->type.contains(Solid::DeviceInterface::StorageVolume)) {
501 iface =
new IOKitVolume(
this);
504 case Solid::DeviceInterface::StorageAccess:
505 if (d->type.contains(Solid::DeviceInterface::StorageDrive)
506 || d->type.contains(Solid::DeviceInterface::StorageVolume)) {
507 iface =
new IOKitStorageAccess(
this);
520#include "moc_iokitdevice.cpp"
Type
This enum type defines the type of device interface that a Device can have.
DriveType
This enum type defines the type of drive a storage device can be.
KDB_EXPORT void getProperties(const KDbLookupFieldSchema *lookup, QMap< QByteArray, QVariant > *values)
QString path(const QString &relativePath)
const char * constData() const const
bool contains(const Key &key) const const
QVariant property(const char *name) const const
bool isEmpty() const const
QString arg(Args &&... args) const const
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
QString fromCFString(CFStringRef string)
QString fromUtf8(QByteArrayView str)
bool isEmpty() const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
CFStringRef toCFString() const const
QByteArray toLocal8Bit() const const
QByteArray toUtf8() const const
QString fileName(ComponentFormattingOptions options) const const
QUrl fromLocalFile(const QString &localFile)