/*************************************************************************** * __________ __ ___. * 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 #include "bootloaderinstallbase.h" #include "bootloaderinstallipod.h" #include "../ipodpatcher/ipodpatcher.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() { 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; } if (ipod.ipod_directory[0].entryOffset == 0) { qDebug() << "BootloaderInstallIpod::installed(): BootloaderOther"; result = BootloaderOther; } 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) { 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); return false; } if(ipod->pinfo[0].start == 0) { emit logItem(tr("No firmware partition on disk"), LOGERROR); return false; } return true; }