rockbox/rbutil/rbutilqt/base/bootloaderinstallipod.cpp

263 lines
7.3 KiB
C++

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2008 by Dominik Riebeling
* $Id$
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include <QtCore>
#include "bootloaderinstallbase.h"
#include "bootloaderinstallipod.h"
#include "../ipodpatcher/ipodpatcher.h"
#include "autodetection.h"
BootloaderInstallIpod::BootloaderInstallIpod(QObject *parent)
: BootloaderInstallBase(parent)
{
(void)parent;
// initialize sector buffer. ipod_sectorbuf is defined in ipodpatcher.
ipod_sectorbuf = NULL;
ipod_alloc_buffer(&ipod_sectorbuf, BUFFER_SIZE);
}
BootloaderInstallIpod::~BootloaderInstallIpod()
{
if(ipod_sectorbuf)
free(ipod_sectorbuf);
}
bool BootloaderInstallIpod::install(void)
{
if(ipod_sectorbuf == NULL) {
emit logItem(tr("Error: can't allocate buffer memory!"), LOGERROR);
emit done(true);
return false;
}
struct ipod_t ipod;
int n = ipod_scan(&ipod);
if(n == -1) {
emit logItem(tr("No Ipod detected\n"
"Permission for disc access denied!"),
LOGERROR);
emit done(true);
return false;
}
if(n == 0) {
emit logItem(tr("No Ipod detected!"), LOGERROR);
emit done(true);
return false;
}
if(ipod.macpod) {
emit logItem(tr("Warning: This is a MacPod, Rockbox only runs on WinPods.\n"
"See http://www.rockbox.org/wiki/IpodConversionToFAT32"), LOGERROR);
emit done(true);
return false;
}
emit logItem(tr("Downloading bootloader file"), LOGINFO);
downloadBlStart(m_blurl);
connect(this, SIGNAL(downloadDone()), this, SLOT(installStage2()));
return true;
}
void BootloaderInstallIpod::installStage2(void)
{
struct ipod_t ipod;
emit logItem(tr("Installing Rockbox bootloader"), LOGINFO);
QCoreApplication::processEvents();
if(!ipodInitialize(&ipod)) {
emit done(true);
return;
}
read_directory(&ipod);
if(ipod.nimages <= 0) {
emit logItem(tr("Failed to read firmware directory"), LOGERROR);
emit done(true);
return;
}
if(getmodel(&ipod,(ipod.ipod_directory[0].vers>>8)) < 0) {
emit logItem(tr("Unknown version number in firmware (%1)").arg(
ipod.ipod_directory[0].vers), LOGERROR);
emit done(true);
return;
}
if(ipod.macpod) {
emit logItem(tr("Warning: This is a MacPod, Rockbox only runs on WinPods.\n"
"See http://www.rockbox.org/wiki/IpodConversionToFAT32"), LOGERROR);
emit done(true);
return;
}
if(ipod_reopen_rw(&ipod) < 0) {
emit logItem(tr("Could not open Ipod in R/W mode"), LOGERROR);
emit done(true);
return;
}
m_tempfile.open();
QString blfile = m_tempfile.fileName();
m_tempfile.close();
if(add_bootloader(&ipod, blfile.toLatin1().data(), FILETYPE_DOT_IPOD) == 0) {
emit logItem(tr("Successfull added bootloader"), LOGOK);
logInstall(LogAdd);
emit done(false);
ipod_close(&ipod);
return;
}
else {
emit logItem(tr("Failed to add bootloader"), LOGERROR);
ipod_close(&ipod);
emit done(true);
return;
}
qDebug() << "version installed:" << m_blversion.toString(Qt::ISODate);
}
bool BootloaderInstallIpod::uninstall(void)
{
struct ipod_t ipod;
emit logItem(tr("Uninstalling bootloader"), LOGINFO);
QCoreApplication::processEvents();
if(!ipodInitialize(&ipod)) {
emit done(true);
return false;
}
read_directory(&ipod);
if (ipod.nimages <= 0) {
emit logItem(tr("Failed to read firmware directory"),LOGERROR);
emit done(true);
return false;
}
if (getmodel(&ipod,(ipod.ipod_directory[0].vers>>8)) < 0) {
emit logItem(tr("Unknown version number in firmware (%1)").arg(
ipod.ipod_directory[0].vers), LOGERROR);
emit done(true);
return false;
}
if (ipod_reopen_rw(&ipod) < 0) {
emit logItem(tr("Could not open Ipod in R/W mode"), LOGERROR);
emit done(true);
return false;
}
if (ipod.ipod_directory[0].entryOffset == 0) {
emit logItem(tr("No bootloader detected."), LOGERROR);
emit done(true);
return false;
}
if (delete_bootloader(&ipod)==0) {
emit logItem(tr("Successfully removed bootloader"), LOGOK);
logInstall(LogRemove);
emit done(false);
ipod_close(&ipod);
return true;
}
else {
emit logItem(tr("Removing bootloader failed."), LOGERROR);
emit done(true);
ipod_close(&ipod);
return false;
}
}
BootloaderInstallBase::BootloaderType BootloaderInstallIpod::installed(void)
{
struct ipod_t ipod;
BootloaderInstallBase::BootloaderType result = BootloaderRockbox;
if(!ipodInitialize(&ipod)) {
qDebug() << "BootloaderInstallIpod::installed(): BootloaderUnknown";
result = BootloaderUnknown;
}
else {
read_directory(&ipod);
if(ipod.ipod_directory[0].entryOffset == 0) {
qDebug() << "BootloaderInstallIpod::installed(): BootloaderOther";
result = BootloaderOther;
}
else {
qDebug() << "BootloaderInstallIpod::installed(): BootloaderRockbox";
}
}
ipod_close(&ipod);
return result;
}
BootloaderInstallBase::Capabilities BootloaderInstallIpod::capabilities(void)
{
return (Install | Uninstall | IsRaw);
}
bool BootloaderInstallIpod::ipodInitialize(struct ipod_t *ipod)
{
if(!m_blfile.isEmpty()) {
#if defined(Q_OS_WIN32)
sprintf(ipod->diskname, "\\\\.\\PhysicalDrive%i",
Autodetection::resolveDevicename(m_blfile).toInt());
#elif defined(Q_OS_MACX)
sprintf(ipod->diskname,
qPrintable(Autodetection::resolveDevicename(m_blfile)
.remove(QRegExp("s[0-9]+$"))));
#else
sprintf(ipod->diskname,
qPrintable(Autodetection::resolveDevicename(m_blfile)
.remove(QRegExp("[0-9]+$"))));
#endif
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("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;
}