mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-08 20:55:17 -05:00
Separate basic functionality from GUI parts by moving it into a separate folder. Some files still need to get cleaned up prior moving them too.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18788 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
3d30029883
commit
f958717d43
23 changed files with 36 additions and 34 deletions
391
rbutil/rbutilqt/base/autodetection.cpp
Normal file
391
rbutil/rbutilqt/base/autodetection.cpp
Normal file
|
|
@ -0,0 +1,391 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
*
|
||||
* Copyright (C) 2007 by Dominik Wenger
|
||||
* $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 "autodetection.h"
|
||||
|
||||
#if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
|
||||
#include <stdio.h>
|
||||
#include <usb.h>
|
||||
#endif
|
||||
#if defined(Q_OS_LINUX)
|
||||
#include <mntent.h>
|
||||
#endif
|
||||
#if defined(Q_OS_MACX)
|
||||
#include <sys/param.h>
|
||||
#include <sys/ucred.h>
|
||||
#include <sys/mount.h>
|
||||
#endif
|
||||
#if defined(Q_OS_WIN32)
|
||||
#if defined(UNICODE)
|
||||
#define _UNICODE
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
#include <windows.h>
|
||||
#include <setupapi.h>
|
||||
#include <winioctl.h>
|
||||
#endif
|
||||
#include "detect.h"
|
||||
#include "utils.h"
|
||||
|
||||
Autodetection::Autodetection(QObject* parent): QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool Autodetection::detect()
|
||||
{
|
||||
m_device = "";
|
||||
m_mountpoint = "";
|
||||
m_errdev = "";
|
||||
|
||||
detectUsb();
|
||||
|
||||
// Try detection via rockbox.info / rbutil.log
|
||||
QStringList mountpoints = getMountpoints();
|
||||
|
||||
for(int i=0; i< mountpoints.size();i++)
|
||||
{
|
||||
// do the file checking
|
||||
QDir dir(mountpoints.at(i));
|
||||
qDebug() << "paths to check for player specific files:" << mountpoints;
|
||||
if(dir.exists())
|
||||
{
|
||||
// check logfile first.
|
||||
if(QFile(mountpoints.at(i) + "/.rockbox/rbutil.log").exists()) {
|
||||
QSettings log(mountpoints.at(i) + "/.rockbox/rbutil.log",
|
||||
QSettings::IniFormat, this);
|
||||
if(!log.value("platform").toString().isEmpty()) {
|
||||
if(m_device.isEmpty())
|
||||
m_device = log.value("platform").toString();
|
||||
m_mountpoint = mountpoints.at(i);
|
||||
qDebug() << "rbutil.log detected:" << m_device << m_mountpoint;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// check rockbox-info.txt afterwards.
|
||||
QFile file(mountpoints.at(i) + "/.rockbox/rockbox-info.txt");
|
||||
if(file.exists())
|
||||
{
|
||||
file.open(QIODevice::ReadOnly | QIODevice::Text);
|
||||
QString line = file.readLine();
|
||||
if(line.startsWith("Target: "))
|
||||
{
|
||||
line.remove("Target: ");
|
||||
if(m_device.isEmpty())
|
||||
m_device = line.trimmed(); // trim whitespaces
|
||||
m_mountpoint = mountpoints.at(i);
|
||||
qDebug() << "rockbox-info.txt detected:" << m_device << m_mountpoint;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// check for some specific files in root folder
|
||||
QDir root(mountpoints.at(i));
|
||||
QStringList rootentries = root.entryList(QDir::Files);
|
||||
if(rootentries.contains("archos.mod", Qt::CaseInsensitive))
|
||||
{
|
||||
// archos.mod in root folder -> Archos Player
|
||||
m_device = "player";
|
||||
m_mountpoint = mountpoints.at(i);
|
||||
return true;
|
||||
}
|
||||
if(rootentries.contains("ONDIOST.BIN", Qt::CaseInsensitive))
|
||||
{
|
||||
// ONDIOST.BIN in root -> Ondio FM
|
||||
m_device = "ondiofm";
|
||||
m_mountpoint = mountpoints.at(i);
|
||||
return true;
|
||||
}
|
||||
if(rootentries.contains("ONDIOSP.BIN", Qt::CaseInsensitive))
|
||||
{
|
||||
// ONDIOSP.BIN in root -> Ondio SP
|
||||
m_device = "ondiosp";
|
||||
m_mountpoint = mountpoints.at(i);
|
||||
return true;
|
||||
}
|
||||
if(rootentries.contains("ajbrec.ajz", Qt::CaseInsensitive))
|
||||
{
|
||||
qDebug() << "ajbrec.ajz found. Trying detectAjbrec()";
|
||||
if(detectAjbrec(mountpoints.at(i))) {
|
||||
m_mountpoint = mountpoints.at(i);
|
||||
qDebug() << m_device;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// detection based on player specific folders
|
||||
QStringList rootfolders = root.entryList(QDir::Dirs
|
||||
| QDir::NoDotAndDotDot | QDir::Hidden | QDir::System);
|
||||
if(rootfolders.contains("GBSYSTEM", Qt::CaseInsensitive))
|
||||
{
|
||||
// GBSYSTEM folder -> Gigabeat
|
||||
m_device = "gigabeatf";
|
||||
m_mountpoint = mountpoints.at(i);
|
||||
return true;
|
||||
}
|
||||
#if defined(Q_OS_WIN32)
|
||||
// on windows, try to detect the drive letter of an Ipod
|
||||
if(rootfolders.contains("iPod_Control", Qt::CaseInsensitive))
|
||||
{
|
||||
// iPod_Control folder -> Ipod found
|
||||
// detecting of the Ipod type is done below using ipodpatcher
|
||||
m_mountpoint = mountpoints.at(i);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int n;
|
||||
// try ipodpatcher
|
||||
// initialize sector buffer. Needed.
|
||||
ipod_sectorbuf = NULL;
|
||||
ipod_alloc_buffer(&ipod_sectorbuf, BUFFER_SIZE);
|
||||
struct ipod_t ipod;
|
||||
n = ipod_scan(&ipod);
|
||||
if(n == 1) {
|
||||
qDebug() << "Ipod found:" << ipod.modelstr << "at" << ipod.diskname;
|
||||
m_device = ipod.targetname;
|
||||
m_mountpoint = resolveMountPoint(ipod.diskname);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
qDebug() << "ipodpatcher: no Ipod found." << n;
|
||||
}
|
||||
free(ipod_sectorbuf);
|
||||
ipod_sectorbuf = NULL;
|
||||
|
||||
// try sansapatcher
|
||||
// initialize sector buffer. Needed.
|
||||
sansa_sectorbuf = NULL;
|
||||
sansa_alloc_buffer(&sansa_sectorbuf, BUFFER_SIZE);
|
||||
struct sansa_t sansa;
|
||||
n = sansa_scan(&sansa);
|
||||
if(n == 1) {
|
||||
qDebug() << "Sansa found:" << sansa.targetname << "at" << sansa.diskname;
|
||||
m_device = QString("sansa%1").arg(sansa.targetname);
|
||||
m_mountpoint = resolveMountPoint(sansa.diskname);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
qDebug() << "sansapatcher: no Sansa found." << n;
|
||||
}
|
||||
free(sansa_sectorbuf);
|
||||
sansa_sectorbuf = NULL;
|
||||
|
||||
if(m_mountpoint.isEmpty() && m_device.isEmpty() && m_errdev.isEmpty() && m_incompat.isEmpty())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
QStringList Autodetection::getMountpoints()
|
||||
{
|
||||
QStringList tempList;
|
||||
#if defined(Q_OS_WIN32)
|
||||
QFileInfoList list = QDir::drives();
|
||||
for(int i=0; i<list.size();i++)
|
||||
{
|
||||
tempList << list.at(i).absolutePath();
|
||||
}
|
||||
|
||||
#elif defined(Q_OS_MACX)
|
||||
int num;
|
||||
struct statfs *mntinf;
|
||||
|
||||
num = getmntinfo(&mntinf, MNT_WAIT);
|
||||
while(num--) {
|
||||
tempList << QString(mntinf->f_mntonname);
|
||||
mntinf++;
|
||||
}
|
||||
#elif defined(Q_OS_LINUX)
|
||||
|
||||
FILE *mn = setmntent("/etc/mtab", "r");
|
||||
if(!mn)
|
||||
return QStringList("");
|
||||
|
||||
struct mntent *ent;
|
||||
while((ent = getmntent(mn)))
|
||||
tempList << QString(ent->mnt_dir);
|
||||
endmntent(mn);
|
||||
|
||||
#else
|
||||
#error Unknown Plattform
|
||||
#endif
|
||||
return tempList;
|
||||
}
|
||||
|
||||
QString Autodetection::resolveMountPoint(QString device)
|
||||
{
|
||||
qDebug() << "Autodetection::resolveMountPoint(QString)" << device;
|
||||
|
||||
#if defined(Q_OS_LINUX)
|
||||
FILE *mn = setmntent("/etc/mtab", "r");
|
||||
if(!mn)
|
||||
return QString("");
|
||||
|
||||
struct mntent *ent;
|
||||
while((ent = getmntent(mn))) {
|
||||
if(QString(ent->mnt_fsname).startsWith(device)
|
||||
&& QString(ent->mnt_type).contains("vfat", Qt::CaseInsensitive)) {
|
||||
endmntent(mn);
|
||||
return QString(ent->mnt_dir);
|
||||
}
|
||||
}
|
||||
endmntent(mn);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_MACX)
|
||||
int num;
|
||||
struct statfs *mntinf;
|
||||
|
||||
num = getmntinfo(&mntinf, MNT_WAIT);
|
||||
while(num--) {
|
||||
if(QString(mntinf->f_mntfromname).startsWith(device)
|
||||
&& QString(mntinf->f_fstypename).contains("vfat", Qt::CaseInsensitive))
|
||||
return QString(mntinf->f_mntonname);
|
||||
mntinf++;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_WIN32)
|
||||
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;
|
||||
|
||||
_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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
if(!result.isEmpty())
|
||||
return result + ":/";
|
||||
#endif
|
||||
return QString("");
|
||||
}
|
||||
|
||||
|
||||
/** @brief detect devices based on usb pid / vid.
|
||||
* @return true upon success, false otherwise.
|
||||
*/
|
||||
bool Autodetection::detectUsb()
|
||||
{
|
||||
// usbids holds the mapping in the form
|
||||
// ((VID<<16)|(PID)), targetname
|
||||
// the ini file needs to hold the IDs as hex values.
|
||||
QMap<int, QString> usbids = settings->usbIdMap();
|
||||
QMap<int, QString> usberror = settings->usbIdErrorMap();
|
||||
QMap<int, QString> usbincompat = settings->usbIdIncompatMap();
|
||||
|
||||
// usb pid detection
|
||||
QList<uint32_t> attached;
|
||||
attached = Detect::listUsbIds();
|
||||
|
||||
int i = attached.size();
|
||||
while(i--) {
|
||||
if(usbids.contains(attached.at(i))) {
|
||||
m_device = usbids.value(attached.at(i));
|
||||
qDebug() << "[USB] detected supported player" << m_device;
|
||||
return true;
|
||||
}
|
||||
if(usberror.contains(attached.at(i))) {
|
||||
m_errdev = usberror.value(attached.at(i));
|
||||
qDebug() << "[USB] detected problem with player" << m_errdev;
|
||||
return true;
|
||||
}
|
||||
if(usbincompat.contains(attached.at(i))) {
|
||||
m_incompat = usbincompat.value(attached.at(i));
|
||||
qDebug() << "[USB] detected incompatible player" << m_incompat;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Autodetection::detectAjbrec(QString root)
|
||||
{
|
||||
QFile f(root + "/ajbrec.ajz");
|
||||
char header[24];
|
||||
f.open(QIODevice::ReadOnly);
|
||||
if(!f.read(header, 24)) return false;
|
||||
|
||||
// check the header of the file.
|
||||
// recorder v1 had a 6 bytes sized header
|
||||
// recorder v2, FM, Ondio SP and FM have a 24 bytes header.
|
||||
|
||||
// recorder v1 has the binary length in the first 4 bytes, so check
|
||||
// for them first.
|
||||
int len = (header[0]<<24) | (header[1]<<16) | (header[2]<<8) | header[3];
|
||||
qDebug() << "possible bin length:" << len;
|
||||
qDebug() << "file len:" << f.size();
|
||||
if((f.size() - 6) == len)
|
||||
m_device = "recorder";
|
||||
|
||||
// size didn't match, now we need to assume we have a headerlength of 24.
|
||||
switch(header[11]) {
|
||||
case 2:
|
||||
m_device = "recorderv2";
|
||||
break;
|
||||
|
||||
case 4:
|
||||
m_device = "fmrecorder";
|
||||
break;
|
||||
|
||||
case 8:
|
||||
m_device = "ondiofm";
|
||||
break;
|
||||
|
||||
case 16:
|
||||
m_device = "ondiosp";
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
f.close();
|
||||
|
||||
if(m_device.isEmpty()) return false;
|
||||
return true;
|
||||
}
|
||||
63
rbutil/rbutilqt/base/autodetection.h
Normal file
63
rbutil/rbutilqt/base/autodetection.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
*
|
||||
* Copyright (C) 2007 by Dominik Wenger
|
||||
* $Id$
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#ifndef AUTODETECTION_H_
|
||||
#define AUTODETECTION_H_
|
||||
|
||||
#include <QtCore>
|
||||
#include "rbsettings.h"
|
||||
|
||||
#include "../ipodpatcher/ipodpatcher.h"
|
||||
#include "../sansapatcher/sansapatcher.h"
|
||||
|
||||
class Autodetection :public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Autodetection(QObject* parent=0);
|
||||
|
||||
void setSettings(RbSettings* sett) {settings = sett;}
|
||||
|
||||
bool detect();
|
||||
|
||||
QString getDevice() {return m_device;}
|
||||
QString getMountPoint() {return m_mountpoint;}
|
||||
QString errdev(void) { return m_errdev; }
|
||||
QString incompatdev(void) { return m_incompat; }
|
||||
|
||||
private:
|
||||
QStringList getMountpoints(void);
|
||||
QString resolveMountPoint(QString);
|
||||
bool detectUsb(void);
|
||||
bool detectAjbrec(QString);
|
||||
|
||||
QString m_device;
|
||||
QString m_mountpoint;
|
||||
QString m_errdev;
|
||||
QString m_incompat;
|
||||
QList<int> m_usbconid;
|
||||
RbSettings* settings;
|
||||
};
|
||||
|
||||
|
||||
#endif /*AUTODETECTION_H_*/
|
||||
184
rbutil/rbutilqt/base/bootloaderinstallbase.cpp
Normal file
184
rbutil/rbutilqt/base/bootloaderinstallbase.cpp
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* 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 "utils.h"
|
||||
|
||||
BootloaderInstallBase::BootloaderType BootloaderInstallBase::installed(void)
|
||||
{
|
||||
return BootloaderUnknown;
|
||||
}
|
||||
|
||||
|
||||
BootloaderInstallBase::Capabilities BootloaderInstallBase::capabilities(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void BootloaderInstallBase::downloadBlStart(QUrl source)
|
||||
{
|
||||
m_http.setFile(&m_tempfile);
|
||||
m_http.setCache(true);
|
||||
connect(&m_http, SIGNAL(done(bool)), this, SLOT(downloadBlFinish(bool)));
|
||||
// connect the http read signal to our logProgess *signal*
|
||||
// to immediately emit it without any helper function.
|
||||
connect(&m_http, SIGNAL(dataReadProgress(int, int)),
|
||||
this, SIGNAL(logProgress(int, int)));
|
||||
m_http.getFile(source);
|
||||
}
|
||||
|
||||
|
||||
void BootloaderInstallBase::downloadReqFinished(int id, bool error)
|
||||
{
|
||||
qDebug() << __FILE__ << "::" << __func__ << id << error;
|
||||
qDebug() << "error:" << m_http.errorString();
|
||||
|
||||
downloadBlFinish(error);
|
||||
}
|
||||
|
||||
|
||||
void BootloaderInstallBase::downloadBlFinish(bool error)
|
||||
{
|
||||
qDebug() << __FILE__ << "::" << __func__ << ": error =" << error;
|
||||
|
||||
// update progress bar
|
||||
emit logProgress(100, 100);
|
||||
|
||||
if(m_http.httpResponse() != 200) {
|
||||
emit logItem(tr("Download error: received HTTP error %1.")
|
||||
.arg(m_http.errorString()), LOGERROR);
|
||||
emit done(true);
|
||||
return;
|
||||
}
|
||||
if(error) {
|
||||
emit logItem(tr("Download error: %1")
|
||||
.arg(m_http.error()), LOGERROR);
|
||||
emit done(true);
|
||||
return;
|
||||
}
|
||||
else if(m_http.isCached())
|
||||
emit logItem(tr("Download finished (cache used)."), LOGOK);
|
||||
else
|
||||
emit logItem(tr("Download finished."), LOGOK);
|
||||
|
||||
m_blversion = m_http.timestamp();
|
||||
emit downloadDone();
|
||||
}
|
||||
|
||||
void BootloaderInstallBase::installBlfile(void)
|
||||
{
|
||||
qDebug() << __FILE__ << __func__;
|
||||
}
|
||||
|
||||
|
||||
//! @brief backup OF file.
|
||||
//! @param to folder to write backup file to. Folder will get created.
|
||||
//! @return true on success, false on error.
|
||||
|
||||
bool BootloaderInstallBase::backup(QString to)
|
||||
{
|
||||
qDebug() << __func__;
|
||||
QDir targetDir(".");
|
||||
emit logItem(tr("Creating backup of original firmware file."), LOGINFO);
|
||||
if(!targetDir.mkpath(to)) {
|
||||
emit logItem(tr("Creating backup folder failed"), LOGERROR);
|
||||
return false;
|
||||
}
|
||||
QString tofile = to + "/" + QFileInfo(m_blfile).fileName();
|
||||
qDebug() << "trying to backup" << m_blfile << "to" << tofile;
|
||||
if(!QFile::copy(resolvePathCase(m_blfile), tofile)) {
|
||||
emit logItem(tr("Creating backup copy failed."), LOGERROR);
|
||||
return false;
|
||||
}
|
||||
emit logItem(tr("Backup created."), LOGOK);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//! @brief log installation to logfile.
|
||||
//! @param mode action to perform. 0: add to log, 1: remove from log.
|
||||
//! @return 0 on success
|
||||
int BootloaderInstallBase::logInstall(LogMode mode)
|
||||
{
|
||||
int result = 0;
|
||||
QString section = m_blurl.path().section('/', -1);
|
||||
QSettings s(m_logfile, QSettings::IniFormat, this);
|
||||
emit logItem(tr("Creating installation log"), LOGINFO);
|
||||
|
||||
if(mode == LogAdd) {
|
||||
s.setValue("Bootloader/" + section, m_blversion.toString(Qt::ISODate));
|
||||
qDebug() << m_blversion.toString(Qt::ISODate);
|
||||
}
|
||||
else {
|
||||
s.remove("Bootloader/" + section);
|
||||
}
|
||||
s.sync();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//! @brief Return post install hints string.
|
||||
//! @param model model string
|
||||
//! @return hints.
|
||||
QString BootloaderInstallBase::postinstallHints(QString model)
|
||||
{
|
||||
bool hint = false;
|
||||
QString msg = tr("Bootloader installation is almost complete. "
|
||||
"Installation <b>requires</b> you to perform the "
|
||||
"following steps manually:");
|
||||
|
||||
msg += tr("<ol>");
|
||||
msg += tr("<li>Safely remove your player.</li>");
|
||||
if(model == "h100" || model == "h120" || model == "h300") {
|
||||
hint = true;
|
||||
msg += tr("<li>Reboot your player into the original firmware.</li>"
|
||||
"<li>Perform a firmware upgrade using the update functionality "
|
||||
"of the original firmware. Please refer to your player's manual "
|
||||
"on details.</li>"
|
||||
"<li>After the firmware has been updated reboot your player.</li>");
|
||||
}
|
||||
if(model == "iaudiox5" || model == "iaudiom5"
|
||||
|| model == "iaudiox5v" || model == "iaudiom3") {
|
||||
hint = true;
|
||||
msg += tr("<li>Turn the player off</li>"
|
||||
"<li>Insert the charger</li>");
|
||||
}
|
||||
if(model == "gigabeatf") {
|
||||
hint = true;
|
||||
msg += tr("<li>Unplug USB and power adaptors</li>"
|
||||
"<li>Hold <i>Power</i> to turn the player off</li>"
|
||||
"<li>Toggle the battery switch on the player</li>"
|
||||
"<li>Hold <i>Power</i> to boot into Rockbox</li>");
|
||||
}
|
||||
|
||||
msg += "</ol>";
|
||||
msg += tr("<p><b>Note:</b> You can safely install other parts first, but "
|
||||
"the above steps are <b>required</b> to finish the installation!</p>");
|
||||
|
||||
if(hint)
|
||||
return msg;
|
||||
else
|
||||
return QString("");
|
||||
}
|
||||
|
||||
90
rbutil/rbutilqt/base/bootloaderinstallbase.h
Normal file
90
rbutil/rbutilqt/base/bootloaderinstallbase.h
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef BOOTLOADERINSTALLBASE_H
|
||||
#define BOOTLOADERINSTALLBASE_H
|
||||
|
||||
#include <QtCore>
|
||||
#include "progressloggerinterface.h"
|
||||
#include "httpget.h"
|
||||
|
||||
|
||||
class BootloaderInstallBase : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Capability
|
||||
{ Install = 0x01, Uninstall = 0x02, Backup = 0x04,
|
||||
IsFile = 0x08, IsRaw = 0x10, NeedsFlashing = 0x20,
|
||||
CanCheckInstalled = 0x40, CanCheckVersion = 0x80 };
|
||||
Q_DECLARE_FLAGS(Capabilities, Capability)
|
||||
|
||||
enum BootloaderType
|
||||
{ BootloaderNone, BootloaderRockbox, BootloaderOther, BootloaderUnknown };
|
||||
|
||||
BootloaderInstallBase(QObject *parent = 0) : QObject(parent)
|
||||
{ }
|
||||
|
||||
virtual bool install(void)
|
||||
{ return false; }
|
||||
virtual bool uninstall(void)
|
||||
{ return false; }
|
||||
virtual BootloaderType installed(void);
|
||||
virtual Capabilities capabilities(void);
|
||||
bool backup(QString to);
|
||||
|
||||
void setBlFile(QString f)
|
||||
{ m_blfile = f; }
|
||||
void setBlUrl(QUrl u)
|
||||
{ m_blurl = u; }
|
||||
void setLogfile(QString f)
|
||||
{ m_logfile = f; }
|
||||
|
||||
static QString postinstallHints(QString model);
|
||||
|
||||
protected slots:
|
||||
void downloadReqFinished(int id, bool error);
|
||||
void downloadBlFinish(bool error);
|
||||
void installBlfile(void);
|
||||
protected:
|
||||
enum LogMode
|
||||
{ LogAdd, LogRemove };
|
||||
|
||||
void downloadBlStart(QUrl source);
|
||||
int logInstall(LogMode mode);
|
||||
|
||||
HttpGet m_http; //! http download object
|
||||
QString m_blfile; //! bootloader filename on player
|
||||
QString m_logfile; //! file for installation log
|
||||
QUrl m_blurl; //! bootloader download URL
|
||||
QTemporaryFile m_tempfile; //! temporary file for download
|
||||
QDateTime m_blversion; //! download timestamp used for version information
|
||||
|
||||
signals:
|
||||
void downloadDone(void); //! internal signal sent when download finished.
|
||||
void done(bool);
|
||||
void logItem(QString, int); //! set logger item
|
||||
void logProgress(int, int); //! set progress bar.
|
||||
};
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(BootloaderInstallBase::Capabilities)
|
||||
|
||||
#endif
|
||||
|
||||
145
rbutil/rbutilqt/base/bootloaderinstallfile.cpp
Normal file
145
rbutil/rbutilqt/base/bootloaderinstallfile.cpp
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* 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 <QtDebug>
|
||||
#include <QtDebug>
|
||||
#include "bootloaderinstallfile.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
BootloaderInstallFile::BootloaderInstallFile(QObject *parent)
|
||||
: BootloaderInstallBase(parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool BootloaderInstallFile::install(void)
|
||||
{
|
||||
emit logItem(tr("Downloading bootloader"), LOGINFO);
|
||||
qDebug() << __func__;
|
||||
downloadBlStart(m_blurl);
|
||||
connect(this, SIGNAL(downloadDone()), this, SLOT(installStage2()));
|
||||
return true;
|
||||
}
|
||||
|
||||
void BootloaderInstallFile::installStage2(void)
|
||||
{
|
||||
emit logItem(tr("Installing Rockbox bootloader"), LOGINFO);
|
||||
|
||||
// if an old bootloader is present (Gigabeat) move it out of the way.
|
||||
QString fwfile(resolvePathCase(m_blfile));
|
||||
if(!fwfile.isEmpty()) {
|
||||
QString moved = resolvePathCase(m_blfile) + ".ORIG";
|
||||
qDebug() << "renaming" << fwfile << "->" << moved;
|
||||
QFile::rename(fwfile, moved);
|
||||
}
|
||||
|
||||
// if no old file found resolve path without basename
|
||||
QFileInfo fi(m_blfile);
|
||||
QString absPath = resolvePathCase(fi.absolutePath());
|
||||
|
||||
// if it's not possible to locate the base path try to create it
|
||||
if(absPath.isEmpty()) {
|
||||
QStringList pathElements = m_blfile.split("/");
|
||||
// remove filename from list and save last path element
|
||||
pathElements.removeLast();
|
||||
QString lastElement = pathElements.last();
|
||||
// remove last path element for base
|
||||
pathElements.removeLast();
|
||||
QString basePath = pathElements.join("/");
|
||||
|
||||
// check for base and bail out if not found. Otherwise create folder.
|
||||
absPath = resolvePathCase(basePath);
|
||||
QDir d(absPath);
|
||||
d.mkpath(lastElement);
|
||||
absPath = resolvePathCase(fi.absolutePath());
|
||||
|
||||
if(absPath.isEmpty()) {
|
||||
emit logItem(tr("Error accessing output folder"), LOGERROR);
|
||||
emit done(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
fwfile = absPath + "/" + fi.fileName();
|
||||
|
||||
// place (new) bootloader
|
||||
m_tempfile.open();
|
||||
qDebug() << "renaming" << m_tempfile.fileName() << "->" << fwfile;
|
||||
m_tempfile.close();
|
||||
m_tempfile.rename(fwfile);
|
||||
|
||||
emit logItem(tr("Bootloader successful installed"), LOGOK);
|
||||
logInstall(LogAdd);
|
||||
|
||||
emit done(false);
|
||||
}
|
||||
|
||||
|
||||
bool BootloaderInstallFile::uninstall(void)
|
||||
{
|
||||
qDebug() << __func__;
|
||||
emit logItem(tr("Removing Rockbox bootloader"), LOGINFO);
|
||||
// check if a .ORIG file is present, and allow moving it back.
|
||||
QString origbl = resolvePathCase(m_blfile + ".ORIG");
|
||||
if(origbl.isEmpty()) {
|
||||
emit logItem(tr("No original firmware file found."), LOGERROR);
|
||||
emit done(true);
|
||||
return false;
|
||||
}
|
||||
QString fwfile = resolvePathCase(m_blfile);
|
||||
if(!QFile::remove(fwfile)) {
|
||||
emit logItem(tr("Can't remove Rockbox bootloader file."), LOGERROR);
|
||||
emit done(true);
|
||||
return false;
|
||||
}
|
||||
if(!QFile::rename(origbl, fwfile)) {
|
||||
emit logItem(tr("Can't restore bootloader file."), LOGERROR);
|
||||
emit done(true);
|
||||
return false;
|
||||
}
|
||||
emit logItem(tr("Original bootloader restored successfully."), LOGOK);
|
||||
logInstall(LogRemove);
|
||||
emit done(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//! @brief check if bootloader is installed.
|
||||
//! @return BootloaderRockbox, BootloaderOther or BootloaderUnknown.
|
||||
BootloaderInstallBase::BootloaderType BootloaderInstallFile::installed(void)
|
||||
{
|
||||
qDebug("%s()", __func__);
|
||||
if(!resolvePathCase(m_blfile).isEmpty()
|
||||
&& !resolvePathCase(m_blfile + ".ORIG").isEmpty())
|
||||
return BootloaderRockbox;
|
||||
else if(!resolvePathCase(m_blfile).isEmpty())
|
||||
return BootloaderOther;
|
||||
else
|
||||
return BootloaderUnknown;
|
||||
}
|
||||
|
||||
|
||||
BootloaderInstallBase::Capabilities BootloaderInstallFile::capabilities(void)
|
||||
{
|
||||
qDebug() << __func__;
|
||||
return Install | IsFile | CanCheckInstalled | Backup;
|
||||
}
|
||||
|
||||
44
rbutil/rbutilqt/base/bootloaderinstallfile.h
Normal file
44
rbutil/rbutilqt/base/bootloaderinstallfile.h
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* 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 "progressloggerinterface.h"
|
||||
#include "bootloaderinstallbase.h"
|
||||
|
||||
//! install a bootloader by putting a single file on the player.
|
||||
// This installation method is used by Iaudio (firmware is flashed
|
||||
// automatically) and Gigabeat (Firmware is a file, OF needs to get
|
||||
// renamed).
|
||||
class BootloaderInstallFile : public BootloaderInstallBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BootloaderInstallFile(QObject *parent = 0);
|
||||
bool install(void);
|
||||
bool uninstall(void);
|
||||
BootloaderInstallBase::BootloaderType installed(void);
|
||||
Capabilities capabilities(void);
|
||||
|
||||
private slots:
|
||||
void installStage2(void);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
244
rbutil/rbutilqt/base/bootloaderinstallhex.cpp
Normal file
244
rbutil/rbutilqt/base/bootloaderinstallhex.cpp
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* 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 "bootloaderinstallhex.h"
|
||||
|
||||
#include "../../tools/iriver.h"
|
||||
#include "../../tools/mkboot.h"
|
||||
|
||||
struct md5s {
|
||||
const char* orig;
|
||||
const char* patched;
|
||||
};
|
||||
|
||||
struct md5s md5sums[] = {
|
||||
#include "irivertools/h100sums.h"
|
||||
{ 0, 0 },
|
||||
#include "irivertools/h120sums.h"
|
||||
{ 0, 0 },
|
||||
#include "irivertools/h300sums.h"
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
BootloaderInstallHex::BootloaderInstallHex(QObject *parent)
|
||||
: BootloaderInstallBase(parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool BootloaderInstallHex::install(void)
|
||||
{
|
||||
if(m_hex.isEmpty())
|
||||
return false;
|
||||
m_hashindex = -1;
|
||||
|
||||
// md5sum hex file
|
||||
emit logItem(tr("checking MD5 hash of input file ..."), LOGINFO);
|
||||
QByteArray filedata;
|
||||
// read hex file into QByteArray
|
||||
QFile file(m_hex);
|
||||
file.open(QIODevice::ReadOnly);
|
||||
filedata = file.readAll();
|
||||
file.close();
|
||||
QString hash = QCryptographicHash::hash(filedata,
|
||||
QCryptographicHash::Md5).toHex();
|
||||
qDebug() << "hexfile hash:" << hash;
|
||||
if(file.error() != QFile::NoError) {
|
||||
emit logItem(tr("Could not verify original firmware file"), LOGERROR);
|
||||
emit done(true);
|
||||
return false;
|
||||
}
|
||||
// check hash and figure model from md5sum
|
||||
int i = sizeof(md5sums) / sizeof(struct md5s);
|
||||
m_model = 4;
|
||||
// 3: h300, 2: h120, 1: h100, 0:invalid
|
||||
while(i--) {
|
||||
if(md5sums[i].orig == 0)
|
||||
m_model--;
|
||||
if(!qstrcmp(md5sums[i].orig, hash.toAscii()))
|
||||
break;
|
||||
}
|
||||
if(i < 0) {
|
||||
emit logItem(tr("Firmware file not recognized."), LOGERROR);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
emit logItem(tr("MD5 hash ok"), LOGOK);
|
||||
m_hashindex = i;
|
||||
}
|
||||
|
||||
// check model agains download link.
|
||||
QString match[] = {"", "h100", "h120", "h300"};
|
||||
if(!m_blurl.path().contains(match[m_model])) {
|
||||
emit logItem(tr("Firmware file doesn't match selected player."),
|
||||
LOGERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
emit logItem(tr("Descrambling file"), LOGINFO);
|
||||
m_descrambled.open();
|
||||
int result;
|
||||
result = iriver_decode(m_hex.toAscii().data(),
|
||||
m_descrambled.fileName().toAscii().data(), FALSE, STRIP_NONE);
|
||||
qDebug() << "iriver_decode" << result;
|
||||
|
||||
if(result < 0) {
|
||||
emit logItem(tr("Error in descramble: %1").arg(scrambleError(result)), LOGERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
// download firmware from server
|
||||
emit logItem(tr("Downloading bootloader file"), LOGINFO);
|
||||
connect(this, SIGNAL(downloadDone()), this, SLOT(installStage2()));
|
||||
|
||||
downloadBlStart(m_blurl);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void BootloaderInstallHex::installStage2(void)
|
||||
{
|
||||
emit logItem(tr("Adding bootloader to firmware file"), LOGINFO);
|
||||
|
||||
// local temp file
|
||||
QTemporaryFile tempbin;
|
||||
tempbin.open();
|
||||
QString tempbinName = tempbin.fileName();
|
||||
tempbin.close();
|
||||
// get temporary files filenames -- external tools need this.
|
||||
m_descrambled.open();
|
||||
QString descrambledName = m_descrambled.fileName();
|
||||
m_descrambled.close();
|
||||
m_tempfile.open();
|
||||
QString tempfileName = m_tempfile.fileName();
|
||||
m_tempfile.close();
|
||||
|
||||
int origin = 0;
|
||||
switch(m_model) {
|
||||
case 3:
|
||||
origin = 0x3f0000;
|
||||
break;
|
||||
case 2:
|
||||
case 1:
|
||||
origin = 0x1f0000;
|
||||
break;
|
||||
default:
|
||||
origin = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// iriver decode already done in stage 1
|
||||
int result;
|
||||
if((result = mkboot(descrambledName.toLocal8Bit().constData(),
|
||||
tempfileName.toLocal8Bit().constData(),
|
||||
tempbinName.toLocal8Bit().constData(), origin)) < 0)
|
||||
{
|
||||
QString error;
|
||||
switch(result) {
|
||||
case -1: error = tr("could not open input file"); break;
|
||||
case -2: error = tr("reading header failed"); break;
|
||||
case -3: error = tr("reading firmware failed"); break;
|
||||
case -4: error = tr("can't open bootloader file"); break;
|
||||
case -5: error = tr("reading bootloader file failed"); break;
|
||||
case -6: error = tr("can't open output file"); break;
|
||||
case -7: error = tr("writing output file failed"); break;
|
||||
}
|
||||
emit logItem(tr("Error in patching: %1").arg(error), LOGERROR);
|
||||
|
||||
emit done(true);
|
||||
return;
|
||||
}
|
||||
QTemporaryFile targethex;
|
||||
targethex.open();
|
||||
QString targethexName = targethex.fileName();
|
||||
if((result = iriver_encode(tempbinName.toLocal8Bit().constData(),
|
||||
targethexName.toLocal8Bit().constData(), FALSE)) < 0)
|
||||
{
|
||||
emit logItem(tr("Error in scramble: %1").arg(scrambleError(result)), LOGERROR);
|
||||
targethex.close();
|
||||
|
||||
emit done(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// finally check the md5sum of the created file
|
||||
QByteArray filedata;
|
||||
filedata = targethex.readAll();
|
||||
targethex.close();
|
||||
QString hash = QCryptographicHash::hash(filedata,
|
||||
QCryptographicHash::Md5).toHex();
|
||||
qDebug() << "created hexfile hash:" << hash;
|
||||
|
||||
emit logItem(tr("Checking modified firmware file"), LOGINFO);
|
||||
if(hash != QString(md5sums[m_hashindex].patched)) {
|
||||
emit logItem(tr("Error: modified file checksum wrong"), LOGERROR);
|
||||
targethex.remove();
|
||||
emit done(true);
|
||||
return;
|
||||
}
|
||||
// finally copy file to player
|
||||
targethex.copy(m_blfile);
|
||||
|
||||
emit logItem(tr("Success: modified firmware file created"), LOGINFO);
|
||||
logInstall(LogAdd);
|
||||
emit done(false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
bool BootloaderInstallHex::uninstall(void)
|
||||
{
|
||||
emit logItem("Uninstallation not possible, only installation info removed", LOGINFO);
|
||||
logInstall(LogRemove);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
BootloaderInstallBase::BootloaderType BootloaderInstallHex::installed(void)
|
||||
{
|
||||
return BootloaderUnknown;
|
||||
}
|
||||
|
||||
|
||||
BootloaderInstallBase::Capabilities BootloaderInstallHex::capabilities(void)
|
||||
{
|
||||
return (Install | NeedsFlashing);
|
||||
}
|
||||
|
||||
QString BootloaderInstallHex::scrambleError(int err)
|
||||
{
|
||||
QString error;
|
||||
switch(err) {
|
||||
case -1: error = tr("Can't open input file"); break;
|
||||
case -2: error = tr("Can't open output file"); break;
|
||||
case -3: error = tr("invalid file: header length wrong"); break;
|
||||
case -4: error = tr("invalid file: unrecognized header"); break;
|
||||
case -5: error = tr("invalid file: \"length\" field wrong"); break;
|
||||
case -6: error = tr("invalid file: \"length2\" field wrong"); break;
|
||||
case -7: error = tr("invalid file: internal checksum error"); break;
|
||||
case -8: error = tr("invalid file: \"length3\" field wrong"); break;
|
||||
default: error = tr("unknown"); break;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
57
rbutil/rbutilqt/base/bootloaderinstallhex.h
Normal file
57
rbutil/rbutilqt/base/bootloaderinstallhex.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef BOOTLOADERINSTALLHEX_H
|
||||
#define BOOTLOADERINSTALLHEX_H
|
||||
|
||||
#include <QtCore>
|
||||
#include "bootloaderinstallbase.h"
|
||||
|
||||
|
||||
// bootloader installation derivate based on fwpatcher
|
||||
// This will patch a given hex file using (de)scramble / mkboot
|
||||
// and put it on the player.
|
||||
class BootloaderInstallHex : public BootloaderInstallBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BootloaderInstallHex(QObject *parent = 0);
|
||||
bool install(void);
|
||||
bool uninstall(void);
|
||||
BootloaderInstallBase::BootloaderType installed(void);
|
||||
Capabilities capabilities(void);
|
||||
|
||||
void setHexfile(QString h)
|
||||
{ m_hex = h; }
|
||||
|
||||
private:
|
||||
QString m_hex;
|
||||
int m_hashindex;
|
||||
int m_model;
|
||||
QTemporaryFile m_descrambled;
|
||||
QString scrambleError(int);
|
||||
|
||||
private slots:
|
||||
void installStage2(void);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
235
rbutil/rbutilqt/base/bootloaderinstallipod.cpp
Normal file
235
rbutil/rbutilqt/base/bootloaderinstallipod.cpp
Normal file
|
|
@ -0,0 +1,235 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* 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"
|
||||
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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 RW 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 the 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;
|
||||
}
|
||||
|
||||
50
rbutil/rbutilqt/base/bootloaderinstallipod.h
Normal file
50
rbutil/rbutilqt/base/bootloaderinstallipod.h
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef BOOTLOADERINSTALLIPOD_H
|
||||
#define BOOTLOADERINSTALLIPOD_H
|
||||
|
||||
#include <QtCore>
|
||||
#include "bootloaderinstallbase.h"
|
||||
#include "../ipodpatcher/ipodpatcher.h"
|
||||
|
||||
// installer class derivate for Ipod installation
|
||||
// based on ipodpatcher.
|
||||
class BootloaderInstallIpod : public BootloaderInstallBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BootloaderInstallIpod(QObject *parent = 0);
|
||||
~BootloaderInstallIpod();
|
||||
bool install(void);
|
||||
bool uninstall(void);
|
||||
BootloaderInstallBase::BootloaderType installed(void);
|
||||
Capabilities capabilities(void);
|
||||
|
||||
private slots:
|
||||
void installStage2(void);
|
||||
|
||||
private:
|
||||
bool ipodInitialize(struct ipod_t *);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
140
rbutil/rbutilqt/base/bootloaderinstallmi4.cpp
Normal file
140
rbutil/rbutilqt/base/bootloaderinstallmi4.cpp
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* 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 <QtDebug>
|
||||
#include <QtDebug>
|
||||
#include "bootloaderinstallmi4.h"
|
||||
#include "utils.h"
|
||||
|
||||
BootloaderInstallMi4::BootloaderInstallMi4(QObject *parent)
|
||||
: BootloaderInstallBase(parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool BootloaderInstallMi4::install(void)
|
||||
{
|
||||
emit logItem(tr("Downloading bootloader"), LOGINFO);
|
||||
qDebug() << __func__;
|
||||
downloadBlStart(m_blurl);
|
||||
connect(this, SIGNAL(downloadDone()), this, SLOT(installStage2()));
|
||||
return true;
|
||||
}
|
||||
|
||||
void BootloaderInstallMi4::installStage2(void)
|
||||
{
|
||||
emit logItem(tr("Installing Rockbox bootloader"), LOGINFO);
|
||||
|
||||
// move old bootloader out of the way
|
||||
QString fwfile(resolvePathCase(m_blfile));
|
||||
QFile oldbl(fwfile);
|
||||
QString moved = QFileInfo(resolvePathCase(m_blfile)).absolutePath()
|
||||
+ "/OF.mi4";
|
||||
qDebug() << "renaming" << fwfile << "->" << moved;
|
||||
oldbl.rename(moved);
|
||||
|
||||
// place new bootloader
|
||||
m_tempfile.open();
|
||||
qDebug() << "renaming" << m_tempfile.fileName() << "->" << fwfile;
|
||||
m_tempfile.close();
|
||||
m_tempfile.rename(fwfile);
|
||||
|
||||
emit logItem(tr("Bootloader successful installed"), LOGOK);
|
||||
logInstall(LogAdd);
|
||||
|
||||
emit done(true);
|
||||
}
|
||||
|
||||
|
||||
bool BootloaderInstallMi4::uninstall(void)
|
||||
{
|
||||
qDebug() << __func__;
|
||||
|
||||
// check if it's actually a Rockbox bootloader
|
||||
emit logItem(tr("Checking for Rockbox bootloader"), LOGINFO);
|
||||
if(installed() != BootloaderRockbox) {
|
||||
emit logItem(tr("No Rockbox bootloader found"), LOGERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if OF file present
|
||||
emit logItem(tr("Checking for original firmware file"), LOGINFO);
|
||||
QString original = QFileInfo(resolvePathCase(m_blfile)).absolutePath()
|
||||
+ "/OF.mi4";
|
||||
|
||||
if(resolvePathCase(original).isEmpty()) {
|
||||
emit logItem(tr("Error finding original firmware file"), LOGERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
// finally remove RB bootloader
|
||||
QString resolved = resolvePathCase(m_blfile);
|
||||
QFile blfile(resolved);
|
||||
blfile.remove();
|
||||
|
||||
QFile oldbl(resolvePathCase(original));
|
||||
oldbl.rename(m_blfile);
|
||||
emit logItem(tr("Rockbox bootloader successful removed"), LOGINFO);
|
||||
logInstall(LogRemove);
|
||||
emit done(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//! check if a bootloader is installed and return its state.
|
||||
BootloaderInstallBase::BootloaderType BootloaderInstallMi4::installed(void)
|
||||
{
|
||||
// for MI4 files we can check if we actually have a RB bootloader
|
||||
// installed.
|
||||
// RB bootloader has "RBBL" at 0x1f8 in the mi4 file.
|
||||
|
||||
// make sure to resolve case to prevent case issues
|
||||
QString resolved;
|
||||
resolved = resolvePathCase(m_blfile);
|
||||
if(resolved.isEmpty()) {
|
||||
qDebug("%s: BootloaderNone", __func__);
|
||||
return BootloaderNone;
|
||||
}
|
||||
|
||||
QFile f(resolved);
|
||||
f.open(QIODevice::ReadOnly);
|
||||
f.seek(0x1f8);
|
||||
char magic[4];
|
||||
f.read(magic, 4);
|
||||
f.close();
|
||||
|
||||
if(!memcmp(magic, "RBBL", 4)) {
|
||||
qDebug("%s: BootloaderRockbox", __func__);
|
||||
return BootloaderRockbox;
|
||||
}
|
||||
else {
|
||||
qDebug("%s: BootloaderOther", __func__);
|
||||
return BootloaderOther;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BootloaderInstallBase::Capabilities BootloaderInstallMi4::capabilities(void)
|
||||
{
|
||||
qDebug() << __func__;
|
||||
return Install | Uninstall | Backup | IsFile | CanCheckInstalled | CanCheckVersion;
|
||||
}
|
||||
|
||||
44
rbutil/rbutilqt/base/bootloaderinstallmi4.h
Normal file
44
rbutil/rbutilqt/base/bootloaderinstallmi4.h
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* 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 "progressloggerinterface.h"
|
||||
#include "bootloaderinstallbase.h"
|
||||
|
||||
|
||||
// mi4 bootloader file based installation.
|
||||
// Puts the bootloader file to the correct location and
|
||||
// renames the OF to OF.mi4.
|
||||
class BootloaderInstallMi4 : public BootloaderInstallBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BootloaderInstallMi4(QObject *parent = 0);
|
||||
bool install(void);
|
||||
bool uninstall(void);
|
||||
BootloaderInstallBase::BootloaderType installed(void);
|
||||
Capabilities capabilities(void);
|
||||
|
||||
private slots:
|
||||
void installStage2(void);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
244
rbutil/rbutilqt/base/bootloaderinstallsansa.cpp
Normal file
244
rbutil/rbutilqt/base/bootloaderinstallsansa.cpp
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* 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 "bootloaderinstallsansa.h"
|
||||
|
||||
#include "../sansapatcher/sansapatcher.h"
|
||||
|
||||
BootloaderInstallSansa::BootloaderInstallSansa(QObject *parent)
|
||||
: BootloaderInstallBase(parent)
|
||||
{
|
||||
(void)parent;
|
||||
// initialize sector buffer. sansa_sectorbuf is instantiated by
|
||||
// sansapatcher.
|
||||
sansa_sectorbuf = NULL;
|
||||
sansa_alloc_buffer(&sansa_sectorbuf, BUFFER_SIZE);
|
||||
}
|
||||
|
||||
|
||||
BootloaderInstallSansa::~BootloaderInstallSansa()
|
||||
{
|
||||
free(sansa_sectorbuf);
|
||||
}
|
||||
|
||||
|
||||
/** Start bootloader installation.
|
||||
*/
|
||||
bool BootloaderInstallSansa::install(void)
|
||||
{
|
||||
if(sansa_sectorbuf == NULL) {
|
||||
emit logItem(tr("Error: can't allocate buffer memory!"), LOGERROR);
|
||||
return false;
|
||||
emit done(true);
|
||||
}
|
||||
|
||||
emit logItem(tr("Searching for Sansa"), LOGINFO);
|
||||
|
||||
struct sansa_t sansa;
|
||||
|
||||
int n = sansa_scan(&sansa);
|
||||
if(n == -1) {
|
||||
emit logItem(tr("Permission for disc access denied!\n"
|
||||
"This is required to install the bootloader"),
|
||||
LOGERROR);
|
||||
emit done(true);
|
||||
return false;
|
||||
}
|
||||
if(n == 0) {
|
||||
emit logItem(tr("No Sansa detected!"), 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;
|
||||
}
|
||||
|
||||
|
||||
/** Finish bootloader installation.
|
||||
*/
|
||||
void BootloaderInstallSansa::installStage2(void)
|
||||
{
|
||||
struct sansa_t sansa;
|
||||
sansa_scan(&sansa);
|
||||
|
||||
if(sansa_open(&sansa, 0) < 0) {
|
||||
emit logItem(tr("could not open Sansa"), LOGERROR);
|
||||
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"
|
||||
"sansapatcher for the first time.\n"
|
||||
"See http://www.rockbox.org/wiki/SansaE200Install\n"),
|
||||
LOGERROR);
|
||||
emit done(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if(sansa_reopen_rw(&sansa) < 0) {
|
||||
emit logItem(tr("Could not open Sansa in R/W mode"), LOGERROR);
|
||||
emit done(true);
|
||||
return;
|
||||
}
|
||||
|
||||
m_tempfile.open();
|
||||
QString blfile = m_tempfile.fileName();
|
||||
m_tempfile.close();
|
||||
if(sansa_add_bootloader(&sansa, blfile.toLatin1().data(),
|
||||
FILETYPE_MI4) == 0) {
|
||||
emit logItem(tr("Successfully installed bootloader"), LOGOK);
|
||||
logInstall(LogAdd);
|
||||
emit done(false);
|
||||
sansa_close(&sansa);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
emit logItem(tr("Failed to install bootloader"), LOGERROR);
|
||||
sansa_close(&sansa);
|
||||
emit done(true);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/** Uninstall the bootloader.
|
||||
*/
|
||||
bool BootloaderInstallSansa::uninstall(void)
|
||||
{
|
||||
struct sansa_t sansa;
|
||||
|
||||
if(sansa_scan(&sansa) != 1) {
|
||||
emit logItem(tr("Can't find Sansa"), LOGERROR);
|
||||
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"
|
||||
"sansapatcher for the first time.\n"
|
||||
"See http://www.rockbox.org/wiki/SansaE200Install\n"),
|
||||
LOGERROR);
|
||||
emit done(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sansa_reopen_rw(&sansa) < 0) {
|
||||
emit logItem(tr("Could not open Sansa in R/W mode"), LOGERROR);
|
||||
emit done(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sansa_delete_bootloader(&sansa)==0) {
|
||||
emit logItem(tr("Successfully removed bootloader"), LOGOK);
|
||||
logInstall(LogRemove);
|
||||
emit done(false);
|
||||
sansa_close(&sansa);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
emit logItem(tr("Removing bootloader failed."),LOGERROR);
|
||||
emit done(true);
|
||||
sansa_close(&sansa);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/** Check if bootloader is already installed
|
||||
*/
|
||||
BootloaderInstallBase::BootloaderType BootloaderInstallSansa::installed(void)
|
||||
{
|
||||
struct sansa_t sansa;
|
||||
int num;
|
||||
|
||||
if(sansa_scan(&sansa) != 1) {
|
||||
return BootloaderUnknown;
|
||||
}
|
||||
if (sansa_open(&sansa, 0) < 0) {
|
||||
return BootloaderUnknown;
|
||||
}
|
||||
if (sansa_read_partinfo(&sansa,0) < 0) {
|
||||
return BootloaderUnknown;
|
||||
}
|
||||
if(is_sansa(&sansa) < 0) {
|
||||
return BootloaderUnknown;
|
||||
}
|
||||
if((num = sansa_list_images(&sansa)) == 2) {
|
||||
return BootloaderRockbox;
|
||||
}
|
||||
else if(num == 1) {
|
||||
return BootloaderOther;
|
||||
}
|
||||
return BootloaderUnknown;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/** Get capabilities of subclass installer.
|
||||
*/
|
||||
BootloaderInstallBase::Capabilities BootloaderInstallSansa::capabilities(void)
|
||||
{
|
||||
return (Install | Uninstall | IsRaw | CanCheckInstalled);
|
||||
}
|
||||
|
||||
48
rbutil/rbutilqt/base/bootloaderinstallsansa.h
Normal file
48
rbutil/rbutilqt/base/bootloaderinstallsansa.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef BOOTLOADERINSTALLSANSA_H
|
||||
#define BOOTLOADERINSTALLSANSA_H
|
||||
|
||||
#include <QtCore>
|
||||
#include "bootloaderinstallbase.h"
|
||||
|
||||
|
||||
// bootloader installation class for devices handled by sansapatcher.
|
||||
class BootloaderInstallSansa : public BootloaderInstallBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BootloaderInstallSansa(QObject *parent = 0);
|
||||
~BootloaderInstallSansa();
|
||||
bool install(void);
|
||||
bool uninstall(void);
|
||||
BootloaderInstallBase::BootloaderType installed(void);
|
||||
Capabilities capabilities(void);
|
||||
|
||||
private:
|
||||
|
||||
private slots:
|
||||
void installStage2(void);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
413
rbutil/rbutilqt/base/httpget.cpp
Normal file
413
rbutil/rbutilqt/base/httpget.cpp
Normal file
|
|
@ -0,0 +1,413 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
*
|
||||
* Copyright (C) 2007 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 <QtNetwork>
|
||||
#include <QtDebug>
|
||||
|
||||
#include "httpget.h"
|
||||
|
||||
QDir HttpGet::m_globalCache; //< global cach path value for new objects
|
||||
QUrl HttpGet::m_globalProxy; //< global proxy value for new objects
|
||||
bool HttpGet::m_globalDumbCache = false; //< globally set cache "dumb" mode
|
||||
QString HttpGet::m_globalUserAgent; //< globally set user agent for requests
|
||||
|
||||
HttpGet::HttpGet(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
outputToBuffer = true;
|
||||
m_cached = false;
|
||||
m_dumbCache = m_globalDumbCache;
|
||||
getRequest = -1;
|
||||
headRequest = -1;
|
||||
// if a request is cancelled before a reponse is available return some
|
||||
// hint about this in the http response instead of nonsense.
|
||||
m_response = -1;
|
||||
|
||||
// default to global proxy / cache if not empty.
|
||||
// proxy is automatically enabled, disable it by setting an empty proxy
|
||||
// cache is enabled to be in line, can get disabled with setCache(bool)
|
||||
if(!m_globalProxy.isEmpty())
|
||||
setProxy(m_globalProxy);
|
||||
m_usecache = false;
|
||||
m_cachedir = m_globalCache;
|
||||
|
||||
m_serverTimestamp = QDateTime();
|
||||
|
||||
connect(&http, SIGNAL(done(bool)), this, SLOT(httpDone(bool)));
|
||||
connect(&http, SIGNAL(dataReadProgress(int, int)), this, SIGNAL(dataReadProgress(int, int)));
|
||||
connect(&http, SIGNAL(requestFinished(int, bool)), this, SLOT(httpFinished(int, bool)));
|
||||
connect(&http, SIGNAL(responseHeaderReceived(const QHttpResponseHeader&)), this, SLOT(httpResponseHeader(const QHttpResponseHeader&)));
|
||||
connect(&http, SIGNAL(stateChanged(int)), this, SLOT(httpState(int)));
|
||||
connect(&http, SIGNAL(requestStarted(int)), this, SLOT(httpStarted(int)));
|
||||
|
||||
connect(&http, SIGNAL(readyRead(const QHttpResponseHeader&)), this, SLOT(httpResponseHeader(const QHttpResponseHeader&)));
|
||||
|
||||
}
|
||||
|
||||
|
||||
//! @brief set cache path
|
||||
// @param d new directory to use as cache path
|
||||
void HttpGet::setCache(QDir d)
|
||||
{
|
||||
m_cachedir = d;
|
||||
bool result;
|
||||
result = initializeCache(d);
|
||||
qDebug() << "[HTTP]"<< __func__ << "(QDir)" << d.absolutePath() << result;
|
||||
m_usecache = result;
|
||||
}
|
||||
|
||||
|
||||
/** @brief enable / disable cache useage
|
||||
* @param c set cache usage
|
||||
*/
|
||||
void HttpGet::setCache(bool c)
|
||||
{
|
||||
qDebug() << "[HTTP]" << __func__ << "(bool) =" << c;
|
||||
m_usecache = c;
|
||||
// make sure cache is initialized
|
||||
if(c)
|
||||
m_usecache = initializeCache(m_cachedir);
|
||||
}
|
||||
|
||||
|
||||
bool HttpGet::initializeCache(const QDir& d)
|
||||
{
|
||||
bool result;
|
||||
QString p = d.absolutePath() + "/rbutil-cache";
|
||||
if(QFileInfo(d.absolutePath()).isDir())
|
||||
{
|
||||
if(!QFileInfo(p).isDir())
|
||||
result = d.mkdir("rbutil-cache");
|
||||
else
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
result = false;
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/** @brief read all downloaded data into a buffer
|
||||
* @return data
|
||||
*/
|
||||
QByteArray HttpGet::readAll()
|
||||
{
|
||||
return dataBuffer;
|
||||
}
|
||||
|
||||
|
||||
/** @brief get http error
|
||||
* @return http error
|
||||
*/
|
||||
QHttp::Error HttpGet::error()
|
||||
{
|
||||
return http.error();
|
||||
}
|
||||
|
||||
|
||||
void HttpGet::setProxy(const QUrl &proxy)
|
||||
{
|
||||
qDebug() << "[HTTP]" << __func__ << "(QUrl)" << proxy.toString();
|
||||
m_proxy = proxy;
|
||||
http.setProxy(m_proxy.host(), m_proxy.port(), m_proxy.userName(), m_proxy.password());
|
||||
}
|
||||
|
||||
|
||||
void HttpGet::setProxy(bool enable)
|
||||
{
|
||||
qDebug() << "[HTTP]" << __func__ << "(bool)" << enable;
|
||||
if(enable)
|
||||
http.setProxy(m_proxy.host(), m_proxy.port(), m_proxy.userName(), m_proxy.password());
|
||||
else
|
||||
http.setProxy("", 0);
|
||||
}
|
||||
|
||||
|
||||
void HttpGet::setFile(QFile *file)
|
||||
{
|
||||
outputFile = file;
|
||||
outputToBuffer = false;
|
||||
qDebug() << "[HTTP]" << __func__ << "(QFile*)" << outputFile->fileName();
|
||||
}
|
||||
|
||||
|
||||
void HttpGet::abort()
|
||||
{
|
||||
http.abort();
|
||||
if(!outputToBuffer)
|
||||
outputFile->close();
|
||||
}
|
||||
|
||||
|
||||
bool HttpGet::getFile(const QUrl &url)
|
||||
{
|
||||
if (!url.isValid()) {
|
||||
qDebug() << "[HTTP] Error: Invalid URL" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (url.scheme() != "http") {
|
||||
qDebug() << "[HTTP] Error: URL must start with 'http:'" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (url.path().isEmpty()) {
|
||||
qDebug() << "[HTTP] Error: URL has no path" << endl;
|
||||
return false;
|
||||
}
|
||||
m_serverTimestamp = QDateTime();
|
||||
// if no output file was set write to buffer
|
||||
if(!outputToBuffer) {
|
||||
if (!outputFile->open(QIODevice::ReadWrite)) {
|
||||
qDebug() << "[HTTP] Error: Cannot open " << qPrintable(outputFile->fileName())
|
||||
<< " for writing: " << qPrintable(outputFile->errorString())
|
||||
<< endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
qDebug() << "[HTTP] downloading" << url.toEncoded();
|
||||
// create request
|
||||
http.setHost(url.host(), url.port(80));
|
||||
// construct query (if any)
|
||||
QList<QPair<QString, QString> > qitems = url.queryItems();
|
||||
if(url.hasQuery()) {
|
||||
m_query = "?";
|
||||
for(int i = 0; i < qitems.size(); i++)
|
||||
m_query += QUrl::toPercentEncoding(qitems.at(i).first, "/") + "="
|
||||
+ QUrl::toPercentEncoding(qitems.at(i).second, "/") + "&";
|
||||
}
|
||||
|
||||
// create hash used for caching
|
||||
m_hash = QCryptographicHash::hash(url.toEncoded(), QCryptographicHash::Md5).toHex();
|
||||
m_path = QString(QUrl::toPercentEncoding(url.path(), "/"));
|
||||
|
||||
// construct request header
|
||||
m_header.setValue("Host", url.host());
|
||||
m_header.setValue("User-Agent", m_globalUserAgent);
|
||||
m_header.setValue("Connection", "Keep-Alive");
|
||||
|
||||
if(m_dumbCache || !m_usecache) {
|
||||
getFileFinish();
|
||||
}
|
||||
else {
|
||||
// schedule HTTP header request
|
||||
connect(this, SIGNAL(headerFinished()), this, SLOT(getFileFinish()));
|
||||
m_header.setRequest("HEAD", m_path + m_query);
|
||||
headRequest = http.request(m_header);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void HttpGet::getFileFinish()
|
||||
{
|
||||
m_cachefile = m_cachedir.absolutePath() + "/rbutil-cache/" + m_hash;
|
||||
if(m_usecache) {
|
||||
// check if the file is present in cache
|
||||
qDebug() << "[HTTP] cache ENABLED";
|
||||
QFileInfo cachefile = QFileInfo(m_cachefile);
|
||||
if(cachefile.isReadable()
|
||||
&& cachefile.size() > 0
|
||||
&& cachefile.lastModified() > m_serverTimestamp) {
|
||||
|
||||
qDebug() << "[HTTP] cached file found:" << m_cachefile;
|
||||
|
||||
getRequest = -1;
|
||||
QFile c(m_cachefile);
|
||||
if(!outputToBuffer) {
|
||||
qDebug() << "[HTTP] copying cache file to output" << outputFile->fileName();
|
||||
c.open(QIODevice::ReadOnly);
|
||||
outputFile->open(QIODevice::ReadWrite);
|
||||
outputFile->write(c.readAll());
|
||||
outputFile->close();
|
||||
c.close();
|
||||
}
|
||||
else {
|
||||
qDebug() << "[HTTP] reading cache file into buffer";
|
||||
c.open(QIODevice::ReadOnly);
|
||||
dataBuffer = c.readAll();
|
||||
c.close();
|
||||
}
|
||||
m_response = 200; // fake "200 OK" HTTP response
|
||||
m_cached = true;
|
||||
httpDone(false); // we're done now. Fake http "done" signal.
|
||||
return;
|
||||
}
|
||||
else {
|
||||
if(cachefile.isReadable())
|
||||
qDebug() << "[HTTP] file in cache timestamp:" << cachefile.lastModified();
|
||||
else
|
||||
qDebug() << "[HTTP] file not in cache.";
|
||||
qDebug() << "[HTTP] server file timestamp:" << m_serverTimestamp;
|
||||
qDebug() << "[HTTP] downloading file to" << m_cachefile;
|
||||
// unlink old cache file
|
||||
if(cachefile.isReadable())
|
||||
QFile(m_cachefile).remove();
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
qDebug() << "[HTTP] cache DISABLED";
|
||||
}
|
||||
// schedule GET request
|
||||
m_header.setRequest("GET", m_path + m_query);
|
||||
if(outputToBuffer) {
|
||||
qDebug() << "[HTTP] downloading to buffer.";
|
||||
getRequest = http.request(m_header);
|
||||
}
|
||||
else {
|
||||
qDebug() << "[HTTP] downloading to file:"
|
||||
<< qPrintable(outputFile->fileName());
|
||||
getRequest = http.request(m_header, 0, outputFile);
|
||||
}
|
||||
qDebug() << "[HTTP] GET request scheduled, id:" << getRequest;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void HttpGet::httpDone(bool error)
|
||||
{
|
||||
if (error) {
|
||||
qDebug() << "[HTTP] Error: " << qPrintable(http.errorString()) << httpResponse();
|
||||
}
|
||||
if(!outputToBuffer)
|
||||
outputFile->close();
|
||||
|
||||
if(m_usecache && !m_cached && !error) {
|
||||
qDebug() << "[HTTP] creating cache file" << m_cachefile;
|
||||
QFile c(m_cachefile);
|
||||
c.open(QIODevice::ReadWrite);
|
||||
if(!outputToBuffer) {
|
||||
outputFile->open(QIODevice::ReadOnly | QIODevice::Truncate);
|
||||
c.write(outputFile->readAll());
|
||||
outputFile->close();
|
||||
}
|
||||
else
|
||||
c.write(dataBuffer);
|
||||
|
||||
c.close();
|
||||
}
|
||||
// if cached file found and cache enabled ignore http errors
|
||||
if(m_usecache && m_cached && !http.hasPendingRequests()) {
|
||||
error = false;
|
||||
}
|
||||
// take care of concurring requests. If there is still one running,
|
||||
// don't emit done(). That request will call this slot again.
|
||||
if(http.currentId() == 0 && !http.hasPendingRequests())
|
||||
emit done(error);
|
||||
}
|
||||
|
||||
|
||||
void HttpGet::httpFinished(int id, bool error)
|
||||
{
|
||||
qDebug() << "[HTTP]" << __func__ << "(int, bool) =" << id << error;
|
||||
if(id == getRequest) {
|
||||
dataBuffer = http.readAll();
|
||||
|
||||
emit requestFinished(id, error);
|
||||
}
|
||||
qDebug() << "[HTTP] hasPendingRequests =" << http.hasPendingRequests();
|
||||
|
||||
|
||||
if(id == headRequest) {
|
||||
QHttpResponseHeader h = http.lastResponse();
|
||||
|
||||
QString date = h.value("Last-Modified").simplified();
|
||||
if(date.isEmpty()) {
|
||||
m_serverTimestamp = QDateTime(); // no value = invalid
|
||||
emit headerFinished();
|
||||
return;
|
||||
}
|
||||
// to successfully parse the date strip weekday and timezone
|
||||
date.remove(0, date.indexOf(" ") + 1);
|
||||
if(date.endsWith("GMT"))
|
||||
date.truncate(date.indexOf(" GMT"));
|
||||
// distinguish input formats (see RFC1945)
|
||||
// RFC 850
|
||||
if(date.contains("-"))
|
||||
m_serverTimestamp = QDateTime::fromString(date, "dd-MMM-yy hh:mm:ss");
|
||||
// asctime format
|
||||
else if(date.at(0).isLetter())
|
||||
m_serverTimestamp = QDateTime::fromString(date, "MMM d hh:mm:ss yyyy");
|
||||
// RFC 822
|
||||
else
|
||||
m_serverTimestamp = QDateTime::fromString(date, "dd MMM yyyy hh:mm:ss");
|
||||
qDebug() << "[HTTP] Header Request Date:" << date << ", parsed:" << m_serverTimestamp;
|
||||
emit headerFinished();
|
||||
return;
|
||||
}
|
||||
if(id == getRequest)
|
||||
emit requestFinished(id, error);
|
||||
}
|
||||
|
||||
void HttpGet::httpStarted(int id)
|
||||
{
|
||||
qDebug() << "[HTTP]" << __func__ << "(int) =" << id;
|
||||
qDebug() << "headRequest" << headRequest << "getRequest" << getRequest;
|
||||
}
|
||||
|
||||
|
||||
QString HttpGet::errorString()
|
||||
{
|
||||
return http.errorString();
|
||||
}
|
||||
|
||||
|
||||
void HttpGet::httpResponseHeader(const QHttpResponseHeader &resp)
|
||||
{
|
||||
// if there is a network error abort all scheduled requests for
|
||||
// this download
|
||||
m_response = resp.statusCode();
|
||||
if(m_response != 200) {
|
||||
qDebug() << "[HTTP] response error =" << m_response << resp.reasonPhrase();
|
||||
http.abort();
|
||||
}
|
||||
// 301 -- moved permanently
|
||||
// 302 -- found
|
||||
// 303 -- see other
|
||||
// 307 -- moved temporarily
|
||||
// in all cases, header: location has the correct address so we can follow.
|
||||
if(m_response == 301 || m_response == 302 || m_response == 303 || m_response == 307) {
|
||||
// start new request with new url
|
||||
qDebug() << "[HTTP] response =" << m_response << "- following";
|
||||
getFile(resp.value("location") + m_query);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int HttpGet::httpResponse()
|
||||
{
|
||||
return m_response;
|
||||
}
|
||||
|
||||
|
||||
void HttpGet::httpState(int state)
|
||||
{
|
||||
QString s[] = {"Unconnected", "HostLookup", "Connecting", "Sending",
|
||||
"Reading", "Connected", "Closing"};
|
||||
if(state <= 6)
|
||||
qDebug() << "[HTTP]" << __func__ << "() = " << s[state];
|
||||
else qDebug() << "[HTTP]" << __func__ << "() = " << state;
|
||||
}
|
||||
|
||||
107
rbutil/rbutilqt/base/httpget.h
Normal file
107
rbutil/rbutilqt/base/httpget.h
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
*
|
||||
* Copyright (C) 2007 by Dominik Riebeling
|
||||
* $Id$
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#ifndef HTTPGET_H
|
||||
#define HTTPGET_H
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtNetwork>
|
||||
|
||||
class QUrl;
|
||||
|
||||
class HttpGet : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
HttpGet(QObject *parent = 0);
|
||||
|
||||
bool getFile(const QUrl &url);
|
||||
void setProxy(const QUrl &url);
|
||||
void setProxy(bool);
|
||||
QHttp::Error error(void);
|
||||
QString errorString(void);
|
||||
void setFile(QFile*);
|
||||
void setCache(QDir);
|
||||
void setCache(bool);
|
||||
int httpResponse(void);
|
||||
QByteArray readAll(void);
|
||||
bool isCached()
|
||||
{ return m_cached; }
|
||||
QDateTime timestamp(void)
|
||||
{ return m_serverTimestamp; }
|
||||
void setDumbCache(bool b) //< disable checking of http header timestamp for caching
|
||||
{ m_dumbCache = b; }
|
||||
static void setGlobalCache(const QDir d) //< set global cache path
|
||||
{ m_globalCache = d; }
|
||||
static void setGlobalProxy(const QUrl p) //< set global proxy value
|
||||
{ m_globalProxy = p; }
|
||||
static void setGlobalDumbCache(bool b) //< set "dumb" (ignore server status) caching mode
|
||||
{ m_globalDumbCache = b; }
|
||||
static void setGlobalUserAgent(QString u) //< set global user agent string
|
||||
{ m_globalUserAgent = u; }
|
||||
|
||||
public slots:
|
||||
void abort(void);
|
||||
|
||||
signals:
|
||||
void done(bool);
|
||||
void dataReadProgress(int, int);
|
||||
void requestFinished(int, bool);
|
||||
void headerFinished(void);
|
||||
|
||||
private slots:
|
||||
void httpDone(bool error);
|
||||
void httpFinished(int, bool);
|
||||
void httpResponseHeader(const QHttpResponseHeader&);
|
||||
void httpState(int);
|
||||
void httpStarted(int);
|
||||
void getFileFinish(void);
|
||||
|
||||
private:
|
||||
bool initializeCache(const QDir&);
|
||||
QHttp http; //< download object
|
||||
QFile *outputFile;
|
||||
int m_response; //< http response
|
||||
int getRequest; //! get file http request id
|
||||
int headRequest; //! get http header request id
|
||||
QByteArray dataBuffer;
|
||||
bool outputToBuffer;
|
||||
bool m_usecache;
|
||||
QDir m_cachedir;
|
||||
QString m_cachefile; // cached filename
|
||||
bool m_cached;
|
||||
QUrl m_proxy;
|
||||
QDateTime m_serverTimestamp; //< timestamp of file on server
|
||||
QString m_query; //< constructed query to pass http getter
|
||||
QString m_path; //< constructed path to pass http getter
|
||||
QString m_hash; //< caching hash
|
||||
bool m_dumbCache; //< true if caching should ignore the server header
|
||||
QHttpRequestHeader m_header;
|
||||
|
||||
static QDir m_globalCache; //< global cache path value
|
||||
static QUrl m_globalProxy; //< global proxy value
|
||||
static bool m_globalDumbCache; //< cache "dumb" mode global setting
|
||||
static QString m_globalUserAgent; //< global user agent string
|
||||
};
|
||||
|
||||
#endif
|
||||
48
rbutil/rbutilqt/base/rbunzip.cpp
Normal file
48
rbutil/rbutilqt/base/rbunzip.cpp
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* 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 "rbunzip.h"
|
||||
#include <QtCore>
|
||||
|
||||
|
||||
UnZip::ErrorCode RbUnZip::extractArchive(const QString& dest)
|
||||
{
|
||||
QStringList files = this->fileList();
|
||||
UnZip::ErrorCode error = Ok;
|
||||
m_abortunzip = false;
|
||||
|
||||
int total = files.size();
|
||||
for(int i = 0; i < total; i++) {
|
||||
qDebug() << __func__ << files.at(i);
|
||||
error = this->extractFile(files.at(i), dest, UnZip::ExtractPaths);
|
||||
emit unzipProgress(i + 1, total);
|
||||
QCoreApplication::processEvents(); // update UI
|
||||
if(m_abortunzip)
|
||||
error = SkipAll;
|
||||
if(error != Ok)
|
||||
break;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
void RbUnZip::abortUnzip(void)
|
||||
{
|
||||
m_abortunzip = true;
|
||||
}
|
||||
|
||||
46
rbutil/rbutilqt/base/rbunzip.h
Normal file
46
rbutil/rbutilqt/base/rbunzip.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
*
|
||||
* Copyright (C) 2008 by Dominik Riebeling
|
||||
* $Id$
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef RBUNZIP_H
|
||||
#define RBUNZIP_H
|
||||
|
||||
#include <QtCore>
|
||||
#include "zip/unzip.h"
|
||||
#include "zip/zip.h"
|
||||
|
||||
class RbUnZip : public QObject, public UnZip
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
UnZip::ErrorCode extractArchive(const QString&);
|
||||
|
||||
signals:
|
||||
void unzipProgress(int, int);
|
||||
|
||||
public slots:
|
||||
void abortUnzip(void);
|
||||
|
||||
private:
|
||||
bool m_abortunzip;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
65
rbutil/rbutilqt/base/rbzip.cpp
Normal file
65
rbutil/rbutilqt/base/rbzip.cpp
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
*
|
||||
* Copyright (C) 2008 by Dominik Wenger
|
||||
* $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 "rbzip.h"
|
||||
#include <QtCore>
|
||||
|
||||
|
||||
Zip::ErrorCode RbZip::createZip(QString zip,QString dir)
|
||||
{
|
||||
Zip::ErrorCode error = Ok;
|
||||
m_curEntry = 1;
|
||||
m_numEntrys=0;
|
||||
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
// get number of entrys in dir
|
||||
QDirIterator it(dir, QDirIterator::Subdirectories);
|
||||
while (it.hasNext())
|
||||
{
|
||||
it.next();
|
||||
m_numEntrys++;
|
||||
QCoreApplication::processEvents();
|
||||
}
|
||||
|
||||
|
||||
//! create zip
|
||||
error = Zip::createArchive(zip);
|
||||
if(error != Ok)
|
||||
return error;
|
||||
|
||||
//! add the content
|
||||
error = Zip::addDirectory(dir);
|
||||
if(error != Ok)
|
||||
return error;
|
||||
|
||||
//! close zip
|
||||
error = Zip::closeArchive();
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void RbZip::progress()
|
||||
{
|
||||
m_curEntry++;
|
||||
emit zipProgress(m_curEntry,m_numEntrys);
|
||||
QCoreApplication::processEvents(); // update UI
|
||||
}
|
||||
|
||||
|
||||
45
rbutil/rbutilqt/base/rbzip.h
Normal file
45
rbutil/rbutilqt/base/rbzip.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
*
|
||||
* Copyright (C) 2008 by Dominik Wenger
|
||||
* $Id$
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef RBZIP_H
|
||||
#define RBZIP_H
|
||||
|
||||
#include <QtCore>
|
||||
#include "zip/zip.h"
|
||||
|
||||
class RbZip : public QObject, public Zip
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Zip::ErrorCode createZip(QString zip,QString dir);
|
||||
|
||||
virtual void progress();
|
||||
|
||||
signals:
|
||||
void zipProgress(int, int);
|
||||
|
||||
private:
|
||||
int m_curEntry;
|
||||
int m_numEntrys;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
101
rbutil/rbutilqt/base/utils.cpp
Normal file
101
rbutil/rbutilqt/base/utils.cpp
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
*
|
||||
* Copyright (C) 2007 by Dominik Wenger
|
||||
* $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 "utils.h"
|
||||
#ifdef UNICODE
|
||||
#define _UNICODE
|
||||
#endif
|
||||
|
||||
#include <QtCore>
|
||||
#include <QDebug>
|
||||
#include <cstdlib>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(Q_OS_WIN32)
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
#include <winioctl.h>
|
||||
#endif
|
||||
|
||||
// recursive function to delete a dir with files
|
||||
bool recRmdir( const QString &dirName )
|
||||
{
|
||||
QString dirN = dirName;
|
||||
QDir dir(dirN);
|
||||
// make list of entries in directory
|
||||
QStringList list = dir.entryList(QDir::AllEntries | QDir::NoDotAndDotDot);
|
||||
QFileInfo fileInfo;
|
||||
QString curItem, lstAt;
|
||||
for(int i = 0; i < list.size(); i++){ // loop through all items of list
|
||||
QString name = list.at(i);
|
||||
curItem = dirN + "/" + name;
|
||||
fileInfo.setFile(curItem);
|
||||
if(fileInfo.isDir()) // is directory
|
||||
recRmdir(curItem); // call recRmdir() recursively for deleting subdirectory
|
||||
else // is file
|
||||
QFile::remove(curItem); // ok, delete file
|
||||
}
|
||||
dir.cdUp();
|
||||
return dir.rmdir(dirN); // delete empty dir and return if (now empty) dir-removing was successfull
|
||||
}
|
||||
|
||||
|
||||
//! @brief resolves the given path, ignoring case.
|
||||
//! @param path absolute path to resolve.
|
||||
//! @return returns exact casing of path, empty string if path not found.
|
||||
QString resolvePathCase(QString path)
|
||||
{
|
||||
QStringList elems;
|
||||
QString realpath;
|
||||
|
||||
elems = path.split("/", QString::SkipEmptyParts);
|
||||
int start;
|
||||
#if defined(Q_OS_WIN32)
|
||||
// on windows we must make sure to start with the first entry (i.e. the
|
||||
// drive letter) instead of a single / to make resolving work.
|
||||
start = 1;
|
||||
realpath = elems.at(0) + "/";
|
||||
#else
|
||||
start = 0;
|
||||
realpath = "/";
|
||||
#endif
|
||||
|
||||
for(int i = start; i < elems.size(); i++) {
|
||||
QStringList direlems
|
||||
= QDir(realpath).entryList(QDir::AllEntries|QDir::Hidden|QDir::System);
|
||||
if(direlems.contains(elems.at(i), Qt::CaseInsensitive)) {
|
||||
// need to filter using QRegExp as QStringList::filter(QString)
|
||||
// matches any substring
|
||||
QString expr = QString("^" + elems.at(i) + "$");
|
||||
QRegExp rx = QRegExp(expr, Qt::CaseInsensitive);
|
||||
QStringList a = direlems.filter(rx);
|
||||
|
||||
if(a.size() != 1)
|
||||
return QString("");
|
||||
if(!realpath.endsWith("/"))
|
||||
realpath += "/";
|
||||
realpath += a.at(0);
|
||||
}
|
||||
else
|
||||
return QString("");
|
||||
}
|
||||
qDebug() << __func__ << path << "->" << realpath;
|
||||
return realpath;
|
||||
}
|
||||
|
||||
33
rbutil/rbutilqt/base/utils.h
Normal file
33
rbutil/rbutilqt/base/utils.h
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
*
|
||||
* Copyright (C) 2007 by Dominik Wenger
|
||||
* $Id$
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
#include <QString>
|
||||
#include <QUrl>
|
||||
|
||||
bool recRmdir( const QString &dirName );
|
||||
QString resolvePathCase(QString path);
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue