diff --git a/CMakeLists.txt b/CMakeLists.txt
index ad57007cf..c5e85a357 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -41,7 +41,7 @@ pkg_check_modules(LIBMTP libmtp)
 
 if (WIN32)
   find_package(ZLIB REQUIRED)
-  find_library(MSWMDM_LIBRARIES MSWMDM)
+  find_library(MSWMDM_LIBRARIES mswmdm)
   find_library(SAC_SHIM_LIBRARIES sac_shim)
 endif (WIN32)
 
diff --git a/src/core/song.cpp b/src/core/song.cpp
index 1845bcf44..44e7e91ea 100644
--- a/src/core/song.cpp
+++ b/src/core/song.cpp
@@ -53,91 +53,6 @@
 #ifdef Q_OS_WIN32
 # include <mswmdm.h>
 # include <QUuid>
-
-  // Copied from the WMDM SDK 11, it doesn't seem to be included in SDK 9 for
-  // some reason, even though the devices use it.
-  typedef enum tagWMDM_FORMATCODE {
-    WMDM_FORMATCODE_NOTUSED  =  0x0000,
-    WMDM_FORMATCODE_ALLIMAGES  =  0xFFFFFFFF,
-    WMDM_FORMATCODE_UNDEFINED  =  0x3000,
-    WMDM_FORMATCODE_ASSOCIATION  =  0x3001,
-    WMDM_FORMATCODE_SCRIPT  =  0x3002,
-    WMDM_FORMATCODE_EXECUTABLE  =  0x3003,
-    WMDM_FORMATCODE_TEXT  =  0x3004,
-    WMDM_FORMATCODE_HTML  =  0x3005,
-    WMDM_FORMATCODE_DPOF  =  0x3006,
-    WMDM_FORMATCODE_AIFF  =  0x3007,
-    WMDM_FORMATCODE_WAVE  =  0x3008,
-    WMDM_FORMATCODE_MP3  =  0x3009,
-    WMDM_FORMATCODE_AVI  =  0x300A,
-    WMDM_FORMATCODE_MPEG  =  0x300B,
-    WMDM_FORMATCODE_ASF  =  0x300C,
-    WMDM_FORMATCODE_RESERVED_FIRST  =  0x300D,
-    WMDM_FORMATCODE_RESERVED_LAST  =  0x37FF,
-    WMDM_FORMATCODE_IMAGE_UNDEFINED  =  0x3800,
-    WMDM_FORMATCODE_IMAGE_EXIF  =  0x3801,
-    WMDM_FORMATCODE_IMAGE_TIFFEP  =  0x3802,
-    WMDM_FORMATCODE_IMAGE_FLASHPIX  =  0x3803,
-    WMDM_FORMATCODE_IMAGE_BMP  =  0x3804,
-    WMDM_FORMATCODE_IMAGE_CIFF  =  0x3805,
-    WMDM_FORMATCODE_IMAGE_GIF  =  0x3807,
-    WMDM_FORMATCODE_IMAGE_JFIF  =  0x3808,
-    WMDM_FORMATCODE_IMAGE_PCD  =  0x3809,
-    WMDM_FORMATCODE_IMAGE_PICT  =  0x380A,
-    WMDM_FORMATCODE_IMAGE_PNG  =  0x380B,
-    WMDM_FORMATCODE_IMAGE_TIFF  =  0x380D,
-    WMDM_FORMATCODE_IMAGE_TIFFIT  =  0x380E,
-    WMDM_FORMATCODE_IMAGE_JP2  =  0x380F,
-    WMDM_FORMATCODE_IMAGE_JPX  =  0x3810,
-    WMDM_FORMATCODE_IMAGE_RESERVED_FIRST  =  0x3811,
-    WMDM_FORMATCODE_IMAGE_RESERVED_LAST  =  0x3FFF,
-    WMDM_FORMATCODE_UNDEFINEDFIRMWARE  =  0xB802,
-    WMDM_FORMATCODE_WINDOWSIMAGEFORMAT  =  0xB881,
-    WMDM_FORMATCODE_UNDEFINEDAUDIO  =  0xB900,
-    WMDM_FORMATCODE_WMA  =  0xB901,
-    WMDM_FORMATCODE_OGG = 0xB902,
-    WMDM_FORMATCODE_AAC  = 0xB903,
-    WMDM_FORMATCODE_AUDIBLE = 0xB904,
-    WMDM_FORMATCODE_FLAC = 0xB906,
-    WMDM_FORMATCODE_UNDEFINEDVIDEO  =  0xB980,
-    WMDM_FORMATCODE_WMV  =  0xB981,
-    WMDM_FORMATCODE_MP4 = 0xB982,
-    WMDM_FORMATCODE_MP2 = 0xB983,
-    WMDM_FORMATCODE_UNDEFINEDCOLLECTION  =  0xBA00,
-    WMDM_FORMATCODE_ABSTRACTMULTIMEDIAALBUM  =  0xBA01,
-    WMDM_FORMATCODE_ABSTRACTIMAGEALBUM  =  0xBA02,
-    WMDM_FORMATCODE_ABSTRACTAUDIOALBUM  =  0xBA03,
-    WMDM_FORMATCODE_ABSTRACTVIDEOALBUM  =  0xBA04,
-    WMDM_FORMATCODE_ABSTRACTAUDIOVIDEOPLAYLIST  =  0xBA05,
-    WMDM_FORMATCODE_ABSTRACTCONTACTGROUP  =  0xBA06,
-    WMDM_FORMATCODE_ABSTRACTMESSAGEFOLDER  =  0xBA07,
-    WMDM_FORMATCODE_ABSTRACTCHAPTEREDPRODUCTION  =  0xBA08,
-    WMDM_FORMATCODE_WPLPLAYLIST  =  0xBA10,
-    WMDM_FORMATCODE_M3UPLAYLIST  =  0xBA11,
-    WMDM_FORMATCODE_MPLPLAYLIST  =  0xBA12,
-    WMDM_FORMATCODE_ASXPLAYLIST  =  0xBA13,
-    WMDM_FORMATCODE_PLSPLAYLIST  =  0xBA14,
-    WMDM_FORMATCODE_UNDEFINEDDOCUMENT  =  0xBA80,
-    WMDM_FORMATCODE_ABSTRACTDOCUMENT  =  0xBA81,
-    WMDM_FORMATCODE_XMLDOCUMENT = 0xBA82,
-    WMDM_FORMATCODE_MICROSOFTWORDDOCUMENT= 0xBA83,
-    WMDM_FORMATCODE_MHTCOMPILEDHTMLDOCUMENT = 0xBA84,
-    WMDM_FORMATCODE_MICROSOFTEXCELSPREADSHEET = 0xBA85,
-    WMDM_FORMATCODE_MICROSOFTPOWERPOINTDOCUMENT = 0xBA86,
-    WMDM_FORMATCODE_UNDEFINEDMESSAGE  =  0xBB00,
-    WMDM_FORMATCODE_ABSTRACTMESSAGE  =  0xBB01,
-    WMDM_FORMATCODE_UNDEFINEDCONTACT  =  0xBB80,
-    WMDM_FORMATCODE_ABSTRACTCONTACT  =  0xBB81,
-    WMDM_FORMATCODE_VCARD2  =  0xBB82,
-    WMDM_FORMATCODE_VCARD3  =  0xBB83,
-    WMDM_FORMATCODE_UNDEFINEDCALENDARITEM  =  0xBE00,
-    WMDM_FORMATCODE_ABSTRACTCALENDARITEM  =  0xBE01,
-    WMDM_FORMATCODE_VCALENDAR1  =  0xBE02,
-    WMDM_FORMATCODE_VCALENDAR2 = 0xBE03,
-    WMDM_FORMATCODE_UNDEFINEDWINDOWSEXECUTABLE  =  0xBE80,
-    WMDM_FORMATCODE_MEDIA_CAST = 0xBE81,
-    WMDM_FORMATCODE_SECTION = 0xBE82
-  } WMDM_FORMATCODE;
 #endif // Q_OS_WIN32
 
 #include <boost/scoped_array.hpp>
