diff --git a/CMakeLists.txt b/CMakeLists.txt index 759c24d98..d1d738ab4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,7 +83,6 @@ pkg_check_modules(TAGLIB REQUIRED taglib>=1.6) if (WIN32) find_package(ZLIB REQUIRED) - find_library(MSWMDM_LIBRARIES mswmdm) find_library(QTSPARKLE_LIBRARIES qtsparkle) endif (WIN32) diff --git a/dist/windows/clementine.nsi.in b/dist/windows/clementine.nsi.in index 0cc6d8846..f9a9ea2a2 100644 --- a/dist/windows/clementine.nsi.in +++ b/dist/windows/clementine.nsi.in @@ -9,9 +9,6 @@ !define PRODUCT_UNINST_ROOT_KEY "HKLM" !define PRODUCT_INSTALL_DIR "$PROGRAMFILES\Clementine" -!define WMDM_DIST_URL "http://clementine-player.googlecode.com/files/wmdmdist.exe" -!define WMF_DIST_URL "http://clementine-player.googlecode.com/files/wmfdist.exe" - ; Set Application Capabilities info !define CAPABILITIES_NAME "Clementine" !define CAPABILITIES_LOCAL_NAME "Clementine" @@ -911,41 +908,6 @@ Section "Uninstaller" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}" SectionEnd -Section "Windows Media Device Manager" - GetDllVersion "$SYSDIR\mswmdm.dll" $R8 $R9 - IntOp $R7 $R8 / 0x00010000 - IntCmp $R7 9 end downloadwmf end # Major version >= 9 - -downloadwmf: - StrCpy $1 "wmfdist.exe" - NSISdl::download ${WMF_DIST_URL} "$TEMP\$1" - Pop $R0 - StrCmp $R0 "success" downloadwmdm - MessageBox MB_OK|MB_ICONSTOP "Error while downloading $1." - Quit - -downloadwmdm: - StrCpy $1 "wmdmdist.exe" - NSISdl::download ${WMDM_DIST_URL} "$TEMP\$1" - Pop $R0 - StrCmp $R0 "success" install - MessageBox MB_OK|MB_ICONSTOP "Error while downloading $1." - Quit - -install: - DetailPrint "Installing the Windows Media Format 9 redistributable" - ExecWait "$TEMP\wmfdist.exe /Q" - - DetailPrint "Installing the Windows Media Device Manager 9 redistributable" - ExecWait "$TEMP\wmdmdist.exe /Q" - - Delete "$TEMP\wmfdist.exe" - Delete "$TEMP\wmdmdist.exe" - -end: - DetailPrint "WMDM redistributable installed" -SectionEnd - Section "Uninstall" ; Kill clementine.exe if it's running ; This calling convention is retarded... diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7ce7fc131..229c75cb6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1045,20 +1045,6 @@ optional_source(HAVE_LIBMTP devices/mtploader.h ) -# Windows media lister -optional_source(WIN32 - SOURCES - devices/wmdmdevice.cpp - devices/wmdmlister.cpp - devices/wmdmloader.cpp - devices/wmdmprogress.cpp - devices/wmdmthread.cpp - HEADERS - devices/wmdmdevice.h - devices/wmdmlister.h - devices/wmdmloader.h -) - # Moodbar support optional_source(HAVE_MOODBAR SOURCES @@ -1297,7 +1283,6 @@ endif(HAVE_STATIC_SQLITE) if (WIN32) target_link_libraries(clementine_lib ${ZLIB_LIBRARIES} - ${MSWMDM_LIBRARIES} ${QTSPARKLE_LIBRARIES} tinysvcmdns qtwin diff --git a/src/core/song.cpp b/src/core/song.cpp index 08af33ae3..f79ab5f93 100644 --- a/src/core/song.cpp +++ b/src/core/song.cpp @@ -40,11 +40,6 @@ #include -#ifdef Q_OS_WIN32 -# include -# include -#endif // Q_OS_WIN32 - #ifdef HAVE_LIBGPOD # include #endif @@ -726,233 +721,6 @@ void Song::InitFromLastFM(const lastfm::Track& track) { } #endif -#if defined(Q_OS_WIN32) - static void AddWmdmItem(IWMDMMetaData* metadata, const wchar_t* name, - const QVariant& value) { - switch (value.type()) { - case QVariant::Int: - case QVariant::UInt: { - DWORD data = value.toUInt(); - metadata->AddItem(WMDM_TYPE_DWORD, name, (BYTE*)&data, sizeof(data)); - break; - } - case QVariant::String: { - ScopedWCharArray data(value.toString()); - metadata->AddItem(WMDM_TYPE_STRING, name, (BYTE*)data.get(), data.bytes()); - break; - } - case QVariant::ByteArray: { - QByteArray data = value.toByteArray(); - metadata->AddItem(WMDM_TYPE_BINARY, name, (BYTE*)data.constData(), data.size()); - break; - } - case QVariant::Bool: { - int data = value.toBool(); - metadata->AddItem(WMDM_TYPE_BOOL, name, (BYTE*)&data, sizeof(data)); - break; - } - case QVariant::LongLong: - case QVariant::ULongLong: { - quint64 data = value.toULongLong(); - metadata->AddItem(WMDM_TYPE_QWORD, name, (BYTE*)&data, sizeof(data)); - break; - } - default: - qLog(Warning) << "Type" << value.type() << "not handled"; - Q_ASSERT(0); - break; - } - } - - static QVariant ReadWmdmValue(int type, uchar* data, uint length) { - switch (type) { - case WMDM_TYPE_DWORD: - return QVariant::fromValue(uint(*reinterpret_cast(data))); - case WMDM_TYPE_WORD: - return QVariant::fromValue(uint(*reinterpret_cast(data))); - case WMDM_TYPE_QWORD: - return QVariant::fromValue(qulonglong(*reinterpret_cast(data))); - case WMDM_TYPE_STRING: - return QString::fromWCharArray(reinterpret_cast(data), length/2); - case WMDM_TYPE_BINARY: - return QByteArray(reinterpret_cast(data), length); - case WMDM_TYPE_BOOL: - return bool(*reinterpret_cast(data)); - case WMDM_TYPE_GUID: - return QUuid(*reinterpret_cast(data)).toString(); - } - return QVariant(); - } - - void Song::InitFromWmdm(IWMDMMetaData* metadata) { - bool non_consumable = false; - int format = 0; - - // How much metadata is there? - uint count = 0; - metadata->GetItemCount(&count); - - for (int i=0 ; iQueryByIndex(i, &name, &type, &value, &length); - - QVariant item_value = ReadWmdmValue(type, value, length); - - // Store it in the song if it's something we recognise - if (wcscmp(name, g_wszWMDMTitle) == 0) - d->title_ = item_value.toString(); - - else if (wcscmp(name, g_wszWMDMAuthor) == 0) - d->artist_ = item_value.toString(); - - else if (wcscmp(name, g_wszWMDMDescription) == 0) - d->comment_ = item_value.toString(); - - else if (wcscmp(name, g_wszWMDMAlbumTitle) == 0) - d->album_ = item_value.toString(); - - else if (wcscmp(name, g_wszWMDMTrack) == 0) - d->track_ = item_value.toInt(); - - else if (wcscmp(name, g_wszWMDMGenre) == 0) - d->genre_ = item_value.toString(); - - else if (wcscmp(name, g_wszWMDMYear) == 0) - d->year_ = item_value.toInt(); - - else if (wcscmp(name, g_wszWMDMComposer) == 0) - d->composer_ = item_value.toString(); - - else if (wcscmp(name, g_wszWMDMBitrate) == 0) - d->bitrate_ = item_value.toInt(); - - else if (wcscmp(name, g_wszWMDMFileName) == 0) - d->url_ = QUrl::fromLocalFile(item_value.toString()); - - else if (wcscmp(name, g_wszWMDMDuration) == 0) - set_length_nanosec(item_value.toULongLong() * 1e2); - - else if (wcscmp(name, L"WMDM/FileSize") == 0) - d->filesize_ = item_value.toULongLong(); - - else if (wcscmp(name, L"WMDM/NonConsumable") == 0) - non_consumable = item_value.toBool(); - - else if (wcscmp(name, L"WMDM/FormatCode") == 0) - format = item_value.toInt(); - - CoTaskMemFree(name); - CoTaskMemFree(value); - } - - // Decide if this is music or not - if (count == 0 || non_consumable) - return; - - switch (format) { - case WMDM_FORMATCODE_AIFF: - d->filetype_ = Song::Type_Aiff; - break; - - case WMDM_FORMATCODE_WAVE: - d->filetype_ = Song::Type_Wav; - break; - - case WMDM_FORMATCODE_MP2: - case WMDM_FORMATCODE_MP3: - case WMDM_FORMATCODE_MPEG: - d->filetype_ = Song::Type_Mpeg; - break; - - case WMDM_FORMATCODE_WMA: - case WMDM_FORMATCODE_ASF: - d->filetype_ = Song::Type_Asf; - break; - - case WMDM_FORMATCODE_OGG: - d->filetype_ = Song::Type_OggVorbis; - break; - - case WMDM_FORMATCODE_AAC: - case WMDM_FORMATCODE_MP4: - d->filetype_ = Song::Type_Mp4; - break; - - case WMDM_FORMATCODE_FLAC: - d->filetype_ = Song::Type_Flac; - break; - - case WMDM_FORMATCODE_AUDIBLE: - case WMDM_FORMATCODE_UNDEFINEDAUDIO: - d->filetype_ = Song::Type_Unknown; - break; - - case WMDM_FORMATCODE_UNDEFINED: - // WMDM doesn't know what type of file it is, so we start guessing - first - // check if any of the music metadata fields were defined. If they were, - // there's a fairly good chance the file was music. - if (!d->title_.isEmpty() || !d->artist_.isEmpty() || - !d->album_.isEmpty() || !d->comment_.isEmpty() || - !d->genre_.isEmpty() || d->track_ != -1 || d->year_ != -1 || - length_nanosec() != -1) { - d->filetype_ = Song::Type_Unknown; - break; - } - - // Make a final guess based on the file extension - { - QString ext = d->url_.path().section('.', -1, -1).toLower(); - if (ext == "mp3" || ext == "wma" || ext == "flac" || ext == "ogg" || - ext == "spx" || ext == "mp4" || ext == "aac" || ext == "m4a") - break; - } - return; - - default: - return; // It's not music - } - - d->valid_ = true; - d->mtime_ = 0; - d->ctime_ = 0; - } - - void Song::ToWmdm(IWMDMMetaData* metadata) const { - AddWmdmItem(metadata, g_wszWMDMTitle, d->title_); - AddWmdmItem(metadata, g_wszWMDMAuthor, d->artist_); - AddWmdmItem(metadata, g_wszWMDMDescription, d->comment_); - AddWmdmItem(metadata, g_wszWMDMAlbumTitle, d->album_); - AddWmdmItem(metadata, g_wszWMDMTrack, d->track_); - AddWmdmItem(metadata, g_wszWMDMGenre, d->genre_); - AddWmdmItem(metadata, g_wszWMDMYear, QString::number(d->year_)); - AddWmdmItem(metadata, g_wszWMDMComposer, d->composer_); - AddWmdmItem(metadata, g_wszWMDMBitrate, d->bitrate_); - AddWmdmItem(metadata, g_wszWMDMFileName, d->basefilename_); - AddWmdmItem(metadata, g_wszWMDMDuration, qint64(length_nanosec() / 1e2)); - AddWmdmItem(metadata, L"WMDM/FileSize", d->filesize_); - - WMDM_FORMATCODE format; - switch (d->filetype_) { - case Type_Aiff: format = WMDM_FORMATCODE_AIFF; break; - case Type_Wav: format = WMDM_FORMATCODE_WAVE; break; - case Type_Mpeg: format = WMDM_FORMATCODE_MP3; break; - case Type_Asf: format = WMDM_FORMATCODE_ASF; break; - case Type_OggFlac: - case Type_OggSpeex: - case Type_OggVorbis: format = WMDM_FORMATCODE_OGG; break; - case Type_Mp4: format = WMDM_FORMATCODE_MP4; break; - case Type_Flac: format = WMDM_FORMATCODE_FLAC; break; - default: format = WMDM_FORMATCODE_UNDEFINEDAUDIO; break; - } - AddWmdmItem(metadata, L"WMDM/FormatCode", format); - } -#endif // Q_OS_WIN32 - void Song::MergeFromSimpleMetaBundle(const Engine::SimpleMetaBundle &bundle) { if (d->init_from_file_ || d->url_.scheme() == "file") { // This Song was already loaded using taglib. Our tags are probably better diff --git a/src/core/song.h b/src/core/song.h index f5310e1ad..b4b76e01a 100644 --- a/src/core/song.h +++ b/src/core/song.h @@ -44,10 +44,6 @@ class QUrl; struct LIBMTP_track_struct; #endif -#if defined(Q_OS_WIN32) - struct IWMDMMetaData; -#endif - #ifdef HAVE_LIBLASTFM namespace lastfm { class Track; @@ -126,11 +122,6 @@ class Song { void ToMTP(LIBMTP_track_struct* track) const; #endif -#if defined(Q_OS_WIN32) - void InitFromWmdm(IWMDMMetaData* metadata); - void ToWmdm(IWMDMMetaData* metadata) const; -#endif - // Copies important statistics from the other song to this one, overwriting // any data that already exists. Useful when you want updated tags from disk // but you want to keep user stats. diff --git a/src/devices/devicemanager.cpp b/src/devices/devicemanager.cpp index cedf4a9f2..eb2a1d351 100644 --- a/src/devices/devicemanager.cpp +++ b/src/devices/devicemanager.cpp @@ -50,10 +50,6 @@ #ifdef Q_OS_DARWIN # include "macdevicelister.h" #endif -#ifdef Q_OS_WIN32 -# include "wmdmlister.h" -# include "wmdmdevice.h" -#endif #ifdef HAVE_LIBGPOD # include "gpoddevice.h" #endif @@ -202,10 +198,6 @@ DeviceManager::DeviceManager(Application* app, QObject *parent) #ifdef Q_OS_DARWIN AddLister(new MacDeviceLister); #endif -#if defined(Q_OS_WIN32) - AddLister(new WmdmLister); - AddDeviceClass(); -#endif AddDeviceClass(); diff --git a/src/devices/wmdmdevice.cpp b/src/devices/wmdmdevice.cpp deleted file mode 100644 index 74aac2c54..000000000 --- a/src/devices/wmdmdevice.cpp +++ /dev/null @@ -1,292 +0,0 @@ -/* This file is part of Clementine. - Copyright 2010, David Sansome - - 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 . -*/ - -#include "devicemanager.h" -#include "wmdmdevice.h" -#include "wmdmlister.h" -#include "wmdmloader.h" -#include "wmdmprogress.h" -#include "wmdmthread.h" -#include "core/application.h" -#include "core/logging.h" -#include "core/utilities.h" -#include "library/librarybackend.h" -#include "library/librarymodel.h" - -#include -#include - -#include - -#include - -WmdmDevice::WmdmDevice(const QUrl& url, DeviceLister* lister, - const QString& unique_id, DeviceManager* manager, - Application* app, - int database_id, bool first_time) - : ConnectedDevice(url, lister, unique_id, manager, app, database_id, first_time), - loader_thread_(new QThread(this)), - loader_(NULL) -{ -} - -WmdmDevice::~WmdmDevice() { -} - -void WmdmDevice::Init() { - InitBackendDirectory("/", first_time_, false); - model_->Init(); - - loader_ = new WmdmLoader(app_->task_manager(), backend_, shared_from_this()); - loader_->moveToThread(loader_thread_); - - connect(loader_, SIGNAL(Error(QString)), SIGNAL(Error(QString))); - connect(loader_, SIGNAL(TaskStarted(int)), SIGNAL(TaskStarted(int))); - connect(loader_, SIGNAL(LoadFinished()), SLOT(LoadFinished())); - connect(loader_thread_, SIGNAL(started()), loader_, SLOT(LoadDatabase())); - loader_thread_->start(); - - db_busy_.lock(); -} - -void WmdmDevice::LoadFinished() { - loader_->deleteLater(); - loader_ = NULL; - - db_busy_.unlock(); -} - -bool WmdmDevice::StartCopy(QList* supported_types) { - // Ensure only one "organise files" can be active at any one time - db_busy_.lock(); - - // This initialises COM and gets a connection to the device - thread_.reset(new WmdmThread); - if (!thread_->manager()) - return false; - - // Find a place to put the files. We default to the root folder for now, but - // could look for a "Music" folder in the future? - WmdmLister* wmdm_lister = static_cast(lister()); - QString canonical_name = wmdm_lister->DeviceCanonicalName(unique_id()); - IWMDMStorage* destination = thread_->GetRootStorage(canonical_name); - - // Get the control interface - destination->QueryInterface(IID_IWMDMStorageControl3, (void**)&storage_control_); - - // Get the storage3 interface for CreateEmptyMetadataObject later - destination->QueryInterface(IID_IWMDMStorage3, (void**)&storage_); - - destination->Release(); - - // Did the caller want a list of supported filetypes? - if (supported_types) { - IWMDMDevice* device = thread_->GetDeviceByCanonicalName(canonical_name); - if (!GetSupportedFiletypes(supported_types, device)) { - device->Release(); - FinishCopy(false); - return false; - } - device->Release(); - } - - return true; -} - -bool WmdmDevice::CopyToStorage(const CopyJob& job) { - if (!storage_control_ || !storage_) - return false; - - // Create the song metadata - IWMDMMetaData* metadata_iface = NULL; - storage_->CreateEmptyMetadataObject(&metadata_iface); - job.metadata_.ToWmdm(metadata_iface); - - // Convert the filenames to wchars - ScopedWCharArray source_filename(QDir::toNativeSeparators(job.source_)); - ScopedWCharArray dest_filename(job.metadata_.basefilename()); - - // Create the progress object - WmdmProgress progress(job.progress_); - - // Copy the file - IWMDMStorage* new_storage = NULL; - if (storage_control_->Insert3( - WMDM_MODE_BLOCK | WMDM_STORAGECONTROL_INSERTINTO | - WMDM_FILE_CREATE_OVERWRITE | WMDM_CONTENT_FILE, - WMDM_FILE_ATTR_FOLDER, - source_filename, - dest_filename, - NULL, // operation - &progress, // progress - metadata_iface, - NULL, // data - &new_storage)) { - qLog(Warning) << "Couldn't copy file to WMDM device"; - metadata_iface->Release(); - return false; - } - metadata_iface->Release(); - - if (!new_storage) - return false; - - // Get the metadata from the newly copied file - IWMDMStorage3* new_storage3 = NULL; - IWMDMMetaData* new_metadata = NULL; - - new_storage->QueryInterface(IID_IWMDMStorage3, (void**)&new_storage3); - new_storage3->GetMetadata(&new_metadata); - - new_storage->Release(); - new_storage3->Release(); - - if (!new_metadata) - return false; - - // Add it to our LibraryModel - Song new_song; - new_song.InitFromWmdm(new_metadata); - new_song.set_directory_id(1); - songs_to_add_ << new_song; - - new_metadata->Release(); - - // Remove the original if requested - if (job.remove_original_) { - if (!QFile::remove(job.source_)) - return false; - } - - return true; -} - -void WmdmDevice::FinishCopy(bool success) { - if (success) { - if (!songs_to_add_.isEmpty()) - backend_->AddOrUpdateSongs(songs_to_add_); - if (!songs_to_remove_.isEmpty()) - backend_->DeleteSongs(songs_to_remove_); - } - - songs_to_add_.clear(); - songs_to_remove_.clear(); - - storage_->Release(); - storage_control_->Release(); - thread_.reset(); - - db_busy_.unlock(); - - ConnectedDevice::FinishCopy(success); -} - -void WmdmDevice::StartDelete() { - StartCopy(NULL); -} - -bool WmdmDevice::DeleteFromStorage(const DeleteJob& job) { - // Walk down the tree until we've found the file - IWMDMStorage3* storage = storage_; - storage->AddRef(); - - const QStringList path_components = - job.metadata_.url().path().split('/', QString::SkipEmptyParts); - foreach (const QString& path_component, path_components) { - ScopedWCharArray path_component_wchar(path_component); - - IWMDMStorage* next_storage = NULL; - if (storage->GetStorage(path_component_wchar, &next_storage)) { - // Couldn't find it - storage->Release(); - return false; - } - storage->Release(); - - next_storage->QueryInterface(IID_IWMDMStorage3, (void**)&storage); - } - - // Get a control interface on it - IWMDMStorageControl3* control = NULL; - storage->QueryInterface(IID_IWMDMStorageControl3, (void**)&control); - storage->Release(); - - // Delete it - WmdmProgress progress; - if (control->Delete(WMDM_MODE_BLOCK, &progress)) { - return false; - } - - // Remove it from our library model - songs_to_remove_ << job.metadata_; - - return true; -} - -void WmdmDevice::FinishDelete(bool success) { - FinishCopy(success); -} - -bool WmdmDevice::GetSupportedFiletypes(QList* ret, IWMDMDevice* device) { - // Get a list of supported formats - uint32_t format_count = 0; - uint32_t mime_count = 0; - _WAVEFORMATEX* formats; - wchar_t** mime_types; - - if (device->GetFormatSupport( - &formats, &format_count, &mime_types, &mime_count)) { - qLog(Warning) << "Unable to get a list of supported formats for device"; - return false; - } - - // Find known mime types - for (int i=0 ; i* ret) { - QMutexLocker l(&db_busy_); - - WmdmThread thread; - - // Get the device - WmdmLister* wmdm_lister = static_cast(lister()); - QString canonical_name = wmdm_lister->DeviceCanonicalName(unique_id()); - IWMDMDevice* device = thread.GetDeviceByCanonicalName(canonical_name); - - bool success = GetSupportedFiletypes(ret, device); - device->Release(); - - return success; -} diff --git a/src/devices/wmdmdevice.h b/src/devices/wmdmdevice.h deleted file mode 100644 index 03ee4976a..000000000 --- a/src/devices/wmdmdevice.h +++ /dev/null @@ -1,75 +0,0 @@ -/* This file is part of Clementine. - Copyright 2010, David Sansome - - 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 . -*/ - -#ifndef WMDMDEVICE_H -#define WMDMDEVICE_H - -#include "connecteddevice.h" - -#include - -class WmdmLoader; -class WmdmThread; - -struct IWMDMDevice; -struct IWMDMStorage3; -struct IWMDMStorageControl3; - -class WmdmDevice : public ConnectedDevice { - Q_OBJECT - -public: - Q_INVOKABLE WmdmDevice(const QUrl& url, DeviceLister* lister, - const QString& unique_id, DeviceManager* manager, - Application* app, - int database_id, bool first_time); - ~WmdmDevice(); - - static QStringList url_schemes() { return QStringList() << "wmdm"; } - - void Init(); - - bool GetSupportedFiletypes(QList* ret); - - bool StartCopy(QList* supported_types); - bool CopyToStorage(const CopyJob& job); - void FinishCopy(bool success); - - void StartDelete(); - bool DeleteFromStorage(const DeleteJob& job); - void FinishDelete(bool success); - -private slots: - void LoadFinished(); - -private: - bool GetSupportedFiletypes(QList* ret, IWMDMDevice* device); - -private: - QThread* loader_thread_; - WmdmLoader* loader_; - - QMutex db_busy_; - SongList songs_to_add_; - SongList songs_to_remove_; - - boost::scoped_ptr thread_; - IWMDMStorage3* storage_; - IWMDMStorageControl3* storage_control_; -}; - -#endif // WMDMDEVICE_H diff --git a/src/devices/wmdmlister.cpp b/src/devices/wmdmlister.cpp deleted file mode 100644 index 412be383a..000000000 --- a/src/devices/wmdmlister.cpp +++ /dev/null @@ -1,528 +0,0 @@ -/* This file is part of Clementine. - Copyright 2010, David Sansome - - 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 . -*/ - -#define _WIN32_WINNT 0x0501 - -#include "wmdmlister.h" -#include "wmdmthread.h" -#include "core/logging.h" -#include "core/utilities.h" - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -const QUuid WmdmLister::kDeviceProtocolMsc( - 0xa4d2c26c, 0xa881, 0x44bb, 0xbd, 0x5d, 0x1f, 0x70, 0x3c, 0x71, 0xf7, 0xa9); - -QString WmdmLister::CanonicalNameToId(const QString& canonical_name) { - return "wmdm/" + canonical_name; -} - -QString WmdmLister::DeviceInfo::unique_id() const { - return WmdmLister::CanonicalNameToId(canonical_name_); -} - -WmdmLister::WmdmLister() - : notification_cookie_(0) -{ -} - -WmdmLister::~WmdmLister() { - Q_ASSERT(!thread_); -} - -void WmdmLister::Init() { - qLog(Debug) << "Starting"; - - thread_.reset(new WmdmThread); - if (!thread_->manager()) - return; - - // Register for notifications - qLog(Debug) << "Obtaining CP container"; - IConnectionPointContainer* cp_container = NULL; - thread_->manager()->QueryInterface(IID_IConnectionPointContainer, (void**)&cp_container); - - qLog(Debug) << "Obtaining CP"; - IConnectionPoint* cp = NULL; - cp_container->FindConnectionPoint(IID_IWMDMNotification, &cp); - - qLog(Debug) << "Registering for notifications"; - cp->Advise(this, ¬ification_cookie_); - - cp->Release(); - cp_container->Release(); - - // Fetch the initial list of devices - qLog(Debug) << "Fetching device list"; - IWMDMEnumDevice* device_it = NULL; - if (thread_->manager()->EnumDevices2(&device_it)) { - qLog(Warning) << "Error querying WMDM devices"; - return; - } - - // Iterate through the devices - QMap devices; - forever { - IWMDMDevice* device = NULL; - IWMDMDevice2* device2 = NULL; - ULONG fetched = 0; - if (device_it->Next(1, &device, &fetched) || fetched != 1) - break; - - qLog(Debug) << "Querying device"; - if (device->QueryInterface(IID_IWMDMDevice2, (void**)&device2)) { - qLog(Warning) << "Error getting IWMDMDevice2 from device"; - device->Release(); - continue; - } - device->Release(); - - DeviceInfo info = ReadDeviceInfo(device2); - if (info.is_suitable_) - devices[info.unique_id()] = info; - else - device2->Release(); - } - device_it->Release(); - - // Update the internal cache - qLog(Debug) << "Updating device cache"; - { - QMutexLocker l(&mutex_); - devices_ = devices; - } - - // Notify about the changes - foreach (const QString& id, devices.keys()) { - emit DeviceAdded(id); - } - - qLog(Debug) << "Startup complete"; -} - -void WmdmLister::ReallyShutdown() { - // Unregister for notifications - IConnectionPointContainer* cp_container; - thread_->manager()->QueryInterface(IID_IConnectionPointContainer, (void**)&cp_container); - - IConnectionPoint* cp; - cp_container->FindConnectionPoint(IID_IWMDMNotification, &cp); - - cp->Release(); - cp_container->Release(); - - thread_.reset(); -} - -void WmdmLister::ShutDown() { - // COM shutdown must be done in the original thread. - metaObject()->invokeMethod(this, "ReallyShutdown", Qt::BlockingQueuedConnection); -} - -WmdmLister::DeviceInfo WmdmLister::ReadDeviceInfo(IWMDMDevice2* device) { - qLog(Debug) << "Reading device info"; - - DeviceInfo ret; - ret.device_ = device; - - // Get text strings - const int max_size = 512; - wchar_t buf[max_size]; - device->GetName(buf, max_size); - ret.name_ = QString::fromWCharArray(buf).trimmed(); - - device->GetManufacturer(buf, max_size); - ret.manufacturer_ = QString::fromWCharArray(buf).trimmed(); - - device->GetCanonicalName(buf, max_size); - ret.canonical_name_ = QString::fromWCharArray(buf).toLower(); - - qLog(Debug) << "Read device strings:" << ret.name_ << ret.manufacturer_ << ret.canonical_name_; - - // Upgrade to a device3 - IWMDMDevice3* device3 = NULL; - device->QueryInterface(IID_IWMDMDevice3, (void**)&device3); - - // Get the device protocol so we can figure out whether the device is MSC - PROPVARIANT protocol; - if (device3) { - device3->GetProperty(g_wszWMDMDeviceProtocol, &protocol); - device3->Release(); - } - - // 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; - if (device->GetDeviceIcon((ULONG*)&icon) == S_OK) { - // Extra check for whether the icon is valid (see issue 1417) - - ICONINFO iconinfo; - if (GetIconInfo(icon, &iconinfo)) { - ret.icon_ = QPixmap::fromWinHICON(icon); - DestroyIcon(icon); - } - } - - // Get the main (first) storage for the device - IWMDMEnumStorage* storage_it = NULL; - if (device->EnumStorage(&storage_it) == S_OK && storage_it) { - ULONG storage_fetched = 0; - IWMDMStorage* storage; - - if (storage_it->Next(1, &storage, &storage_fetched) == S_OK) { - if (storage->QueryInterface(IID_IWMDMStorage2, (void**)&ret.storage_)) { - qLog(Warning) << "Error getting IWMDMStorage2 from storage"; - } else { - // Get free space information - UpdateFreeSpace(&ret); - } - storage->Release(); - } - storage_it->Release(); - } - - // There doesn't seem to be a way to get the drive letter of MSC devices, so - // try parsing the device's name to extract it. - if (!device3 || QUuid(*protocol.puuid) == kDeviceProtocolMsc) - GuessDriveLetter(&ret); - - return ret; -} - -void WmdmLister::GuessDriveLetter(DeviceInfo* info) { - qLog(Debug) << "Guessing drive letter for" << info->name_; - - // Windows XP puts the drive letter in brackets at the end of the name - QRegExp drive_letter("\\(([A-Z]:)\\)$"); - if (drive_letter.indexIn(info->name_) != -1) { - qLog(Debug) << "Looks like an XP drive" << drive_letter.cap(1); - CheckDriveLetter(info, drive_letter.cap(1)); - return; - } - - // Windows 7 sometimes has the drive letter as the whole name - drive_letter = QRegExp("^([A-Z]:)\\\\$"); - if (drive_letter.indexIn(info->name_) != -1) { - qLog(Debug) << "Looks like a win7 drive" << drive_letter.cap(1); - CheckDriveLetter(info, drive_letter.cap(1)); - return; - } - - // Otherwise Windows 7 uses the drive's DOS label as its whole name. - // Let's enumerate all the volumes on the system and find one with that - // label, then get its drive letter. Yay! - wchar_t volume_name[MAX_PATH + 1]; - HANDLE handle = FindFirstVolumeW(volume_name, MAX_PATH); - - forever { - // QueryDosDeviceW doesn't allow a trailing backslash, so remove it. - int length = wcslen(volume_name); - volume_name[length - 1] = L'\0'; - - wchar_t device_name[MAX_PATH + 1]; - QueryDosDeviceW(&volume_name[4], device_name, MAX_PATH); - - volume_name[length - 1] = L'\\'; - - // Don't do cd-roms or floppies - if (QString::fromWCharArray(device_name).contains("HarddiskVolume")) { - wchar_t volume_path[MAX_PATH + 1]; - DWORD volume_path_length = MAX_PATH; - GetVolumePathNamesForVolumeNameW( - volume_name, volume_path, volume_path_length, &volume_path_length); - - if (wcslen(volume_path) == 3) { - ScopedWCharArray name(QString(MAX_PATH + 1, '\0')); - ScopedWCharArray type(QString(MAX_PATH + 1, '\0')); - DWORD serial = 0; - - if (!GetVolumeInformationW(volume_path, name, MAX_PATH, - &serial, NULL, NULL, type, MAX_PATH)) { - qLog(Warning) << "Error getting volume information for" << - QString::fromWCharArray(volume_path); - } else { - if (name.ToString() == info->name_ && name.characters() != 0) { - // We found it! - qLog(Debug) << "Looks like a win7 drive name" << QString::fromWCharArray(volume_path); - if (CheckDriveLetter(info, QString::fromWCharArray(volume_path))) { - info->device_name_ = QString::fromWCharArray(device_name); - info->volume_name_ = QString::fromWCharArray(volume_name); - } - break; - } - } - } - } - - if (!FindNextVolumeW(handle, volume_name, MAX_PATH)) - break; - } - FindVolumeClose(handle); -} - -bool WmdmLister::CheckDriveLetter(DeviceInfo* info, const QString& drive) { - // Sanity check to make sure there really is a drive there - ScopedWCharArray path(drive.endsWith('\\') ? drive : (drive + "\\")); - ScopedWCharArray name(QString(MAX_PATH + 1, '\0')); - ScopedWCharArray type(QString(MAX_PATH + 1, '\0')); - DWORD serial = 0; - - if (!GetVolumeInformationW( - path, - name, MAX_PATH, - &serial, - NULL, // max component length - NULL, // flags - type, MAX_PATH // fat or ntfs - )) { - qLog(Warning) << "Error getting volume information for" << drive; - return false; - } else { - qLog(Debug) << "Validated drive letter" << drive; - info->mount_point_ = path.ToString(); - info->fs_name_ = name.ToString(); - info->fs_type_ = type.ToString(); - info->fs_serial_ = serial; - return true; - } -} - -QStringList WmdmLister::DeviceUniqueIDs() { - QMutexLocker l(&mutex_); - return devices_.keys(); -} - -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 LockAndGetDeviceInfo(id, &DeviceInfo::manufacturer_); -} - -QString WmdmLister::DeviceModel(const QString& id) { - return LockAndGetDeviceInfo(id, &DeviceInfo::name_); -} - -quint64 WmdmLister::DeviceCapacity(const QString& id) { - return LockAndGetDeviceInfo(id, &DeviceInfo::total_bytes_); -} - -quint64 WmdmLister::DeviceFreeSpace(const QString& id) { - return LockAndGetDeviceInfo(id, &DeviceInfo::free_bytes_); -} - -QVariantMap WmdmLister::DeviceHardwareInfo(const QString& id) { - QVariantMap ret; - - QMutexLocker l(&mutex_); - if (!devices_.contains(id)) - return ret; - - const DeviceInfo& info = devices_[id]; - - ret[tr("Drive letter")] = QDir::toNativeSeparators(info.mount_point_); - ret[tr("Filesystem type")] = info.fs_type_; - ret[tr("Filesystem name")] = info.fs_name_; - ret[tr("Device name")] = info.device_name_; - ret[tr("Volume name")] = info.volume_name_; - - if (info.fs_serial_ != 0) - ret[tr("Filesystem serial number")] = info.fs_serial_; - - return ret; -} - -QString WmdmLister::MakeFriendlyName(const QString& id) { - 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 WmdmLister::MakeDeviceUrls(const QString& id) { - QList ret; - - QString mount_point = LockAndGetDeviceInfo(id, &DeviceInfo::mount_point_); - if (!mount_point.isEmpty()) { - ret << MakeUrlFromLocalPath(mount_point); - } - - QUrl wmdm_url; - wmdm_url.setScheme("wmdm"); - wmdm_url.setPath(id); - ret << wmdm_url; - - return ret; -} - -void WmdmLister::UnmountDevice(const QString& id) { -} - -void WmdmLister::UpdateDeviceFreeSpace(const QString& id) { - // This needs to be done in the lister's thread where we already have COM - // initialised - metaObject()->invokeMethod(this, "DoUpdateDriveFreeSpace", - Qt::BlockingQueuedConnection, Q_ARG(QString, id)); -} - -void WmdmLister::DoUpdateDriveFreeSpace(const QString& id) { - { - QMutexLocker l(&mutex_); - if (!devices_.contains(id)) - return; - - UpdateFreeSpace(&devices_[id]); - } - - emit DeviceChanged(id); -} - -namespace { -qint64 GetSpaceValue( - IWMDMStorageGlobals* globals, - LONG (IWMDMStorageGlobals::*f)(DWORD*,DWORD*)) { - DWORD low, high; - ((globals)->*(f))(&low, &high); - - return (qint64)high << 32 | (qint64)low; -} -} - -void WmdmLister::UpdateFreeSpace(DeviceInfo* info) { - IWMDMStorageGlobals* globals; - info->storage_->GetStorageGlobals(&globals); - - DWORD low, high; - - globals->GetTotalSize(&low, &high); - info->total_bytes_ = (qint64)high << 32 | (qint64)low; - - globals->GetTotalFree(&low, &high); - info->free_bytes_ = (qint64)high << 32 | (qint64)low; - - globals->Release(); -} - -HRESULT WmdmLister::WMDMMessage(DWORD message_type, LPCWSTR name) { - qLog(Debug) << "WMDM message" << message_type << name; - - QString canonical_name = QString::fromWCharArray(name).toLower(); - - switch (message_type) { - case WMDM_MSG_DEVICE_ARRIVAL: WMDMDeviceAdded(canonical_name); break; - case WMDM_MSG_DEVICE_REMOVAL: WMDMDeviceRemoved(canonical_name); break; - } - - return S_OK; -} - -void WmdmLister::WMDMDeviceAdded(const QString& canonical_name) { - ScopedWCharArray name(canonical_name); - - IWMDMDevice* device = NULL; - if (thread_->manager()->GetDeviceFromCanonicalName(name, &device)) { - qLog(Warning) << "Error in GetDeviceFromCanonicalName for" << canonical_name; - return; - } - - IWMDMDevice2* device2 = NULL; - if (device->QueryInterface(IID_IWMDMDevice2, (void**) &device2)) { - qLog(Warning) << "Error getting IWMDMDevice2 from device"; - device->Release(); - return; - } - device->Release(); - - DeviceInfo info = ReadDeviceInfo(device2); - if (info.is_suitable_) { - QString id = info.unique_id(); - { - QMutexLocker l(&mutex_); - devices_[id] = info; - } - emit DeviceAdded(id); - } else { - device2->Release(); - } -} - -void WmdmLister::WMDMDeviceRemoved(const QString& canonical_name) { - QString id = CanonicalNameToId(canonical_name); - { - QMutexLocker l(&mutex_); - if (!devices_.contains(id)) - return; - - devices_[id].device_->Release(); - devices_[id].storage_->Release(); - - devices_.remove(id); - } - - emit DeviceRemoved(id); -} - -LONG WmdmLister::QueryInterface(REFIID riid, void** object) { - *object = 0; - - if (riid == IID_IUnknown) - *object = (IUnknown*) this; - else if (riid == IID_IWMDMNotification) - *object = (IWMDMNotification*) this; - else - return E_NOINTERFACE; - - return S_OK; -} - -ULONG WmdmLister::AddRef() { - return 0; -} - -ULONG WmdmLister::Release() { - return 0; -} - -QString WmdmLister::DeviceCanonicalName(const QString& id) { - return LockAndGetDeviceInfo(id, &DeviceInfo::canonical_name_); -} - diff --git a/src/devices/wmdmlister.h b/src/devices/wmdmlister.h deleted file mode 100644 index ba0ae7bc6..000000000 --- a/src/devices/wmdmlister.h +++ /dev/null @@ -1,141 +0,0 @@ -/* This file is part of Clementine. - Copyright 2010, David Sansome - - 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 . -*/ - -#ifndef WMDMLISTER_H -#define WMDMLISTER_H - -#include "devicelister.h" - -#include -#include -#include -#include - -#include - -#include -#include -#undef LoadIcon - -class WmdmThread; - -class WmdmLister : public DeviceLister, public IWMDMNotification { - Q_OBJECT - -public: - WmdmLister(); - ~WmdmLister(); - - // DeviceLister - virtual void Init(); - - virtual QStringList DeviceUniqueIDs(); - virtual QVariantList DeviceIcons(const QString& id); - virtual QString DeviceManufacturer(const QString& id); - virtual QString DeviceModel(const QString& id); - virtual quint64 DeviceCapacity(const QString& id); - virtual quint64 DeviceFreeSpace(const QString& id); - virtual QVariantMap DeviceHardwareInfo(const QString& id); - virtual QString MakeFriendlyName(const QString& id); - virtual QList MakeDeviceUrls(const QString& id); - virtual void UnmountDevice(const QString& id); - - // IWMDMNotification - // The __stdcall is *really* important - virtual HRESULT __stdcall WMDMMessage(DWORD message_type, LPCWSTR name); - virtual LONG __stdcall QueryInterface(const IID& riid, void** object); - virtual ULONG __stdcall AddRef(); - virtual ULONG __stdcall Release(); - - // Called by WmdmLister - QString DeviceCanonicalName(const QString& id); - -public slots: - virtual void UpdateDeviceFreeSpace(const QString& id); - virtual void ShutDown(); - -private slots: - virtual void DoUpdateDriveFreeSpace(const QString& id); - virtual void ReallyShutdown(); - -private: - struct DeviceInfo { - DeviceInfo() : device_(NULL), storage_(NULL), is_suitable_(false), - total_bytes_(0), free_bytes_(0) {} - - QString unique_id() const; - - IWMDMDevice2* device_; - IWMDMStorage2* storage_; - - bool is_suitable_; - - QString name_; - QString manufacturer_; - QString canonical_name_; - - QPixmap icon_; - - quint64 total_bytes_; - quint64 free_bytes_; - - // Only valid for filesystem devices - QString mount_point_; - QString fs_name_; - QString fs_type_; - int fs_serial_; - - // Information we get by querying win7-style FS devices - QString device_name_; - QString volume_name_; - }; - - static const QUuid kDeviceProtocolMsc; - - DeviceInfo ReadDeviceInfo(IWMDMDevice2* device); - - template - T LockAndGetDeviceInfo(const QString& id, T DeviceInfo::*field); - - void UpdateFreeSpace(DeviceInfo* info); - void GuessDriveLetter(DeviceInfo* info); - bool CheckDriveLetter(DeviceInfo* info, const QString& drive); - - static QString CanonicalNameToId(const QString& canonical_name); - void WMDMDeviceAdded(const QString& canonical_name); - void WMDMDeviceRemoved(const QString& canonical_name); - -private: - boost::scoped_ptr thread_; - - SacHandle sac_; - DWORD notification_cookie_; - - QMutex mutex_; - QMap devices_; -}; - -template -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 diff --git a/src/devices/wmdmloader.cpp b/src/devices/wmdmloader.cpp deleted file mode 100644 index 0467309fa..000000000 --- a/src/devices/wmdmloader.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* This file is part of Clementine. - Copyright 2010, David Sansome - - 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 . -*/ - -#include "devicelister.h" -#include "wmdmdevice.h" -#include "wmdmlister.h" -#include "wmdmloader.h" -#include "wmdmthread.h" -#include "core/taskmanager.h" -#include "library/librarybackend.h" - -#include - -#include -#include - -#include - -WmdmLoader::WmdmLoader(TaskManager* task_manager, LibraryBackend* backend, - boost::shared_ptr device) - : QObject(NULL), - device_(device), - task_manager_(task_manager), - backend_(backend) -{ - original_thread_ = thread(); -} - -WmdmLoader::~WmdmLoader() { -} - -void WmdmLoader::LoadDatabase() { - int task_id = task_manager_->StartTask(tr("Loading Windows Media device")); - emit TaskStarted(task_id); - - boost::scoped_ptr thread(new WmdmThread); - - // Get the device's canonical name - boost::shared_ptr connected_device = - boost::static_pointer_cast(device_); - WmdmLister* lister = static_cast(connected_device->lister()); - QString canonical_name = lister->DeviceCanonicalName(connected_device->unique_id()); - - IWMDMStorage* storage = thread->GetRootStorage(canonical_name); - QStringList path_components; - RecursiveExploreStorage(storage, &path_components); - storage->Release(); - - thread.reset(); - - // Need to remove all the existing songs in the database first - backend_->DeleteSongs(backend_->FindSongsInDirectory(1)); - - // Add the songs we've just loaded - backend_->AddOrUpdateSongs(songs_); - - task_manager_->SetTaskFinished(task_id); - emit LoadFinished(); -} - -void WmdmLoader::RecursiveExploreStorage(IWMDMStorage* parent, QStringList* path_components) { - IWMDMEnumStorage* child_it = NULL; - parent->EnumStorage(&child_it); - - IWMDMStorage* child = NULL; - ULONG num_retreived = 0; - while (child_it->Next(1, &child, &num_retreived) == S_OK && num_retreived == 1) { - const int kMaxLen = 255; - wchar_t name[kMaxLen]; - child->GetName(name, kMaxLen); - - DWORD attributes = 0; - _WAVEFORMATEX audio_format; - child->GetAttributes(&attributes, &audio_format); - - path_components->append(QString::fromWCharArray(name)); - if (attributes & WMDM_FILE_ATTR_FILE) { - LoadFile(child, path_components); - } else if (attributes & WMDM_FILE_ATTR_FOLDER) { - RecursiveExploreStorage(child, path_components); - } - path_components->removeLast(); - - child->Release(); - } - child_it->Release(); -} - -void WmdmLoader::LoadFile(IWMDMStorage* file, const QStringList* path_components) { - // Convert to a IWMDMStorage3 so we can get metadata - IWMDMStorage3* storage3 = NULL; - if (file->QueryInterface(IID_IWMDMStorage3, (void**) &storage3)) - return; - - // Get the metadata interface - IWMDMMetaData* metadata = NULL; - if (storage3->GetMetadata(&metadata)) { - storage3->Release(); - return; - } - storage3->Release(); - - QUrl url; - url.setScheme("wmdm"); - url.setPath(path_components->join("/")); - - // Store the metadata in here - Song song; - song.InitFromWmdm(metadata); - song.set_directory_id(1); - song.set_url(url); - - metadata->Release(); - - if (song.is_valid()) - songs_ << song; -} - - diff --git a/src/devices/wmdmloader.h b/src/devices/wmdmloader.h deleted file mode 100644 index 098e4ed98..000000000 --- a/src/devices/wmdmloader.h +++ /dev/null @@ -1,63 +0,0 @@ -/* This file is part of Clementine. - Copyright 2010, David Sansome - - 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 . -*/ - -#ifndef WMDMLOADER_H -#define WMDMLOADER_H - -#include - -#include - -#include "core/song.h" - -class ConnectedDevice; -class LibraryBackend; -class TaskManager; - -struct IWMDMStorage; - -class WmdmLoader : public QObject { - Q_OBJECT - -public: - WmdmLoader(TaskManager* task_manager, LibraryBackend* backend, - boost::shared_ptr device); - ~WmdmLoader(); - -public slots: - void LoadDatabase(); - -signals: - void Error(const QString& message); - void TaskStarted(int task_id); - void LoadFinished(); - -private: - void RecursiveExploreStorage(IWMDMStorage* parent, QStringList* path_components); - void LoadFile(IWMDMStorage* file, const QStringList* path_components); - -private: - boost::shared_ptr device_; - QThread* original_thread_; - - TaskManager* task_manager_; - LibraryBackend* backend_; - - SongList songs_; -}; - -#endif // WMDMLOADER_H diff --git a/src/devices/wmdmprogress.cpp b/src/devices/wmdmprogress.cpp deleted file mode 100644 index 349e4ecb6..000000000 --- a/src/devices/wmdmprogress.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* This file is part of Clementine. - Copyright 2010, David Sansome - - 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 . -*/ - -#include "wmdmprogress.h" - -#include - -WmdmProgress::WmdmProgress(const MusicStorage::ProgressFunction& f) - : f_(f), - estimated_(0) -{ -} - -LONG WmdmProgress::QueryInterface(const IID& riid, void** object) { - *object = 0; - - if (riid == IID_IUnknown) - *object = (IUnknown*) this; - else if (riid == IID_IWMDMProgress) - *object = (IWMDMProgress*) this; - else if (riid == IID_IWMDMProgress2) - *object = (IWMDMProgress2*) this; - else if (riid == IID_IWMDMProgress3) - *object = (IWMDMProgress3*) this; - else - return E_NOINTERFACE; - - return S_OK; -} - -ULONG WmdmProgress::AddRef() { - return 0; -} - -ULONG WmdmProgress::Release() { - return 0; -} - -HRESULT WmdmProgress::Begin(DWORD estimated_ticks) { - return Begin3(EVENT_WMDM_CONTENT_TRANSFER, estimated_ticks, NULL); -} - -HRESULT WmdmProgress::End() { - return End3(EVENT_WMDM_CONTENT_TRANSFER, S_OK, NULL); -} - -HRESULT WmdmProgress::Progress(DWORD transpired_ticks) { - return Progress3(EVENT_WMDM_CONTENT_TRANSFER, transpired_ticks, NULL); -} - -HRESULT WmdmProgress::End2(HRESULT completion_code) { - return End3(EVENT_WMDM_CONTENT_TRANSFER, completion_code, NULL); -} - -HRESULT WmdmProgress::Begin3(GUID, DWORD estimated_ticks, OPAQUECOMMAND*) { - estimated_ = estimated_ticks; - return S_OK; -} - -HRESULT WmdmProgress::End3(GUID, HRESULT, OPAQUECOMMAND*) { - return S_OK; -} - -HRESULT WmdmProgress::Progress3(GUID, DWORD transpired_ticks, OPAQUECOMMAND*) { - if (estimated_ != 0) - f_(float(transpired_ticks) / estimated_); - return S_OK; -} diff --git a/src/devices/wmdmprogress.h b/src/devices/wmdmprogress.h deleted file mode 100644 index 2619e9256..000000000 --- a/src/devices/wmdmprogress.h +++ /dev/null @@ -1,58 +0,0 @@ -/* This file is part of Clementine. - Copyright 2010, David Sansome - - 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 . -*/ - -#ifndef WMDMPROGRESS_H -#define WMDMPROGRESS_H - -#include - -#include "core/musicstorage.h" - -class WmdmProgress : public IWMDMProgress3 { -public: - WmdmProgress(const MusicStorage::ProgressFunction& f = - MusicStorage::ProgressFunction()); - - // IUnknown - // The __stdcall is *really* important - virtual LONG __stdcall QueryInterface(const IID& riid, void** object); - virtual ULONG __stdcall AddRef(); - virtual ULONG __stdcall Release(); - - // IWMDMProgress - virtual HRESULT __stdcall Begin(DWORD estimated_ticks); - virtual HRESULT __stdcall End(); - virtual HRESULT __stdcall Progress(DWORD transpired_ticks); - - // IWMDMProgress2 - virtual HRESULT __stdcall End2(HRESULT completion_code); - - // IWMDMProgress3 - virtual HRESULT __stdcall Begin3(GUID event_id, DWORD estimated_ticks, - OPAQUECOMMAND* context); - virtual HRESULT __stdcall End3(GUID event_id, HRESULT completion_code, - OPAQUECOMMAND* context); - virtual HRESULT __stdcall Progress3(GUID event_id, DWORD transpired_ticks, - OPAQUECOMMAND* context); - -private: - MusicStorage::ProgressFunction f_; - - DWORD estimated_; -}; - -#endif // WMDMPROGRESS_H diff --git a/src/devices/wmdmthread.cpp b/src/devices/wmdmthread.cpp deleted file mode 100644 index 1e8754e6e..000000000 --- a/src/devices/wmdmthread.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/* This file is part of Clementine. - Copyright 2010, David Sansome - - 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 . -*/ - -#include "wmdmthread.h" -#include "core/logging.h" -#include "core/utilities.h" - -#include - -#include - -#include -#include -#include -#include - -BYTE abPVK[] = {0x00}; -BYTE abCert[] = {0x00}; - -bool WmdmThread::sIsLoaded = false; - -decltype(&CSecureChannelClient_New) WmdmThread::_CSecureChannelClient_New; -decltype(&CSecureChannelClient_Free) WmdmThread::_CSecureChannelClient_Free; -decltype(&CSecureChannelClient_SetCertificate) WmdmThread::_CSecureChannelClient_SetCertificate; -decltype(&CSecureChannelClient_SetInterface) WmdmThread::_CSecureChannelClient_SetInterface; -decltype(&CSecureChannelClient_Authenticate) WmdmThread::_CSecureChannelClient_Authenticate; - - -WmdmThread::WmdmThread() - : device_manager_(NULL), - sac_(NULL) -{ - if (!sIsLoaded) { - return; - } - // Initialise COM - CoInitialize(0); - - // Authenticate with WMDM - IComponentAuthenticate* auth; - if (CoCreateInstance(CLSID_MediaDevMgr, NULL, CLSCTX_ALL, - IID_IComponentAuthenticate, (void**) &auth)) { - qLog(Warning) << "Error creating the IComponentAuthenticate interface"; - return; - } - - sac_ = _CSecureChannelClient_New(); - if (_CSecureChannelClient_SetCertificate( - sac_, SAC_CERT_V1, abCert, sizeof(abCert), abPVK, sizeof(abPVK))) { - qLog(Warning) << "Error setting SAC certificate"; - return; - } - - _CSecureChannelClient_SetInterface(sac_, auth); - if (_CSecureChannelClient_Authenticate(sac_, SAC_PROTOCOL_V1)) { - qLog(Warning) << "Error authenticating with SAC"; - return; - } - - // Create the device manager - if (auth->QueryInterface(IID_IWMDeviceManager2, (void**)&device_manager_)) { - qLog(Warning) << "Error creating WMDM device manager"; - return; - } -} - -WmdmThread::~WmdmThread() { - if (device_manager_) { - // Release the device manager - device_manager_->Release(); - } - - if (sac_) { - // SAC - _CSecureChannelClient_Free(sac_); - } - - // Uninitialise COM - CoUninitialize(); -} - -namespace { - -template -T Resolve(QLibrary* library, const char* name) { - return reinterpret_cast(library->resolve(name)); -} - -} // namespace - -bool WmdmThread::StaticInit() { - if (!sIsLoaded) { - QLibrary library(QCoreApplication::applicationDirPath() + "/sac_shim.dll"); - if (!library.load()) { - return false; - } - - _CSecureChannelClient_New = Resolve( - &library, "CSecureChannelClient_New"); - _CSecureChannelClient_Free = Resolve( - &library, "CSecureChannelClient_Free"); - _CSecureChannelClient_SetCertificate = Resolve( - &library, "CSecureChannelClient_SetCertificate"); - _CSecureChannelClient_SetInterface = Resolve( - &library, "CSecureChannelClient_SetInterface"); - if (_CSecureChannelClient_New && - _CSecureChannelClient_Free && - _CSecureChannelClient_SetCertificate && - _CSecureChannelClient_SetInterface) { - sIsLoaded = true; - return true; - } - } - return false; -} - -IWMDMDevice* WmdmThread::GetDeviceByCanonicalName(const QString& device_name) { - ScopedWCharArray name(device_name); - - IWMDMDevice* device = NULL; - if (device_manager_->GetDeviceFromCanonicalName(name, &device)) { - qLog(Warning) << "Error in GetDeviceFromCanonicalName for" << device_name; - return NULL; - } - - return device; -} - -IWMDMStorage* WmdmThread::GetRootStorage(const QString& device_name) { - IWMDMDevice* device = GetDeviceByCanonicalName(device_name); - - IWMDMEnumStorage* storage_it = NULL; - device->EnumStorage(&storage_it); - - ULONG storage_fetched = 0; - IWMDMStorage* storage = NULL; - storage_it->Next(1, &storage, &storage_fetched); - - storage_it->Release(); - device->Release(); - - return storage; -} diff --git a/src/devices/wmdmthread.h b/src/devices/wmdmthread.h deleted file mode 100644 index 98a665ffe..000000000 --- a/src/devices/wmdmthread.h +++ /dev/null @@ -1,57 +0,0 @@ -/* This file is part of Clementine. - Copyright 2010, David Sansome - - 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 . -*/ - -#ifndef WMDMTHREAD_H -#define WMDMTHREAD_H - -#include -#include - -#include - -struct IWMDeviceManager2; -struct IWMDMDevice; -struct IWMDMStorage; - -class WmdmThread { -public: - WmdmThread(); - ~WmdmThread(); - - IWMDeviceManager2* manager() const { return device_manager_; } - - IWMDMDevice* GetDeviceByCanonicalName(const QString& device_name); - IWMDMStorage* GetRootStorage(const QString& device_name); - - static bool StaticInit(); -private: - - Q_DISABLE_COPY(WmdmThread); - - IWMDeviceManager2* device_manager_; - SacHandle sac_; - - static decltype(&CSecureChannelClient_New) _CSecureChannelClient_New; - static decltype(&CSecureChannelClient_Free) _CSecureChannelClient_Free; - static decltype(&CSecureChannelClient_SetCertificate) _CSecureChannelClient_SetCertificate; - static decltype(&CSecureChannelClient_SetInterface) _CSecureChannelClient_SetInterface; - static decltype(&CSecureChannelClient_Authenticate) _CSecureChannelClient_Authenticate; - - static bool sIsLoaded; -}; - -#endif // WMDMTHREAD_H diff --git a/src/main.cpp b/src/main.cpp index 709f6f589..5f75aad8f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -101,7 +101,6 @@ using boost::scoped_ptr; #ifdef Q_OS_WIN32 # include -# include "devices/wmdmthread.h" #endif // Load sqlite plugin on windows and mac. @@ -447,12 +446,6 @@ int main(int argc, char *argv[]) { mpris::Mpris mpris(&app); #endif -#ifdef Q_OS_WIN32 - if (!WmdmThread::StaticInit()) { - qLog(Warning) << "Failed to initialise SAC shim"; - } -#endif - // Window MainWindow w(&app, tray_icon.get(), &osd); #ifdef Q_OS_DARWIN