1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
9 * Copyright (C) 2008 by Dominik Riebeling
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
17 ****************************************************************************/
20 #include "bootloaderinstallbase.h"
21 #include "bootloaderinstallsansa.h"
23 #include "../sansapatcher/sansapatcher.h"
26 BootloaderInstallSansa::BootloaderInstallSansa(QObject
*parent
)
27 : BootloaderInstallBase(parent
)
30 // initialize sector buffer. The sector buffer is part of the sansa_t
31 // structure, so a second instance of this class will have its own buffer.
32 sansa_alloc_buffer(&sansa
, BUFFER_SIZE
);
36 BootloaderInstallSansa::~BootloaderInstallSansa()
39 sansa_dealloc_buffer(&sansa
);
44 /** Start bootloader installation.
46 bool BootloaderInstallSansa::install(void)
48 if(sansa
.sectorbuf
== NULL
) {
49 emit
logItem(tr("Error: can't allocate buffer memory!"), LOGERROR
);
54 emit
logItem(tr("Searching for Sansa"), LOGINFO
);
56 int n
= sansa_scan(&sansa
);
58 emit
logItem(tr("Permission for disc access denied!\n"
59 "This is required to install the bootloader"),
65 emit
logItem(tr("No Sansa detected!"), LOGERROR
);
69 if(sansa
.hasoldbootloader
) {
70 emit
logItem(tr("OLD ROCKBOX INSTALLATION DETECTED, ABORTING.\n"
71 "You must reinstall the original Sansa firmware before running\n"
72 "sansapatcher for the first time.\n"
73 "See http://www.rockbox.org/wiki/SansaE200Install\n"),
78 emit
logItem(tr("Downloading bootloader file"), LOGINFO
);
80 downloadBlStart(m_blurl
);
81 connect(this, SIGNAL(downloadDone()), this, SLOT(installStage2()));
86 /** Finish bootloader installation.
88 void BootloaderInstallSansa::installStage2(void)
90 unsigned char* buf
= NULL
;
93 emit
logItem(tr("Installing Rockbox bootloader"), LOGINFO
);
94 QCoreApplication::processEvents();
95 if(!sansaInitialize(&sansa
)) {
100 if(sansa_reopen_rw(&sansa
) < 0) {
101 emit
logItem(tr("Could not open Sansa in R/W mode"), LOGERROR
);
106 // check model -- if sansapatcher reports a c200 don't install an e200
107 // bootloader and vice versa.
108 // The model is available in the mi4 file at offset 0x1fc and matches
109 // the targetname set by sansapatcher.
110 emit
logItem(tr("Checking downloaded bootloader"), LOGINFO
);
112 QString blfile
= m_tempfile
.fileName();
114 m_tempfile
.seek(0x1fc);
115 m_tempfile
.read(magic
, 4);
117 if(memcmp(sansa
.targetname
, magic
, 4) != 0) {
118 emit
logItem(tr("Bootloader mismatch! Aborting."), LOGERROR
);
119 qDebug("[BootloaderInstallSansa] Targetname: %s, mi4 magic: %c%c%c%c",
120 sansa
.targetname
, magic
[0], magic
[1], magic
[2], magic
[3]);
126 len
= sansa_read_bootloader(&sansa
, blfile
.toLatin1().data(), &buf
);
127 if(sansa_add_bootloader(&sansa
, buf
, len
) == 0) {
128 emit
logItem(tr("Successfully installed bootloader"), LOGOK
);
130 #if defined(Q_OS_MACX)
131 m_remountDevice
= sansa
.diskname
;
132 connect(this, SIGNAL(remounted(bool)), this, SLOT(installStage3(bool)));
139 emit
logItem(tr("Failed to install bootloader"), LOGERROR
);
148 void BootloaderInstallSansa::installStage3(bool mounted
)
152 emit
logItem(tr("Bootloader Installation complete."), LOGINFO
);
157 emit
logItem(tr("Writing log aborted"), LOGERROR
);
160 qDebug() << "[BootloaderInstallSansa] version installed:" << m_blversion
.toString(Qt::ISODate
);
164 /** Uninstall the bootloader.
166 bool BootloaderInstallSansa::uninstall(void)
168 emit
logItem(tr("Uninstalling bootloader"), LOGINFO
);
169 QCoreApplication::processEvents();
171 if(!sansaInitialize(&sansa
)) {
176 if (sansa
.hasoldbootloader
) {
177 emit
logItem(tr("OLD ROCKBOX INSTALLATION DETECTED, ABORTING.\n"
178 "You must reinstall the original Sansa firmware before running\n"
179 "sansapatcher for the first time.\n"
180 "See http://www.rockbox.org/wiki/SansaE200Install\n"),
186 if (sansa_reopen_rw(&sansa
) < 0) {
187 emit
logItem(tr("Could not open Sansa in R/W mode"), LOGERROR
);
192 if (sansa_delete_bootloader(&sansa
)==0) {
193 emit
logItem(tr("Successfully removed bootloader"), LOGOK
);
194 logInstall(LogRemove
);
200 emit
logItem(tr("Removing bootloader failed."),LOGERROR
);
210 /** Check if bootloader is already installed
212 BootloaderInstallBase::BootloaderType
BootloaderInstallSansa::installed(void)
216 if(!sansaInitialize(&sansa
)) {
217 return BootloaderUnknown
;
219 if((num
= sansa_list_images(&sansa
)) == 2) {
221 return BootloaderRockbox
;
225 return BootloaderOther
;
227 return BootloaderUnknown
;
231 bool BootloaderInstallSansa::sansaInitialize(struct sansa_t
*sansa
)
233 if(!m_blfile
.isEmpty()) {
234 QString devicename
= Utils::resolveDevicename(m_blfile
);
235 if(devicename
.isEmpty()) {
236 emit
logItem(tr("Error: could not retrieve device name"), LOGERROR
);
239 #if defined(Q_OS_WIN32)
240 sprintf(sansa
->diskname
, "\\\\.\\PhysicalDrive%i", devicename
.toInt());
241 #elif defined(Q_OS_MACX)
242 sprintf(sansa
->diskname
,
243 qPrintable(devicename
.remove(QRegExp("s[0-9]+$"))));
245 sprintf(sansa
->diskname
,
246 qPrintable(devicename
.remove(QRegExp("[0-9]+$"))));
248 qDebug() << "[BootloaderInstallSansa] sansapatcher: overriding scan, using"
251 else if(sansa_scan(sansa
) != 1) {
252 emit
logItem(tr("Can't find Sansa"), LOGERROR
);
256 if (sansa_open(sansa
, 0) < 0) {
257 emit
logItem(tr("Could not open Sansa"), LOGERROR
);
261 if (sansa_read_partinfo(sansa
,0) < 0) {
262 emit
logItem(tr("Could not read partition table"), LOGERROR
);
267 int i
= is_sansa(sansa
);
269 emit
logItem(tr("Disk is not a Sansa (Error %1), aborting.").arg(i
), LOGERROR
);
277 /** Get capabilities of subclass installer.
279 BootloaderInstallBase::Capabilities
BootloaderInstallSansa::capabilities(void)
281 return (Install
| Uninstall
| IsRaw
| CanCheckInstalled
);