diff --git a/src/devices/wmdmlister.cpp b/src/devices/wmdmlister.cpp
index bd5869dcf..bfd579a05 100644
--- a/src/devices/wmdmlister.cpp
+++ b/src/devices/wmdmlister.cpp
@@ -14,13 +14,15 @@
    along with Clementine.  If not, see <http://www.gnu.org/licenses/>.
 */
 
+#define _WIN32_WINNT 0x0501
+
 #include "wmdmlister.h"
 #include "wmdmthread.h"
 #include "core/utilities.h"
 
-#include <icomponentauthenticate.h>
 #include <objbase.h>
 #include <mswmdm_i.c>
+#include <winbase.h>
 
 #include <boost/bind.hpp>
 #include <boost/scoped_array.hpp>
@@ -29,6 +31,9 @@
 #include <QStringList>
 #include <QtDebug>
 
+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;
 }
@@ -139,14 +144,23 @@ WmdmLister::DeviceInfo WmdmLister::ReadDeviceInfo(IWMDMDevice2* device) {
   const int max_size = 512;
   wchar_t buf[max_size];
   device->GetName(buf, max_size);
-  ret.name_ = QString::fromWCharArray(buf);
+  ret.name_ = QString::fromWCharArray(buf).trimmed();
 
   device->GetManufacturer(buf, max_size);
-  ret.manufacturer_ = QString::fromWCharArray(buf);
+  ret.manufacturer_ = QString::fromWCharArray(buf).trimmed();
 
   device->GetCanonicalName(buf, max_size);
   ret.canonical_name_ = QString::fromWCharArray(buf).toLower();
 
+  // 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;
+  device3->GetProperty(g_wszWMDMDeviceProtocol, &protocol);
+  device3->Release();
+
   // Get the type and check whether it has storage
   DWORD type = 0;
   device->GetType(&type);
@@ -180,34 +194,99 @@ WmdmLister::DeviceInfo WmdmLister::ReadDeviceInfo(IWMDMDevice2* device) {
 
   // 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.
-  QRegExp drive_letter("\\(([A-Z]:)\\)$");
-  if (drive_letter.indexIn(ret.name_) != -1) {
-    // Sanity check to make sure there really is a drive there
-    ScopedWCharArray path(drive_letter.cap(1) + "\\");
-    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
-        )) {
-      qWarning() << "Error getting volume information for" << drive_letter.cap(1);
-    } else {
-      ret.mount_point_ = drive_letter.cap(1) + "/";
-      ret.fs_name_ = name.ToString();
-      ret.fs_type_ = type.ToString();
-      ret.fs_serial_ = serial;
-    }
-  }
+  if (QUuid(*protocol.puuid) == kDeviceProtocolMsc)
+    GuessDriveLetter(&ret);
 
   return ret;
 }
 
+void WmdmLister::GuessDriveLetter(DeviceInfo* info) {
+  // 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) {
+    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) {
+    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)) {
+          qWarning() << "Error getting volume information for" <<
+              QString::fromWCharArray(volume_path);
+        } else {
+          if (name.ToString() == info->name_ && name.characters() != 0) {
+            // We found it!
+            CheckDriveLetter(info, QString::fromWCharArray(volume_path));
+            break;
+          }
+        }
+      }
+    }
+
+    if (!FindNextVolumeW(handle, volume_name, MAX_PATH))
+      break;
+  }
+  FindVolumeClose(handle);
+}
+
+void 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
+      )) {
+    qWarning() << "Error getting volume information for" << drive;
+  } else {
+    info->mount_point_ = drive + "/";
+    info->fs_name_ = name.ToString();
+    info->fs_type_ = type.ToString();
+    info->fs_serial_ = serial;
+  }
+}
+
 QStringList WmdmLister::DeviceUniqueIDs() {
   QMutexLocker l(&mutex_);
   return devices_.keys();
diff --git a/src/devices/wmdmlister.h b/src/devices/wmdmlister.h
index 7ef646bd8..f32c72428 100644
--- a/src/devices/wmdmlister.h
+++ b/src/devices/wmdmlister.h
@@ -22,6 +22,7 @@
 #include <QMap>
 #include <QMutex>
 #include <QPixmap>
+#include <QUuid>
 
 #include <boost/scoped_ptr.hpp>
 
@@ -98,12 +99,16 @@ private:
     int fs_serial_;
   };
 
+  static const QUuid kDeviceProtocolMsc;
+
   DeviceInfo ReadDeviceInfo(IWMDMDevice2* device);
 
   template <typename T>
   T LockAndGetDeviceInfo(const QString& id, T DeviceInfo::*field);
 
   void UpdateFreeSpace(DeviceInfo* info);
+  void GuessDriveLetter(DeviceInfo* info);
+  void CheckDriveLetter(DeviceInfo* info, const QString& drive);
 
   static QString CanonicalNameToId(const QString& canonical_name);
   void WMDMDeviceAdded(const QString& canonical_name);