Semi-working WMDM device lister
This commit is contained in:
parent
164d4f6f6f
commit
78db71c02c
|
@ -91,10 +91,9 @@ QStringList DeviceKitLister::DeviceUniqueIDs() {
|
|||
return device_data_.keys();
|
||||
}
|
||||
|
||||
QStringList DeviceKitLister::DeviceIcons(const QString &id) {
|
||||
QVariantList DeviceKitLister::DeviceIcons(const QString &id) {
|
||||
QString path = LockAndGetDeviceInfo(id, &DeviceData::device_mount_paths)[0];
|
||||
QStringList guessed = DeviceLister::GuessIconForPath(path);
|
||||
return QStringList()
|
||||
return QVariantList()
|
||||
<< GuessIconForPath(path)
|
||||
<< GuessIconForModel(DeviceManufacturer(id), DeviceModel(id))
|
||||
<< LockAndGetDeviceInfo(id, &DeviceData::device_presentation_icon_name);
|
||||
|
|
|
@ -36,7 +36,7 @@ public:
|
|||
~DeviceKitLister();
|
||||
|
||||
QStringList DeviceUniqueIDs();
|
||||
QStringList DeviceIcons(const QString& id);
|
||||
QVariantList DeviceIcons(const QString& id);
|
||||
QString DeviceManufacturer(const QString& id);
|
||||
QString DeviceModel(const QString& id);
|
||||
quint64 DeviceCapacity(const QString& id);
|
||||
|
|
|
@ -42,7 +42,7 @@ public:
|
|||
|
||||
// Query information about the devices that are available. Must be thread-safe.
|
||||
virtual QStringList DeviceUniqueIDs() = 0;
|
||||
virtual QStringList DeviceIcons(const QString& id) = 0;
|
||||
virtual QVariantList DeviceIcons(const QString& id) = 0;
|
||||
virtual QString DeviceManufacturer(const QString& id) = 0;
|
||||
virtual QString DeviceModel(const QString& id) = 0;
|
||||
virtual quint64 DeviceCapacity(const QString& id) = 0;
|
||||
|
|
|
@ -82,7 +82,14 @@ void DeviceManager::DeviceInfo::InitFromDb(const DeviceDatabaseBackend::Device &
|
|||
database_id_ = dev.id_;
|
||||
friendly_name_ = dev.friendly_name_;
|
||||
size_ = dev.size_;
|
||||
LoadIcon(dev.icon_name_.split(','), friendly_name_);
|
||||
|
||||
QStringList icon_names = dev.icon_name_.split(',');
|
||||
QVariantList icons;
|
||||
foreach (const QString& icon_name, icon_names) {
|
||||
icons << icon_name;
|
||||
}
|
||||
|
||||
LoadIcon(icons, friendly_name_);
|
||||
|
||||
QStringList unique_ids = dev.unique_id_.split(',');
|
||||
foreach (const QString& id, unique_ids) {
|
||||
|
@ -90,7 +97,7 @@ void DeviceManager::DeviceInfo::InitFromDb(const DeviceDatabaseBackend::Device &
|
|||
}
|
||||
}
|
||||
|
||||
void DeviceManager::DeviceInfo::LoadIcon(const QStringList& icons, const QString& name_hint) {
|
||||
void DeviceManager::DeviceInfo::LoadIcon(const QVariantList& icons, const QString& name_hint) {
|
||||
if (icons.isEmpty()) {
|
||||
icon_name_ = "drive-removable-media-usb-pendrive";
|
||||
icon_ = IconLoader::Load(icon_name_);
|
||||
|
@ -98,15 +105,20 @@ void DeviceManager::DeviceInfo::LoadIcon(const QStringList& icons, const QString
|
|||
}
|
||||
|
||||
// Try to load the icon with that exact name first
|
||||
foreach (const QString& name, icons) {
|
||||
icon_ = IconLoader::Load(name);
|
||||
if (!icon_.isNull()) {
|
||||
icon_name_ = name;
|
||||
foreach (const QVariant& icon, icons) {
|
||||
if (!icon.value<QPixmap>().isNull()) {
|
||||
icon_ = QIcon(icon.value<QPixmap>());
|
||||
return;
|
||||
} else {
|
||||
icon_ = IconLoader::Load(icon.toString());
|
||||
if (!icon_.isNull()) {
|
||||
icon_name_ = icon.toString();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString hint = QString(icons.first() + name_hint).toLower();
|
||||
QString hint = QString(icons.first().toString() + name_hint).toLower();
|
||||
|
||||
// If that failed than try to guess if it's a phone or ipod. Fall back on
|
||||
// a usb memory stick icon.
|
||||
|
@ -581,7 +593,7 @@ void DeviceManager::SetDeviceIdentity(int row, const QString &friendly_name,
|
|||
const QString &icon_name) {
|
||||
DeviceInfo& info = devices_[row];
|
||||
info.friendly_name_ = friendly_name;
|
||||
info.LoadIcon(QStringList() << icon_name, friendly_name);
|
||||
info.LoadIcon(QVariantList() << icon_name, friendly_name);
|
||||
|
||||
emit dataChanged(index(row, 0), index(row, 0));
|
||||
|
||||
|
|
|
@ -132,7 +132,7 @@ private:
|
|||
DeviceDatabaseBackend::Device SaveToDb() const;
|
||||
|
||||
// Tries to load a good icon for the device. Sets icon_name_ and icon_.
|
||||
void LoadIcon(const QStringList& icons, const QString& name_hint);
|
||||
void LoadIcon(const QVariantList& icons, const QString& name_hint);
|
||||
|
||||
// Gets the best backend available (the one with the highest priority)
|
||||
const Backend* BestBackend() const;
|
||||
|
|
|
@ -69,8 +69,8 @@ QStringList GioLister::DeviceUniqueIDs() {
|
|||
return mounts_.keys();
|
||||
}
|
||||
|
||||
QStringList GioLister::DeviceIcons(const QString &id) {
|
||||
QStringList ret;
|
||||
QVariantList GioLister::DeviceIcons(const QString &id) {
|
||||
QVariantList ret;
|
||||
QString path = LockAndGetMountInfo(id, &MountInfo::mount_path);
|
||||
ret << DeviceLister::GuessIconForPath(path)
|
||||
<< DeviceLister::GuessIconForModel(DeviceManufacturer(id), DeviceModel(id))
|
||||
|
|
|
@ -34,7 +34,7 @@ public:
|
|||
int priority() const { return 50; }
|
||||
|
||||
QStringList DeviceUniqueIDs();
|
||||
QStringList DeviceIcons(const QString& id);
|
||||
QVariantList DeviceIcons(const QString& id);
|
||||
QString DeviceManufacturer(const QString& id);
|
||||
QString DeviceModel(const QString& id);
|
||||
quint64 DeviceCapacity(const QString& id);
|
||||
|
|
|
@ -64,8 +64,8 @@ QStringList iLister::DeviceUniqueIDs() {
|
|||
return devices_.keys();
|
||||
}
|
||||
|
||||
QStringList iLister::DeviceIcons(const QString& id) {
|
||||
return QStringList() << "ipodtouchicon";
|
||||
QVariantList iLister::DeviceIcons(const QString& id) {
|
||||
return QVariantList() << "ipodtouchicon";
|
||||
}
|
||||
|
||||
QString iLister::DeviceManufacturer(const QString& id) {
|
||||
|
|
|
@ -16,7 +16,7 @@ class iLister : public DeviceLister {
|
|||
int priority() const { return 120; }
|
||||
|
||||
virtual QStringList DeviceUniqueIDs();
|
||||
virtual QStringList DeviceIcons(const QString& id);
|
||||
virtual QVariantList DeviceIcons(const QString& id);
|
||||
virtual QString DeviceManufacturer(const QString& id);
|
||||
virtual QString DeviceModel(const QString& id);
|
||||
virtual quint64 DeviceCapacity(const QString& id);
|
||||
|
|
|
@ -16,7 +16,7 @@ class MacDeviceLister : public DeviceLister {
|
|||
~MacDeviceLister();
|
||||
|
||||
virtual QStringList DeviceUniqueIDs();
|
||||
virtual QStringList DeviceIcons(const QString& id);
|
||||
virtual QVariantList DeviceIcons(const QString& id);
|
||||
virtual QString DeviceManufacturer(const QString& id);
|
||||
virtual QString DeviceModel(const QString& id);
|
||||
virtual quint64 DeviceCapacity(const QString& id);
|
||||
|
|
|
@ -260,7 +260,7 @@ QStringList MacDeviceLister::DeviceUniqueIDs() {
|
|||
return current_devices_.keys();
|
||||
}
|
||||
|
||||
QStringList MacDeviceLister::DeviceIcons(const QString& serial) {
|
||||
QVariantList MacDeviceLister::DeviceIcons(const QString& serial) {
|
||||
QString bsd_name = current_devices_[serial];
|
||||
DASessionRef session = DASessionCreate(kCFAllocatorDefault);
|
||||
DADiskRef disk = DADiskCreateFromBSDName(
|
||||
|
@ -279,7 +279,7 @@ QStringList MacDeviceLister::DeviceIcons(const QString& serial) {
|
|||
CFRelease(disk);
|
||||
CFRelease(session);
|
||||
|
||||
QStringList ret;
|
||||
QVariantList ret;
|
||||
ret << GuessIconForPath(path);
|
||||
ret << GuessIconForModel(DeviceManufacturer(serial), DeviceModel(serial));
|
||||
if (!icon.isEmpty()) {
|
||||
|
|
|
@ -22,70 +22,135 @@
|
|||
#include <mswmdm.h>
|
||||
#include <mswmdm_i.c>
|
||||
|
||||
#include <QPixmap>
|
||||
#include <QStringList>
|
||||
#include <QtDebug>
|
||||
|
||||
BYTE abPVK[] = {0x00};
|
||||
BYTE abCert[] = {0x00};
|
||||
|
||||
QString WmdmLister::DeviceInfo::unique_id() const {
|
||||
// TODO: Serial number?
|
||||
return name_;
|
||||
}
|
||||
|
||||
WmdmLister::WmdmLister()
|
||||
: device_manager_(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
void WmdmLister::Init() {
|
||||
qDebug() << "Creating IPortableDeviceManager";
|
||||
|
||||
qDebug() << "CoInitialize says" << CoInitialize(0);
|
||||
// Initialise COM
|
||||
CoInitialize(0);
|
||||
|
||||
// Authenticate with WMDM
|
||||
IComponentAuthenticate* auth;
|
||||
HRESULT result = CoCreateInstance(
|
||||
CLSID_MediaDevMgr, NULL, CLSCTX_ALL, IID_IComponentAuthenticate, (void **)&auth);
|
||||
qDebug() << "Auth" << result << auth;
|
||||
if (CoCreateInstance(CLSID_MediaDevMgr, NULL, CLSCTX_ALL,
|
||||
IID_IComponentAuthenticate, (void**) &auth)) {
|
||||
qWarning() << "Error creating the IComponentAuthenticate interface";
|
||||
return;
|
||||
}
|
||||
|
||||
SacHandle sac = CSecureChannelClient_New();
|
||||
qDebug() << "SAC is" << sac;
|
||||
|
||||
result = CSecureChannelClient_SetCertificate(sac,
|
||||
SAC_CERT_V1,
|
||||
abCert, sizeof(abCert),
|
||||
abPVK, sizeof(abPVK));
|
||||
qDebug() << "SetCertificate" << result << abCert << sizeof(abCert);
|
||||
if (CSecureChannelClient_SetCertificate(
|
||||
sac, SAC_CERT_V1, abCert, sizeof(abCert), abPVK, sizeof(abPVK))) {
|
||||
qWarning() << "Error setting SAC certificate";
|
||||
return;
|
||||
}
|
||||
|
||||
CSecureChannelClient_SetInterface(sac, auth);
|
||||
if (CSecureChannelClient_Authenticate(sac, SAC_PROTOCOL_V1)) {
|
||||
qWarning() << "Error authenticating with SAC";
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD* prot;
|
||||
DWORD prot_count;
|
||||
result = auth->SACGetProtocols(&prot, &prot_count);
|
||||
qDebug() << "SACGetProtocols" << result << prot_count;
|
||||
qDebug() << "Prot is" << prot;
|
||||
qDebug() << "Prot is" << prot[0];
|
||||
// Create the device manager
|
||||
if (auth->QueryInterface(IID_IWMDeviceManager, (void**)&device_manager_)) {
|
||||
qWarning() << "Error creating WMDM device manager";
|
||||
return;
|
||||
}
|
||||
|
||||
result = CSecureChannelClient_Authenticate(sac, prot[0]);
|
||||
qDebug() << "Authenticate" << result;
|
||||
// Fetch the inital list of devices
|
||||
IWMDMEnumDevice* device_it = NULL;
|
||||
if (device_manager_->EnumDevices(&device_it)) {
|
||||
qWarning() << "Error querying WMDM devices";
|
||||
return;
|
||||
}
|
||||
|
||||
CoTaskMemFree(prot);
|
||||
// Iterate through the devices
|
||||
QMap<QString, DeviceInfo> devices;
|
||||
forever {
|
||||
IWMDMDevice* device = NULL;
|
||||
ULONG fetched = 0;
|
||||
if (device_it->Next(1, &device, &fetched) || fetched != 1)
|
||||
break;
|
||||
|
||||
IWMDeviceManager* device_manager;
|
||||
result = auth->QueryInterface(IID_IWMDeviceManager, (void**)device_manager);
|
||||
qDebug() << "Manager" << result << device_manager;
|
||||
DeviceInfo info = ReadDeviceInfo(device);
|
||||
if (info.is_suitable_)
|
||||
devices[info.unique_id()] = info;
|
||||
|
||||
CoUninitialize();
|
||||
device->Release();
|
||||
}
|
||||
device_it->Release();
|
||||
|
||||
// Update the internal cache
|
||||
{
|
||||
QMutexLocker l(&mutex_);
|
||||
devices_ = devices;
|
||||
}
|
||||
|
||||
// Notify about the changes
|
||||
foreach (const QString& id, devices.keys()) {
|
||||
emit DeviceAdded(id);
|
||||
}
|
||||
}
|
||||
|
||||
WmdmLister::DeviceInfo WmdmLister::ReadDeviceInfo(IWMDMDevice* device) {
|
||||
DeviceInfo ret;
|
||||
|
||||
// Get text strings
|
||||
wchar_t buf[MAX_PATH];
|
||||
device->GetName(buf, MAX_PATH);
|
||||
ret.name_ = QString::fromWCharArray(buf);
|
||||
|
||||
device->GetManufacturer(buf, MAX_PATH);
|
||||
ret.manufacturer_ = QString::fromWCharArray(buf);
|
||||
|
||||
// Get the type and check whether it has storage
|
||||
DWORD type = 0;
|
||||
device->GetType(&type);
|
||||
if (type & WMDM_DEVICE_TYPE_STORAGE)
|
||||
ret.is_suitable_ = true;
|
||||
|
||||
// Get the icon
|
||||
HICON icon;
|
||||
device->GetDeviceIcon((ULONG*)&icon);
|
||||
|
||||
ret.icon_ = QPixmap::fromWinHICON(icon);
|
||||
DestroyIcon(icon);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QStringList WmdmLister::DeviceUniqueIDs() {
|
||||
return QStringList();
|
||||
QMutexLocker l(&mutex_);
|
||||
return devices_.keys();
|
||||
}
|
||||
|
||||
QStringList WmdmLister::DeviceIcons(const QString& id) {
|
||||
return QStringList();
|
||||
QVariantList WmdmLister::DeviceIcons(const QString& id) {
|
||||
QPixmap pixmap = LockAndGetDeviceInfo(id, &DeviceInfo::icon_);
|
||||
|
||||
if (pixmap.isNull())
|
||||
return QVariantList();
|
||||
return QVariantList() << pixmap;
|
||||
}
|
||||
|
||||
QString WmdmLister::DeviceManufacturer(const QString& id) {
|
||||
return QString();
|
||||
return LockAndGetDeviceInfo(id, &DeviceInfo::manufacturer_);
|
||||
}
|
||||
|
||||
QString WmdmLister::DeviceModel(const QString& id) {
|
||||
return QString();
|
||||
return LockAndGetDeviceInfo(id, &DeviceInfo::name_);
|
||||
}
|
||||
|
||||
quint64 WmdmLister::DeviceCapacity(const QString& id) {
|
||||
|
@ -101,7 +166,15 @@ QVariantMap WmdmLister::DeviceHardwareInfo(const QString& id) {
|
|||
}
|
||||
|
||||
QString WmdmLister::MakeFriendlyName(const QString& id) {
|
||||
return QString();
|
||||
QMutexLocker l(&mutex_);
|
||||
if (!devices_.contains(id))
|
||||
return QString();
|
||||
|
||||
const DeviceInfo& info = devices_[id];
|
||||
if (info.manufacturer_.isEmpty() || info.manufacturer_ == "Unknown")
|
||||
return info.name_;
|
||||
|
||||
return info.manufacturer_ + " " + info.name_;
|
||||
}
|
||||
|
||||
QList<QUrl> WmdmLister::MakeDeviceUrls(const QString& id) {
|
||||
|
|
|
@ -19,19 +19,23 @@
|
|||
|
||||
#include "devicelister.h"
|
||||
|
||||
struct IWMDMDevice;
|
||||
struct IWMDeviceManager;
|
||||
|
||||
#include <QMap>
|
||||
#include <QMutex>
|
||||
#include <QPixmap>
|
||||
|
||||
class WmdmLister : public DeviceLister {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
WmdmLister();
|
||||
|
||||
static uchar* kDRMCert;
|
||||
static uchar* kDRMPrivateKey;
|
||||
|
||||
virtual void Init();
|
||||
|
||||
virtual QStringList DeviceUniqueIDs();
|
||||
virtual QStringList DeviceIcons(const QString& id);
|
||||
virtual QVariantList DeviceIcons(const QString& id);
|
||||
virtual QString DeviceManufacturer(const QString& id);
|
||||
virtual QString DeviceModel(const QString& id);
|
||||
virtual quint64 DeviceCapacity(const QString& id);
|
||||
|
@ -42,7 +46,41 @@ public:
|
|||
virtual void UnmountDevice(const QString& id);
|
||||
|
||||
public slots:
|
||||
virtual void UpdateDeviceFreeSpace(const QString& id);
|
||||
virtual void UpdateDeviceFreeSpace(const QString& id);
|
||||
|
||||
private:
|
||||
struct DeviceInfo {
|
||||
DeviceInfo() : is_suitable_(false) {}
|
||||
|
||||
QString unique_id() const;
|
||||
|
||||
bool is_suitable_;
|
||||
|
||||
QString name_;
|
||||
QString manufacturer_;
|
||||
|
||||
QPixmap icon_;
|
||||
};
|
||||
|
||||
DeviceInfo ReadDeviceInfo(IWMDMDevice* device);
|
||||
|
||||
template <typename T>
|
||||
T LockAndGetDeviceInfo(const QString& id, T DeviceInfo::*field);
|
||||
|
||||
private:
|
||||
IWMDeviceManager* device_manager_;
|
||||
|
||||
QMutex mutex_;
|
||||
QMap<QString, DeviceInfo> devices_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
T WmdmLister::LockAndGetDeviceInfo(const QString& id, T DeviceInfo::*field) {
|
||||
QMutexLocker l(&mutex_);
|
||||
if (!devices_.contains(id))
|
||||
return T();
|
||||
|
||||
return devices_[id].*field;
|
||||
}
|
||||
|
||||
#endif // WMDMLISTER_H
|
||||
|
|
Loading…
Reference in New Issue