2010-08-15 20:08:09 +02:00
|
|
|
/* This file is part of Clementine.
|
|
|
|
|
|
|
|
Clementine is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
Clementine is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "wmdmlister.h"
|
|
|
|
|
|
|
|
#include <icomponentauthenticate.h>
|
|
|
|
#include <objbase.h>
|
|
|
|
#include <sac_shim.h>
|
|
|
|
#include <mswmdm.h>
|
|
|
|
#include <mswmdm_i.c>
|
|
|
|
|
2010-08-16 01:26:04 +02:00
|
|
|
#include <QPixmap>
|
2010-08-15 20:08:09 +02:00
|
|
|
#include <QStringList>
|
|
|
|
#include <QtDebug>
|
|
|
|
|
|
|
|
BYTE abPVK[] = {0x00};
|
|
|
|
BYTE abCert[] = {0x00};
|
|
|
|
|
2010-08-16 01:26:04 +02:00
|
|
|
QString WmdmLister::DeviceInfo::unique_id() const {
|
|
|
|
// TODO: Serial number?
|
|
|
|
return name_;
|
|
|
|
}
|
|
|
|
|
2010-08-15 20:08:09 +02:00
|
|
|
WmdmLister::WmdmLister()
|
2010-08-16 01:26:04 +02:00
|
|
|
: device_manager_(NULL)
|
2010-08-15 20:08:09 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void WmdmLister::Init() {
|
2010-08-16 01:26:04 +02:00
|
|
|
// Initialise COM
|
|
|
|
CoInitialize(0);
|
2010-08-15 20:08:09 +02:00
|
|
|
|
2010-08-16 01:26:04 +02:00
|
|
|
// Authenticate with WMDM
|
2010-08-15 20:08:09 +02:00
|
|
|
IComponentAuthenticate* auth;
|
2010-08-16 01:26:04 +02:00
|
|
|
if (CoCreateInstance(CLSID_MediaDevMgr, NULL, CLSCTX_ALL,
|
|
|
|
IID_IComponentAuthenticate, (void**) &auth)) {
|
|
|
|
qWarning() << "Error creating the IComponentAuthenticate interface";
|
|
|
|
return;
|
|
|
|
}
|
2010-08-15 20:08:09 +02:00
|
|
|
|
|
|
|
SacHandle sac = CSecureChannelClient_New();
|
2010-08-16 01:26:04 +02:00
|
|
|
if (CSecureChannelClient_SetCertificate(
|
|
|
|
sac, SAC_CERT_V1, abCert, sizeof(abCert), abPVK, sizeof(abPVK))) {
|
|
|
|
qWarning() << "Error setting SAC certificate";
|
|
|
|
return;
|
|
|
|
}
|
2010-08-15 20:08:09 +02:00
|
|
|
|
|
|
|
CSecureChannelClient_SetInterface(sac, auth);
|
2010-08-16 01:26:04 +02:00
|
|
|
if (CSecureChannelClient_Authenticate(sac, SAC_PROTOCOL_V1)) {
|
|
|
|
qWarning() << "Error authenticating with SAC";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create the device manager
|
|
|
|
if (auth->QueryInterface(IID_IWMDeviceManager, (void**)&device_manager_)) {
|
|
|
|
qWarning() << "Error creating WMDM device manager";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fetch the inital list of devices
|
|
|
|
IWMDMEnumDevice* device_it = NULL;
|
|
|
|
if (device_manager_->EnumDevices(&device_it)) {
|
|
|
|
qWarning() << "Error querying WMDM devices";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
|
|
|
|
DeviceInfo info = ReadDeviceInfo(device);
|
|
|
|
if (info.is_suitable_)
|
|
|
|
devices[info.unique_id()] = info;
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2010-08-15 20:08:09 +02:00
|
|
|
|
2010-08-16 01:26:04 +02:00
|
|
|
WmdmLister::DeviceInfo WmdmLister::ReadDeviceInfo(IWMDMDevice* device) {
|
|
|
|
DeviceInfo ret;
|
2010-08-15 20:08:09 +02:00
|
|
|
|
2010-08-16 01:26:04 +02:00
|
|
|
// Get text strings
|
|
|
|
wchar_t buf[MAX_PATH];
|
|
|
|
device->GetName(buf, MAX_PATH);
|
|
|
|
ret.name_ = QString::fromWCharArray(buf);
|
2010-08-15 20:08:09 +02:00
|
|
|
|
2010-08-16 01:26:04 +02:00
|
|
|
device->GetManufacturer(buf, MAX_PATH);
|
|
|
|
ret.manufacturer_ = QString::fromWCharArray(buf);
|
2010-08-15 20:08:09 +02:00
|
|
|
|
2010-08-16 01:26:04 +02:00
|
|
|
// 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;
|
2010-08-15 20:08:09 +02:00
|
|
|
|
2010-08-16 01:26:04 +02:00
|
|
|
// Get the icon
|
|
|
|
HICON icon;
|
|
|
|
device->GetDeviceIcon((ULONG*)&icon);
|
|
|
|
|
|
|
|
ret.icon_ = QPixmap::fromWinHICON(icon);
|
|
|
|
DestroyIcon(icon);
|
|
|
|
|
|
|
|
return ret;
|
2010-08-15 20:08:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
QStringList WmdmLister::DeviceUniqueIDs() {
|
2010-08-16 01:26:04 +02:00
|
|
|
QMutexLocker l(&mutex_);
|
|
|
|
return devices_.keys();
|
2010-08-15 20:08:09 +02:00
|
|
|
}
|
|
|
|
|
2010-08-16 01:26:04 +02:00
|
|
|
QVariantList WmdmLister::DeviceIcons(const QString& id) {
|
|
|
|
QPixmap pixmap = LockAndGetDeviceInfo(id, &DeviceInfo::icon_);
|
|
|
|
|
|
|
|
if (pixmap.isNull())
|
|
|
|
return QVariantList();
|
|
|
|
return QVariantList() << pixmap;
|
2010-08-15 20:08:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
QString WmdmLister::DeviceManufacturer(const QString& id) {
|
2010-08-16 01:26:04 +02:00
|
|
|
return LockAndGetDeviceInfo(id, &DeviceInfo::manufacturer_);
|
2010-08-15 20:08:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
QString WmdmLister::DeviceModel(const QString& id) {
|
2010-08-16 01:26:04 +02:00
|
|
|
return LockAndGetDeviceInfo(id, &DeviceInfo::name_);
|
2010-08-15 20:08:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
quint64 WmdmLister::DeviceCapacity(const QString& id) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
quint64 WmdmLister::DeviceFreeSpace(const QString& id) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
QVariantMap WmdmLister::DeviceHardwareInfo(const QString& id) {
|
|
|
|
return QVariantMap();
|
|
|
|
}
|
|
|
|
|
|
|
|
QString WmdmLister::MakeFriendlyName(const QString& id) {
|
2010-08-16 01:26:04 +02:00
|
|
|
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_;
|
2010-08-15 20:08:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
QList<QUrl> WmdmLister::MakeDeviceUrls(const QString& id) {
|
|
|
|
return QList<QUrl>();
|
|
|
|
}
|
|
|
|
|
|
|
|
void WmdmLister::UnmountDevice(const QString& id) {
|
|
|
|
}
|
|
|
|
|
|
|
|
void WmdmLister::UpdateDeviceFreeSpace(const QString& id) {
|
|
|
|
}
|