mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-14 02:27:39 -04:00
sansapatcher: move sectorbuf pointer into sansa_t structure.
Similar as the ipod_t structure for ipodpatcher the sansa_t structure holds all relevant information for sansapatcher. Put the global sansa_sectorbuf pointer into it as well. Change-Id: Iad08ef6aafc49609c3d0d556914246f230ee0179
This commit is contained in:
parent
24e37ddf57
commit
9c1ed84d28
9 changed files with 77 additions and 97 deletions
|
@ -167,9 +167,8 @@ bool Autodetection::detect()
|
||||||
|
|
||||||
// try sansapatcher
|
// try sansapatcher
|
||||||
// initialize sector buffer. Needed.
|
// initialize sector buffer. Needed.
|
||||||
sansa_sectorbuf = NULL;
|
|
||||||
sansa_alloc_buffer(&sansa_sectorbuf, BUFFER_SIZE);
|
|
||||||
struct sansa_t sansa;
|
struct sansa_t sansa;
|
||||||
|
sansa_alloc_buffer(&sansa, BUFFER_SIZE);
|
||||||
n = sansa_scan(&sansa);
|
n = sansa_scan(&sansa);
|
||||||
if(n == 1) {
|
if(n == 1) {
|
||||||
qDebug() << "[Autodetect] Sansa found:" << sansa.targetname << "at" << sansa.diskname;
|
qDebug() << "[Autodetect] Sansa found:" << sansa.targetname << "at" << sansa.diskname;
|
||||||
|
@ -187,8 +186,8 @@ bool Autodetection::detect()
|
||||||
else {
|
else {
|
||||||
qDebug() << "[Autodetect] sansapatcher: no Sansa found." << n;
|
qDebug() << "[Autodetect] sansapatcher: no Sansa found." << n;
|
||||||
}
|
}
|
||||||
free(sansa_sectorbuf);
|
free(sansa.sectorbuf);
|
||||||
sansa_sectorbuf = NULL;
|
sansa.sectorbuf = NULL;
|
||||||
|
|
||||||
if(m_mountpoint.isEmpty() && m_device.isEmpty()
|
if(m_mountpoint.isEmpty() && m_device.isEmpty()
|
||||||
&& m_errdev.isEmpty() && m_incompat.isEmpty())
|
&& m_errdev.isEmpty() && m_incompat.isEmpty())
|
||||||
|
|
|
@ -27,22 +27,17 @@ BootloaderInstallSansa::BootloaderInstallSansa(QObject *parent)
|
||||||
: BootloaderInstallBase(parent)
|
: BootloaderInstallBase(parent)
|
||||||
{
|
{
|
||||||
(void)parent;
|
(void)parent;
|
||||||
// initialize sector buffer. sansa_sectorbuf is instantiated by
|
// initialize sector buffer. The sector buffer is part of the sansa_t
|
||||||
// sansapatcher.
|
// structure, so a second instance of this class will have its own buffer.
|
||||||
// The buffer itself is only present once, so make sure to not allocate
|
sansa_alloc_buffer(&sansa, BUFFER_SIZE);
|
||||||
// it if it was already allocated. The application needs to take care
|
|
||||||
// no concurrent (i.e. multiple objects of this class running) requests
|
|
||||||
// are done.
|
|
||||||
if(sansa_sectorbuf == NULL)
|
|
||||||
sansa_alloc_buffer(&sansa_sectorbuf, BUFFER_SIZE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BootloaderInstallSansa::~BootloaderInstallSansa()
|
BootloaderInstallSansa::~BootloaderInstallSansa()
|
||||||
{
|
{
|
||||||
if(sansa_sectorbuf) {
|
if(sansa.sectorbuf) {
|
||||||
free(sansa_sectorbuf);
|
free(sansa.sectorbuf);
|
||||||
sansa_sectorbuf = NULL;
|
sansa.sectorbuf = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +46,7 @@ BootloaderInstallSansa::~BootloaderInstallSansa()
|
||||||
*/
|
*/
|
||||||
bool BootloaderInstallSansa::install(void)
|
bool BootloaderInstallSansa::install(void)
|
||||||
{
|
{
|
||||||
if(sansa_sectorbuf == NULL) {
|
if(sansa.sectorbuf == NULL) {
|
||||||
emit logItem(tr("Error: can't allocate buffer memory!"), LOGERROR);
|
emit logItem(tr("Error: can't allocate buffer memory!"), LOGERROR);
|
||||||
return false;
|
return false;
|
||||||
emit done(true);
|
emit done(true);
|
||||||
|
@ -59,8 +54,6 @@ bool BootloaderInstallSansa::install(void)
|
||||||
|
|
||||||
emit logItem(tr("Searching for Sansa"), LOGINFO);
|
emit logItem(tr("Searching for Sansa"), LOGINFO);
|
||||||
|
|
||||||
struct sansa_t sansa;
|
|
||||||
|
|
||||||
int n = sansa_scan(&sansa);
|
int n = sansa_scan(&sansa);
|
||||||
if(n == -1) {
|
if(n == -1) {
|
||||||
emit logItem(tr("Permission for disc access denied!\n"
|
emit logItem(tr("Permission for disc access denied!\n"
|
||||||
|
@ -95,7 +88,6 @@ bool BootloaderInstallSansa::install(void)
|
||||||
*/
|
*/
|
||||||
void BootloaderInstallSansa::installStage2(void)
|
void BootloaderInstallSansa::installStage2(void)
|
||||||
{
|
{
|
||||||
struct sansa_t sansa;
|
|
||||||
unsigned char* buf = NULL;
|
unsigned char* buf = NULL;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
|
|
||||||
|
@ -174,8 +166,6 @@ void BootloaderInstallSansa::installStage3(bool mounted)
|
||||||
*/
|
*/
|
||||||
bool BootloaderInstallSansa::uninstall(void)
|
bool BootloaderInstallSansa::uninstall(void)
|
||||||
{
|
{
|
||||||
struct sansa_t sansa;
|
|
||||||
|
|
||||||
emit logItem(tr("Uninstalling bootloader"), LOGINFO);
|
emit logItem(tr("Uninstalling bootloader"), LOGINFO);
|
||||||
QCoreApplication::processEvents();
|
QCoreApplication::processEvents();
|
||||||
|
|
||||||
|
@ -222,7 +212,6 @@ bool BootloaderInstallSansa::uninstall(void)
|
||||||
*/
|
*/
|
||||||
BootloaderInstallBase::BootloaderType BootloaderInstallSansa::installed(void)
|
BootloaderInstallBase::BootloaderType BootloaderInstallSansa::installed(void)
|
||||||
{
|
{
|
||||||
struct sansa_t sansa;
|
|
||||||
int num;
|
int num;
|
||||||
|
|
||||||
if(!sansaInitialize(&sansa)) {
|
if(!sansaInitialize(&sansa)) {
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
#include "bootloaderinstallbase.h"
|
#include "bootloaderinstallbase.h"
|
||||||
|
#include "sansapatcher.h"
|
||||||
|
|
||||||
|
|
||||||
// bootloader installation class for devices handled by sansapatcher.
|
// bootloader installation class for devices handled by sansapatcher.
|
||||||
|
@ -38,6 +39,7 @@ class BootloaderInstallSansa : public BootloaderInstallBase
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool sansaInitialize(struct sansa_t *);
|
bool sansaInitialize(struct sansa_t *);
|
||||||
|
struct sansa_t sansa;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void installStage2(void);
|
void installStage2(void);
|
||||||
|
|
|
@ -155,7 +155,7 @@ int main(int argc, char* argv[])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sansa_alloc_buffer(&sansa_sectorbuf,BUFFER_SIZE) < 0) {
|
if (sansa_alloc_buffer(&sansa, BUFFER_SIZE) < 0) {
|
||||||
fprintf(stderr,"Failed to allocate memory buffer\n");
|
fprintf(stderr,"Failed to allocate memory buffer\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,10 +113,10 @@ int sansa_close(struct sansa_t* sansa)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sansa_alloc_buffer(unsigned char** sectorbuf, int bufsize)
|
int sansa_alloc_buffer(struct sansa_t *sansa, int bufsize)
|
||||||
{
|
{
|
||||||
*sectorbuf=malloc(bufsize);
|
sansa->sectorbuf=malloc(bufsize);
|
||||||
if (*sectorbuf == NULL) {
|
if (sansa->sectorbuf == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -139,9 +139,9 @@ int sansa_read(struct sansa_t* sansa, unsigned char* buf, int nbytes)
|
||||||
return read(sansa->dh, buf, nbytes);
|
return read(sansa->dh, buf, nbytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
int sansa_write(struct sansa_t* sansa, unsigned char* buf, int nbytes)
|
int sansa_write(struct sansa_t* sansa, int nbytes)
|
||||||
{
|
{
|
||||||
return write(sansa->dh, buf, nbytes);
|
return write(sansa->dh, sansa->sectorbuf, nbytes);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -150,12 +150,12 @@ int sansa_close(struct sansa_t* sansa)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sansa_alloc_buffer(unsigned char** sectorbuf, int bufsize)
|
int sansa_alloc_buffer(struct sansa_t* sansa, int bufsize)
|
||||||
{
|
{
|
||||||
/* The ReadFile function requires a memory buffer aligned to a multiple of
|
/* The ReadFile function requires a memory buffer aligned to a multiple of
|
||||||
the disk sector size. */
|
the disk sector size. */
|
||||||
*sectorbuf = (unsigned char*)VirtualAlloc(NULL, bufsize, MEM_COMMIT, PAGE_READWRITE);
|
sansa->sectorbuf = (unsigned char*)VirtualAlloc(NULL, bufsize, MEM_COMMIT, PAGE_READWRITE);
|
||||||
if (*sectorbuf == NULL) {
|
if (sansa->sectorbuf == NULL) {
|
||||||
sansa_print_error(" Error allocating a buffer: ");
|
sansa_print_error(" Error allocating a buffer: ");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -189,11 +189,11 @@ int sansa_read(struct sansa_t* sansa, unsigned char* buf, int nbytes)
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sansa_write(struct sansa_t* sansa, unsigned char* buf, int nbytes)
|
int sansa_write(struct sansa_t* sansa, int nbytes)
|
||||||
{
|
{
|
||||||
unsigned long count;
|
unsigned long count;
|
||||||
|
|
||||||
if (!WriteFile(sansa->dh, buf, nbytes, &count, NULL)) {
|
if (!WriteFile(sansa->dh, sansa->sectorbuf, nbytes, &count, NULL)) {
|
||||||
sansa_print_error(" Error writing to disk: ");
|
sansa_print_error(" Error writing to disk: ");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,7 @@ struct mi4header_t {
|
||||||
|
|
||||||
struct sansa_t {
|
struct sansa_t {
|
||||||
HANDLE dh;
|
HANDLE dh;
|
||||||
|
unsigned char* sectorbuf;
|
||||||
char diskname[4096];
|
char diskname[4096];
|
||||||
int sector_size;
|
int sector_size;
|
||||||
struct sansa_partinfo_t pinfo[4];
|
struct sansa_partinfo_t pinfo[4];
|
||||||
|
@ -77,8 +78,8 @@ int sansa_reopen_rw(struct sansa_t* sansa);
|
||||||
int sansa_close(struct sansa_t* sansa);
|
int sansa_close(struct sansa_t* sansa);
|
||||||
int sansa_seek(struct sansa_t* sansa, loff_t pos);
|
int sansa_seek(struct sansa_t* sansa, loff_t pos);
|
||||||
int sansa_read(struct sansa_t* sansa, unsigned char* buf, int nbytes);
|
int sansa_read(struct sansa_t* sansa, unsigned char* buf, int nbytes);
|
||||||
int sansa_write(struct sansa_t* sansa, unsigned char* buf, int nbytes);
|
int sansa_write(struct sansa_t* sansa, int nbytes);
|
||||||
int sansa_alloc_buffer(unsigned char** sectorbuf, int bufsize);
|
int sansa_alloc_buffer(struct sansa_t* sansa, int bufsize);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,8 +43,6 @@ int sansa_verbose = 0;
|
||||||
and initialise it with sansa_alloc_buf() in main().
|
and initialise it with sansa_alloc_buf() in main().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
unsigned char* sansa_sectorbuf = NULL;
|
|
||||||
|
|
||||||
static off_t filesize(int fd) {
|
static off_t filesize(int fd) {
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
|
|
||||||
|
@ -92,17 +90,17 @@ int sansa_read_partinfo(struct sansa_t* sansa, int silent)
|
||||||
int i;
|
int i;
|
||||||
unsigned long count;
|
unsigned long count;
|
||||||
|
|
||||||
count = sansa_read(sansa,sansa_sectorbuf, sansa->sector_size);
|
count = sansa_read(sansa,sansa->sectorbuf, sansa->sector_size);
|
||||||
|
|
||||||
if (count <= 0) {
|
if (count <= 0) {
|
||||||
sansa_print_error(" Error reading from disk: ");
|
sansa_print_error(" Error reading from disk: ");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sansa_sectorbuf[510] == 0x55) && (sansa_sectorbuf[511] == 0xaa)) {
|
if ((sansa->sectorbuf[510] == 0x55) && (sansa->sectorbuf[511] == 0xaa)) {
|
||||||
/* parse partitions */
|
/* parse partitions */
|
||||||
for ( i = 0; i < 4; i++ ) {
|
for ( i = 0; i < 4; i++ ) {
|
||||||
unsigned char* ptr = sansa_sectorbuf + 0x1be + 16*i;
|
unsigned char* ptr = sansa->sectorbuf + 0x1be + 16*i;
|
||||||
sansa->pinfo[i].type = ptr[4];
|
sansa->pinfo[i].type = ptr[4];
|
||||||
sansa->pinfo[i].start = BYTES2INT32(ptr, 8);
|
sansa->pinfo[i].start = BYTES2INT32(ptr, 8);
|
||||||
sansa->pinfo[i].size = BYTES2INT32(ptr, 12);
|
sansa->pinfo[i].size = BYTES2INT32(ptr, 12);
|
||||||
|
@ -112,7 +110,7 @@ int sansa_read_partinfo(struct sansa_t* sansa, int silent)
|
||||||
/* not handled yet */
|
/* not handled yet */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ((sansa_sectorbuf[0] == 'E') && (sansa_sectorbuf[1] == 'R')) {
|
} else if ((sansa->sectorbuf[0] == 'E') && (sansa->sectorbuf[1] == 'R')) {
|
||||||
if (!silent) fprintf(stderr,"[ERR] Bad boot sector signature\n");
|
if (!silent) fprintf(stderr,"[ERR] Bad boot sector signature\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -406,14 +404,14 @@ int is_sansa(struct sansa_t* sansa)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check Bootloader header */
|
/* Check Bootloader header */
|
||||||
if (sansa_seek_and_read(sansa, sansa->start, sansa_sectorbuf, 0x200) < 0) {
|
if (sansa_seek_and_read(sansa, sansa->start, sansa->sectorbuf, 0x200) < 0) {
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
if (memcmp(sansa_sectorbuf,"PPBL",4)!=0) {
|
if (memcmp(sansa->sectorbuf,"PPBL",4)!=0) {
|
||||||
/* No bootloader header, abort */
|
/* No bootloader header, abort */
|
||||||
return -4;
|
return -4;
|
||||||
}
|
}
|
||||||
ppbl_length = (le2int(sansa_sectorbuf+4) + 0x1ff) & ~0x1ff;
|
ppbl_length = (le2int(sansa->sectorbuf+4) + 0x1ff) & ~0x1ff;
|
||||||
|
|
||||||
/* Sanity/safety check - the bootloader can't be larger than PPMI_OFFSET */
|
/* Sanity/safety check - the bootloader can't be larger than PPMI_OFFSET */
|
||||||
if (ppbl_length > PPMI_OFFSET)
|
if (ppbl_length > PPMI_OFFSET)
|
||||||
|
@ -422,12 +420,12 @@ int is_sansa(struct sansa_t* sansa)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load Sansa bootloader and check for "Sansa C200" magic string */
|
/* Load Sansa bootloader and check for "Sansa C200" magic string */
|
||||||
if (sansa_seek_and_read(sansa, sansa->start + 0x200, sansa_sectorbuf, ppbl_length) < 0) {
|
if (sansa_seek_and_read(sansa, sansa->start + 0x200, sansa->sectorbuf, ppbl_length) < 0) {
|
||||||
fprintf(stderr,"[ERR] Seek and read to 0x%08llx in is_sansa failed.\n",
|
fprintf(stderr,"[ERR] Seek and read to 0x%08llx in is_sansa failed.\n",
|
||||||
sansa->start+0x200);
|
sansa->start+0x200);
|
||||||
return -6;
|
return -6;
|
||||||
}
|
}
|
||||||
if (sansa_memmem(sansa_sectorbuf, ppbl_length, "Sansa C200", 10) != NULL) {
|
if (sansa_memmem(sansa->sectorbuf, ppbl_length, "Sansa C200", 10) != NULL) {
|
||||||
/* C200 */
|
/* C200 */
|
||||||
sansa->targetname="c200";
|
sansa->targetname="c200";
|
||||||
} else {
|
} else {
|
||||||
|
@ -436,25 +434,25 @@ int is_sansa(struct sansa_t* sansa)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check Main firmware header */
|
/* Check Main firmware header */
|
||||||
if (sansa_seek_and_read(sansa, sansa->start+PPMI_OFFSET, sansa_sectorbuf, 0x200) < 0) {
|
if (sansa_seek_and_read(sansa, sansa->start+PPMI_OFFSET, sansa->sectorbuf, 0x200) < 0) {
|
||||||
fprintf(stderr,"[ERR] Seek to 0x%08llx in is_sansa failed.\n",
|
fprintf(stderr,"[ERR] Seek to 0x%08llx in is_sansa failed.\n",
|
||||||
sansa->start+PPMI_OFFSET);
|
sansa->start+PPMI_OFFSET);
|
||||||
return -5;
|
return -5;
|
||||||
}
|
}
|
||||||
if (memcmp(sansa_sectorbuf,"PPMI",4)!=0) {
|
if (memcmp(sansa->sectorbuf,"PPMI",4)!=0) {
|
||||||
/* No bootloader header, abort */
|
/* No bootloader header, abort */
|
||||||
return -7;
|
return -7;
|
||||||
}
|
}
|
||||||
ppmi_length = le2int(sansa_sectorbuf+4);
|
ppmi_length = le2int(sansa->sectorbuf+4);
|
||||||
|
|
||||||
/* Check main mi4 file header */
|
/* Check main mi4 file header */
|
||||||
if (sansa_seek_and_read(sansa, sansa->start+PPMI_OFFSET+0x200, sansa_sectorbuf, 0x200) < 0) {
|
if (sansa_seek_and_read(sansa, sansa->start+PPMI_OFFSET+0x200, sansa->sectorbuf, 0x200) < 0) {
|
||||||
fprintf(stderr,"[ERR] Seek to 0x%08llx in is_sansa failed.\n",
|
fprintf(stderr,"[ERR] Seek to 0x%08llx in is_sansa failed.\n",
|
||||||
sansa->start+PPMI_OFFSET+0x200);
|
sansa->start+PPMI_OFFSET+0x200);
|
||||||
return -5;
|
return -5;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_mi4header(sansa_sectorbuf,&mi4header) < 0) {
|
if (get_mi4header(sansa->sectorbuf,&mi4header) < 0) {
|
||||||
fprintf(stderr,"[ERR] Invalid mi4header\n");
|
fprintf(stderr,"[ERR] Invalid mi4header\n");
|
||||||
return -6;
|
return -6;
|
||||||
}
|
}
|
||||||
|
@ -466,15 +464,15 @@ int is_sansa(struct sansa_t* sansa)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
sansa->hasoldbootloader = 0;
|
sansa->hasoldbootloader = 0;
|
||||||
if (memcmp(sansa_sectorbuf+0x1f8,"RBBL",4)==0) {
|
if (memcmp(sansa->sectorbuf+0x1f8,"RBBL",4)==0) {
|
||||||
/* Look for an original firmware after the first image */
|
/* Look for an original firmware after the first image */
|
||||||
if (sansa_seek_and_read(sansa,
|
if (sansa_seek_and_read(sansa,
|
||||||
sansa->start + PPMI_OFFSET + 0x200 + ppmi_length,
|
sansa->start + PPMI_OFFSET + 0x200 + ppmi_length,
|
||||||
sansa_sectorbuf, 512) < 0) {
|
sansa->sectorbuf, 512) < 0) {
|
||||||
return -7;
|
return -7;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_mi4header(sansa_sectorbuf,&mi4header)!=0) {
|
if (get_mi4header(sansa->sectorbuf,&mi4header)!=0) {
|
||||||
fprintf(stderr,"[ERR] No original firmware found\n");
|
fprintf(stderr,"[ERR] No original firmware found\n");
|
||||||
sansa->hasoldbootloader = 1;
|
sansa->hasoldbootloader = 1;
|
||||||
}
|
}
|
||||||
|
@ -659,7 +657,7 @@ int sansa_read_firmware(struct sansa_t* sansa, const char* filename)
|
||||||
int outfile;
|
int outfile;
|
||||||
struct mi4header_t mi4header;
|
struct mi4header_t mi4header;
|
||||||
|
|
||||||
res = load_original_firmware(sansa,sansa_sectorbuf,&mi4header);
|
res = load_original_firmware(sansa,sansa->sectorbuf,&mi4header);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
|
@ -669,7 +667,7 @@ int sansa_read_firmware(struct sansa_t* sansa, const char* filename)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = write(outfile,sansa_sectorbuf,mi4header.mi4size);
|
res = write(outfile,sansa->sectorbuf,mi4header.mi4size);
|
||||||
if (res != (int)mi4header.mi4size) {
|
if (res != (int)mi4header.mi4size) {
|
||||||
fprintf(stderr,"[ERR] Write error - %d\n", res);
|
fprintf(stderr,"[ERR] Write error - %d\n", res);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -730,16 +728,16 @@ int sansa_add_bootloader(struct sansa_t* sansa, const unsigned char* bootloader,
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
/* Create PPMI header */
|
/* Create PPMI header */
|
||||||
memset(sansa_sectorbuf,0,0x200);
|
memset(sansa->sectorbuf,0,0x200);
|
||||||
memcpy(sansa_sectorbuf,"PPMI",4);
|
memcpy(sansa->sectorbuf,"PPMI",4);
|
||||||
int2le(bl_length, sansa_sectorbuf+4);
|
int2le(bl_length, sansa->sectorbuf+4);
|
||||||
int2le(0x00020000, sansa_sectorbuf+8);
|
int2le(0x00020000, sansa->sectorbuf+8);
|
||||||
|
|
||||||
/* copy bootloader to sansa_sectorbuf+0x200 */
|
/* copy bootloader to sansa->sectorbuf+0x200 */
|
||||||
memcpy(sansa_sectorbuf+0x200,bootloader,bl_length);
|
memcpy(sansa->sectorbuf+0x200,bootloader,bl_length);
|
||||||
|
|
||||||
/* Load original firmware from Sansa to the space after the bootloader */
|
/* Load original firmware from Sansa to the space after the bootloader */
|
||||||
res = load_original_firmware(sansa,sansa_sectorbuf+0x200+bl_length,&mi4header);
|
res = load_original_firmware(sansa,sansa->sectorbuf+0x200+bl_length,&mi4header);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
|
@ -753,7 +751,7 @@ int sansa_add_bootloader(struct sansa_t* sansa, const unsigned char* bootloader,
|
||||||
|
|
||||||
length = 0x200 + bl_length + mi4header.mi4size;
|
length = 0x200 + bl_length + mi4header.mi4size;
|
||||||
|
|
||||||
n=sansa_write(sansa, sansa_sectorbuf, length);
|
n=sansa_write(sansa, length);
|
||||||
if (n < length) {
|
if (n < length) {
|
||||||
fprintf(stderr,"[ERR] Short write in add_bootloader\n");
|
fprintf(stderr,"[ERR] Short write in add_bootloader\n");
|
||||||
return -6;
|
return -6;
|
||||||
|
@ -769,16 +767,16 @@ int sansa_delete_bootloader(struct sansa_t* sansa)
|
||||||
int n;
|
int n;
|
||||||
int length;
|
int length;
|
||||||
|
|
||||||
/* Load original firmware from Sansa to sansa_sectorbuf+0x200 */
|
/* Load original firmware from Sansa to sansa->sectorbuf+0x200 */
|
||||||
res = load_original_firmware(sansa,sansa_sectorbuf+0x200,&mi4header);
|
res = load_original_firmware(sansa,sansa->sectorbuf+0x200,&mi4header);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
/* Create PPMI header */
|
/* Create PPMI header */
|
||||||
memset(sansa_sectorbuf,0,0x200);
|
memset(sansa->sectorbuf,0,0x200);
|
||||||
memcpy(sansa_sectorbuf,"PPMI",4);
|
memcpy(sansa->sectorbuf,"PPMI",4);
|
||||||
int2le(mi4header.mi4size, sansa_sectorbuf+4);
|
int2le(mi4header.mi4size, sansa->sectorbuf+4);
|
||||||
int2le(0x00020000, sansa_sectorbuf+8);
|
int2le(0x00020000, sansa->sectorbuf+8);
|
||||||
|
|
||||||
/* Now write the whole thing back to the Sansa */
|
/* Now write the whole thing back to the Sansa */
|
||||||
|
|
||||||
|
@ -790,7 +788,7 @@ int sansa_delete_bootloader(struct sansa_t* sansa)
|
||||||
|
|
||||||
length = 0x200 + mi4header.mi4size;
|
length = 0x200 + mi4header.mi4size;
|
||||||
|
|
||||||
n=sansa_write(sansa, sansa_sectorbuf, length);
|
n=sansa_write(sansa, length);
|
||||||
if (n < length) {
|
if (n < length) {
|
||||||
fprintf(stderr,"[ERR] Short write in delete_bootloader\n");
|
fprintf(stderr,"[ERR] Short write in delete_bootloader\n");
|
||||||
return -6;
|
return -6;
|
||||||
|
@ -808,21 +806,21 @@ int sansa_list_images(struct sansa_t* sansa)
|
||||||
int num = 0;
|
int num = 0;
|
||||||
|
|
||||||
/* Check Main firmware header */
|
/* Check Main firmware header */
|
||||||
if (sansa_seek_and_read(sansa, sansa->start+PPMI_OFFSET, sansa_sectorbuf, 0x200) < 0) {
|
if (sansa_seek_and_read(sansa, sansa->start+PPMI_OFFSET, sansa->sectorbuf, 0x200) < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ppmi_length = le2int(sansa_sectorbuf+4);
|
ppmi_length = le2int(sansa->sectorbuf+4);
|
||||||
|
|
||||||
printf("[INFO] Image 1 - %llu bytes\n",ppmi_length);
|
printf("[INFO] Image 1 - %llu bytes\n",ppmi_length);
|
||||||
num = 1;
|
num = 1;
|
||||||
|
|
||||||
/* Look for an original firmware after the first image */
|
/* Look for an original firmware after the first image */
|
||||||
if (sansa_seek_and_read(sansa, sansa->start + PPMI_OFFSET + 0x200 + ppmi_length, sansa_sectorbuf, 512) < 0) {
|
if (sansa_seek_and_read(sansa, sansa->start + PPMI_OFFSET + 0x200 + ppmi_length, sansa->sectorbuf, 512) < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_mi4header(sansa_sectorbuf,&mi4header)==0) {
|
if (get_mi4header(sansa->sectorbuf,&mi4header)==0) {
|
||||||
printf("[INFO] Image 2 - %d bytes\n",mi4header.mi4size);
|
printf("[INFO] Image 2 - %d bytes\n",mi4header.mi4size);
|
||||||
num = 2;
|
num = 2;
|
||||||
}
|
}
|
||||||
|
@ -874,8 +872,8 @@ int sansa_update_of(struct sansa_t* sansa, const char* filename)
|
||||||
of_length = filesize(infile);
|
of_length = filesize(infile);
|
||||||
|
|
||||||
/* Load original firmware from file */
|
/* Load original firmware from file */
|
||||||
memset(sansa_sectorbuf,0,0x200);
|
memset(sansa->sectorbuf,0,0x200);
|
||||||
n = read(infile,sansa_sectorbuf,of_length);
|
n = read(infile,sansa->sectorbuf,of_length);
|
||||||
close(infile);
|
close(infile);
|
||||||
if (n < of_length) {
|
if (n < of_length) {
|
||||||
fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n"
|
fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n"
|
||||||
|
@ -884,13 +882,13 @@ int sansa_update_of(struct sansa_t* sansa, const char* filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check we have a valid MI4 file. */
|
/* Check we have a valid MI4 file. */
|
||||||
if (get_mi4header(sansa_sectorbuf,&mi4header)!=0) {
|
if (get_mi4header(sansa->sectorbuf,&mi4header)!=0) {
|
||||||
fprintf(stderr,"[ERR] %s is not a valid mi4 file\n",filename);
|
fprintf(stderr,"[ERR] %s is not a valid mi4 file\n",filename);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Decrypt and build the header */
|
/* Decrypt and build the header */
|
||||||
if(prepare_original_firmware(sansa, sansa_sectorbuf, &mi4header)!=0){
|
if(prepare_original_firmware(sansa, sansa->sectorbuf, &mi4header)!=0){
|
||||||
fprintf(stderr,"[ERR] Unable to build decrypted mi4 from %s\n"
|
fprintf(stderr,"[ERR] Unable to build decrypted mi4 from %s\n"
|
||||||
,filename);
|
,filename);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -903,7 +901,7 @@ int sansa_update_of(struct sansa_t* sansa, const char* filename)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
n=sansa_write(sansa, sansa_sectorbuf, of_length);
|
n=sansa_write(sansa, of_length);
|
||||||
if (n < of_length) {
|
if (n < of_length) {
|
||||||
fprintf(stderr,"[ERR] Short write in sansa_update_of\n");
|
fprintf(stderr,"[ERR] Short write in sansa_update_of\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -920,8 +918,8 @@ int sansa_update_of(struct sansa_t* sansa, const char* filename)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(sansa_sectorbuf,0,NVPARAMS_SIZE);
|
memset(sansa->sectorbuf,0,NVPARAMS_SIZE);
|
||||||
n=sansa_write(sansa, sansa_sectorbuf, NVPARAMS_SIZE);
|
n=sansa_write(sansa, NVPARAMS_SIZE);
|
||||||
if (n < NVPARAMS_SIZE) {
|
if (n < NVPARAMS_SIZE) {
|
||||||
fprintf(stderr,"[ERR] Short write in sansa_update_of\n");
|
fprintf(stderr,"[ERR] Short write in sansa_update_of\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -947,7 +945,7 @@ int sansa_update_ppbl(struct sansa_t* sansa, const char* filename)
|
||||||
|
|
||||||
ppbl_length = filesize(infile);
|
ppbl_length = filesize(infile);
|
||||||
|
|
||||||
n = read(infile,sansa_sectorbuf+0x200,ppbl_length);
|
n = read(infile,sansa->sectorbuf+0x200,ppbl_length);
|
||||||
close(infile);
|
close(infile);
|
||||||
if (n < ppbl_length) {
|
if (n < ppbl_length) {
|
||||||
fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n", ppbl_length, n);
|
fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n", ppbl_length, n);
|
||||||
|
@ -955,10 +953,10 @@ int sansa_update_ppbl(struct sansa_t* sansa, const char* filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Step 2 - Build the header */
|
/* Step 2 - Build the header */
|
||||||
memset(sansa_sectorbuf,0,0x200);
|
memset(sansa->sectorbuf,0,0x200);
|
||||||
memcpy(sansa_sectorbuf,"PPBL",4);
|
memcpy(sansa->sectorbuf,"PPBL",4);
|
||||||
int2le(ppbl_length, sansa_sectorbuf+4);
|
int2le(ppbl_length, sansa->sectorbuf+4);
|
||||||
int2le(0x00010000, sansa_sectorbuf+8);
|
int2le(0x00010000, sansa->sectorbuf+8);
|
||||||
|
|
||||||
/* Step 3 - write the bootloader to the Sansa */
|
/* Step 3 - write the bootloader to the Sansa */
|
||||||
if (sansa_seek(sansa, sansa->start) < 0) {
|
if (sansa_seek(sansa, sansa->start) < 0) {
|
||||||
|
@ -966,7 +964,7 @@ int sansa_update_ppbl(struct sansa_t* sansa, const char* filename)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
n=sansa_write(sansa, sansa_sectorbuf, ppbl_length + 0x200);
|
n=sansa_write(sansa, ppbl_length + 0x200);
|
||||||
if (n < (ppbl_length+0x200)) {
|
if (n < (ppbl_length+0x200)) {
|
||||||
fprintf(stderr,"[ERR] Short write in sansa_update_ppbl\n");
|
fprintf(stderr,"[ERR] Short write in sansa_update_ppbl\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -32,15 +32,6 @@ extern int sansa_verbose;
|
||||||
/* Size of buffer for disk I/O - 8MB is large enough for any version
|
/* Size of buffer for disk I/O - 8MB is large enough for any version
|
||||||
of the Apple firmware, but not the Nano's RSRC image. */
|
of the Apple firmware, but not the Nano's RSRC image. */
|
||||||
#define BUFFER_SIZE 8*1024*1024
|
#define BUFFER_SIZE 8*1024*1024
|
||||||
#ifndef _MSC_VER
|
|
||||||
extern unsigned char* sansa_sectorbuf;
|
|
||||||
#else
|
|
||||||
/* MSVC needs to use dllimport to allow using it directly from a DLL.
|
|
||||||
* See http://support.microsoft.com/kb/90530
|
|
||||||
* Building with MSVC is only when using as DLL.
|
|
||||||
*/
|
|
||||||
_declspec(dllimport) unsigned char* sansa_sectorbuf;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int sansa_read_partinfo(struct sansa_t* sansa, int silent);
|
int sansa_read_partinfo(struct sansa_t* sansa, int silent);
|
||||||
int is_sansa(struct sansa_t* sansa);
|
int is_sansa(struct sansa_t* sansa);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue