Index: base/autodetection.cpp =================================================================== --- base/autodetection.cpp (revision 20572) +++ base/autodetection.cpp (working copy) @@ -238,6 +238,11 @@ return tempList; } + +/** resolve device name to mount point / drive letter + * @brief device device name / disk number + * @return mount point / drive letter + */ QString Autodetection::resolveMountPoint(QString device) { qDebug() << "Autodetection::resolveMountPoint(QString)" << device; @@ -289,39 +294,57 @@ QString result; unsigned int driveno = device.replace(QRegExp("^.*([0-9]+)"), "\\1").toInt(); - for(int letter = 'A'; letter <= 'Z'; letter++) { - DWORD written; - HANDLE h; - TCHAR uncpath[MAX_PATH]; - UCHAR buffer[0x400]; - PVOLUME_DISK_EXTENTS extents = (PVOLUME_DISK_EXTENTS)buffer; + int letter; + for(letter = 'A'; letter <= 'Z'; letter++) { + if(resolveDevicename(QString(letter)).toUInt() == driveno) { + result = letter; + break; + } + } + qDebug() << "Autodetection::resolveMountPoint(QString)" << "->" << result; + if(!result.isEmpty()) + return result + ":/"; +#endif + return QString(""); +} - _stprintf(uncpath, _TEXT("\\\\.\\%c:"), letter); - h = CreateFile(uncpath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, OPEN_EXISTING, 0, NULL); - if(h == INVALID_HANDLE_VALUE) { - //qDebug() << "error getting extents for" << uncpath; - continue; - } - // get the extents - if(DeviceIoControl(h, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, - NULL, 0, extents, sizeof(buffer), &written, NULL)) { - for(unsigned int a = 0; a < extents->NumberOfDiskExtents; a++) { - qDebug() << "Disk:" << extents->Extents[a].DiskNumber; - if(extents->Extents[a].DiskNumber == driveno) { - result = letter; - qDebug("drive found for volume %i: %c", driveno, letter); - break; - } - } - } +/** Resolve mountpoint to devicename / disk number + * @param path mountpoint path / drive letter + * @return devicename / disk number + */ +QString Autodetection::resolveDevicename(QString path) +{ + qDebug() << __func__; + QString result; +#if defined(Q_OS_WIN32) + DWORD written; + HANDLE h; + TCHAR uncpath[MAX_PATH]; + UCHAR buffer[0x400]; + PVOLUME_DISK_EXTENTS extents = (PVOLUME_DISK_EXTENTS)buffer; + _stprintf(uncpath, _TEXT("\\\\.\\%c:"), path.toAscii().at(0)); + h = CreateFile(uncpath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, 0, NULL); + if(h == INVALID_HANDLE_VALUE) { + //qDebug() << "error getting extents for" << uncpath; + return ""; } - if(!result.isEmpty()) - return result + ":/"; + // get the extents + if(DeviceIoControl(h, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, + NULL, 0, extents, sizeof(buffer), &written, NULL)) { + if(extents->NumberOfDiskExtents > 1) { + qDebug() << "volume spans multiple disks!"; + return ""; + } + //qDebug() << "Disk:" << extents->Extents[0].DiskNumber; + result = QString("%1").arg(extents->Extents[0].DiskNumber); + } #endif - return QString(""); + qDebug() << __func__ << path << " ->" << result; + return result; + } Index: base/autodetection.h =================================================================== --- base/autodetection.h (revision 20572) +++ base/autodetection.h (working copy) @@ -42,6 +42,7 @@ QString errdev(void) { return m_errdev; } QString incompatdev(void) { return m_incompat; } static QStringList mountpoints(void); + static QString resolveDevicename(QString path); private: QString resolveMountPoint(QString); Index: base/bootloaderinstallipod.cpp =================================================================== --- base/bootloaderinstallipod.cpp (revision 20572) +++ base/bootloaderinstallipod.cpp (working copy) @@ -22,6 +22,7 @@ #include "bootloaderinstallipod.h" #include "../ipodpatcher/ipodpatcher.h" +#include "autodetection.h" BootloaderInstallIpod::BootloaderInstallIpod(QObject *parent) @@ -199,11 +200,13 @@ result = BootloaderUnknown; } - if (ipod.ipod_directory[0].entryOffset == 0) { + else if (ipod.ipod_directory[0].entryOffset == 0) { qDebug() << "BootloaderInstallIpod::installed(): BootloaderOther"; result = BootloaderOther; } - qDebug() << "BootloaderInstallIpod::installed(): BootloaderRockbox"; + else { + qDebug() << "BootloaderInstallIpod::installed(): BootloaderRockbox"; + } ipod_close(&ipod); return result; @@ -218,20 +221,28 @@ bool BootloaderInstallIpod::ipodInitialize(struct ipod_t *ipod) { - ipod_scan(ipod); + if(!m_blfile.isEmpty()) { + sprintf(ipod->diskname, "\\\\.\\PhysicalDrive%i", + Autodetection::resolveDevicename(m_blfile).toInt()); + qDebug() << "ipodpatcher: overriding scan, using" << ipod->diskname; + } + else { + ipod_scan(ipod); + } if(ipod_open(ipod, 0) < 0) { emit logItem(tr("Could not open Ipod"), LOGERROR); return false; } if(read_partinfo(ipod, 0) < 0) { - emit logItem(tr("Could not read partition table"), LOGERROR); + emit logItem(tr("Error reading partition table - possibly not an Ipod"), LOGERROR); + ipod_close(ipod); return false; } if(ipod->pinfo[0].start == 0) { emit logItem(tr("No firmware partition on disk"), LOGERROR); - + ipod_close(ipod); return false; } return true; Index: base/bootloaderinstallsansa.cpp =================================================================== --- base/bootloaderinstallsansa.cpp (revision 20572) +++ base/bootloaderinstallsansa.cpp (working copy) @@ -22,6 +22,7 @@ #include "bootloaderinstallsansa.h" #include "../sansapatcher/sansapatcher.h" +#include "autodetection.h" BootloaderInstallSansa::BootloaderInstallSansa(QObject *parent) : BootloaderInstallBase(parent) @@ -80,32 +81,14 @@ void BootloaderInstallSansa::installStage2(void) { struct sansa_t sansa; - sansa_scan(&sansa); emit logItem(tr("Installing Rockbox bootloader"), LOGINFO); QCoreApplication::processEvents(); - - if(sansa_open(&sansa, 0) < 0) { - emit logItem(tr("could not open Sansa"), LOGERROR); - emit done(true); - return; + if(!sansaInitialize(&sansa)) { + emit done(true); + return; } - if(sansa_read_partinfo(&sansa, 0) < 0) - { - emit logItem(tr("could not read partitiontable"), LOGERROR); - emit done(true); - return; - } - - int i = is_sansa(&sansa); - if(i < 0) { - - emit logItem(tr("Disk is not a Sansa (Error: %1), aborting.").arg(i), LOGERROR); - emit done(true); - return; - } - if(sansa.hasoldbootloader) { emit logItem(tr("OLD ROCKBOX INSTALLATION DETECTED, ABORTING.\n" "You must reinstall the original Sansa firmware before running\n" @@ -152,31 +135,11 @@ emit logItem(tr("Uninstalling bootloader"), LOGINFO); QCoreApplication::processEvents(); - if(sansa_scan(&sansa) != 1) { - emit logItem(tr("Can't find Sansa"), LOGERROR); + if(!sansaInitialize(&sansa)) { emit done(true); return false; } - if (sansa_open(&sansa, 0) < 0) { - emit logItem(tr("Could not open Sansa"), LOGERROR); - emit done(true); - return false; - } - - if (sansa_read_partinfo(&sansa,0) < 0) { - emit logItem(tr("Could not read partition table"), LOGERROR); - emit done(true); - return false; - } - - int i = is_sansa(&sansa); - if(i < 0) { - emit logItem(tr("Disk is not a Sansa (Error %1), aborting.").arg(i), LOGERROR); - emit done(true); - return false; - } - if (sansa.hasoldbootloader) { emit logItem(tr("OLD ROCKBOX INSTALLATION DETECTED, ABORTING.\n" "You must reinstall the original Sansa firmware before running\n" @@ -218,20 +181,9 @@ struct sansa_t sansa; int num; - if(sansa_scan(&sansa) != 1) { + if(!sansaInitialize(&sansa)) { return BootloaderUnknown; } - if (sansa_open(&sansa, 0) < 0) { - return BootloaderUnknown; - } - if (sansa_read_partinfo(&sansa,0) < 0) { - sansa_close(&sansa); - return BootloaderUnknown; - } - if(is_sansa(&sansa) < 0) { - sansa_close(&sansa); - return BootloaderUnknown; - } if((num = sansa_list_images(&sansa)) == 2) { sansa_close(&sansa); return BootloaderRockbox; @@ -244,7 +196,39 @@ } +bool BootloaderInstallSansa::sansaInitialize(struct sansa_t *sansa) +{ + if(!m_blfile.isEmpty()) { + sprintf(sansa->diskname, "\\\\.\\PhysicalDrive%i", + Autodetection::resolveDevicename(m_blfile).toInt()); + qDebug() << "sansapatcher: overriding scan, using" << sansa->diskname; + } + else if(sansa_scan(sansa) != 1) { + emit logItem(tr("Can't find Sansa"), LOGERROR); + return false; + } + if (sansa_open(sansa, 0) < 0) { + emit logItem(tr("Could not open Sansa"), LOGERROR); + return false; + } + + if (sansa_read_partinfo(sansa,0) < 0) { + emit logItem(tr("Could not read partition table"), LOGERROR); + sansa_close(sansa); + return false; + } + + int i = is_sansa(sansa); + if(i < 0) { + emit logItem(tr("Disk is not a Sansa (Error %1), aborting.").arg(i), LOGERROR); + sansa_close(sansa); + return false; + } + return true; +} + + /** Get capabilities of subclass installer. */ BootloaderInstallBase::Capabilities BootloaderInstallSansa::capabilities(void) Index: base/bootloaderinstallsansa.h =================================================================== --- base/bootloaderinstallsansa.h (revision 20572) +++ base/bootloaderinstallsansa.h (working copy) @@ -38,6 +38,7 @@ Capabilities capabilities(void); private: + bool sansaInitialize(struct sansa_t *); private slots: void installStage2(void);