void BootloaderInstallAms::installStage2(void)
{    
    qDebug() << "[BootloaderInstallAms] installStage2";
    
    unsigned char* buf;
    unsigned char* of_packed;
    int of_packedsize;
    unsigned char* rb_packed;
    int rb_packedsize;
    off_t len;
    struct md5sums sum;
    char md5sum[33]; /* 32 hex digits, plus terminating zero */
    int n;
    int firmware_size;
    int bootloader_size;
    int patchable;
    int totalsize;
    char errstr[200];
      
    sum.md5 = md5sum;  
      
    m_tempfile.open();
    QString bootfile = m_tempfile.fileName();
    m_tempfile.close();

    /* Load original firmware file */                
    buf = load_of_file(m_offile.toLocal8Bit().data(), &len,&sum,&firmware_size,
                        &of_packed,&of_packedsize,errstr,sizeof(errstr));
    if (buf == NULL) 
    {
        qDebug() << "[BootloaderInstallAms] could not load OF: " << m_offile;
        emit logItem(errstr, LOGERROR);
        emit logItem(tr("Could not load %1").arg(m_offile), LOGERROR);
        emit done(true);
        return;
    }

    /* Load bootloader file */
    rb_packed = load_rockbox_file(bootfile.toLocal8Bit().data(), sum.model,
                                  &bootloader_size,&rb_packedsize,
                                    errstr,sizeof(errstr));
    if (rb_packed == NULL) 
    {   
        qDebug() << "[BootloaderInstallAms] could not load bootloader: " << bootfile;
        emit logItem(errstr, LOGERROR);
        emit logItem(tr("Could not load %1").arg(bootfile), LOGERROR);
        free(buf);
        free(of_packed);
        emit done(true);
        return;
    }
    
    /* check total size */
    patchable = check_sizes(sum.model, rb_packedsize, bootloader_size,
            of_packedsize, firmware_size, &totalsize, errstr, sizeof(errstr));

    if (!patchable)
    {
        qDebug() << "[BootloaderInstallAms] No room to insert bootloader";
        emit logItem(errstr, LOGERROR);
        emit logItem(tr("No room to insert bootloader, try another firmware version"),
                     LOGERROR);
        free(buf);
        free(of_packed);
        free(rb_packed);
        emit done(true);
        return;
    }
    
    /* patch the firmware */
    emit logItem(tr("Patching Firmware..."), LOGINFO);
    
    patch_firmware(sum.model,firmware_revision(sum.model),firmware_size,buf,
                   len,of_packed,of_packedsize,rb_packed,rb_packedsize);

    /* write out file */
    QFile out(m_blfile);
    
    if(!out.open(QIODevice::WriteOnly | QIODevice::Truncate))
    {
        qDebug() << "[BootloaderInstallAms] Could not open" <<  m_blfile << "for writing";
        emit logItem(tr("Could not open %1 for writing").arg(m_blfile),LOGERROR);
        free(buf);
        free(of_packed);
        free(rb_packed);
        emit done(true);
        return;
    }
    
    n = out.write((char*)buf, len);

    if (n != len)
    {
        qDebug() << "[BootloaderInstallAms] Could not write firmware file";
        emit logItem(tr("Could not write firmware file"),LOGERROR);
        free(buf);
        free(of_packed);
        free(rb_packed);
        emit done(true);
        return;
    }

    out.close();
    
    free(buf);
    free(of_packed);
    free(rb_packed);
    
    //end of install
    qDebug() << "[BootloaderInstallAms] install successfull";
    emit logItem(tr("Success: modified firmware file created"), LOGINFO);
    logInstall(LogAdd);
    emit done(false);
    return;
}
Esempio n. 2
0
/* standalone executable */
int main(int argc, char* argv[])
{
    char *infile, *bootfile, *outfile;
    int fdout;
    off_t len;
    uint32_t n;
    unsigned char* buf;
    int firmware_size;
    int bootloader_size;
    unsigned char* of_packed;
    int of_packedsize;
    unsigned char* rb_packed;
    int rb_packedsize;
    int patchable;
    int totalsize;
    int model;
    char errstr[200];
    struct md5sums sum;
    char md5sum[33]; /* 32 digits + \0 */

    sum.md5 = md5sum;

/* VERSION comes frome the Makefile */
    fprintf(stderr,
"mkamsboot Version " VERSION "\n"
"This is free software; see the source for copying conditions.  There is NO\n"
"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
"\n");

    if(argc != 4) {
        printf("Usage: mkamsboot <firmware file> <boot file> <output file>\n");
        return 1;
    }

    infile = argv[1];
    bootfile = argv[2];
    outfile = argv[3];

    /* Load bootloader file */
    rb_packed = load_rockbox_file(bootfile, &model, &bootloader_size,
            &rb_packedsize, errstr, sizeof(errstr));
    if (rb_packed == NULL) {
        fprintf(stderr, "%s", errstr);
        fprintf(stderr, "[ERR]  Could not load %s\n", bootfile);
        return 1;
    }

    /* Load original firmware file */
    buf = load_of_file(infile, model, &len, &sum,
            &firmware_size, &of_packed, &of_packedsize, errstr, sizeof(errstr));

    if (buf == NULL) {
        free(rb_packed);
        fprintf(stderr, "%s", errstr);
        fprintf(stderr, "[ERR]  Could not load %s\n", infile);
        return 1;
    }

    fprintf(stderr, "[INFO] Original firmware MD5 checksum match\n");
    fprintf(stderr, "[INFO] Model: Sansa %s v%d - Firmware version: %s\n",
            model_names[sum.model], hw_revisions[sum.model], sum.version);


    printf("[INFO] Firmware patching has begun !\n\n");

    fprintf(stderr, "[INFO] Original firmware size:   %d bytes\n",
            firmware_size);
    fprintf(stderr, "[INFO] Packed OF size:           %d bytes\n",
            of_packedsize);
    fprintf(stderr, "[INFO] Bootloader size:          %d bytes\n",
            (int)bootloader_size);
    fprintf(stderr, "[INFO] Packed bootloader size:   %d bytes\n",
            rb_packedsize);
    fprintf(stderr, "[INFO] Dual-boot function size:  %d bytes\n",
            bootloader_sizes[sum.model]);
    fprintf(stderr, "[INFO] UCL unpack function size: %u bytes\n",
            (unsigned int)sizeof(nrv2e_d8));

    patchable = check_sizes(sum.model, rb_packedsize, bootloader_size,
        of_packedsize, firmware_size, &totalsize, errstr, sizeof(errstr));

    fprintf(stderr, "[INFO] Total size of new image:  %d bytes\n", totalsize);

    if (!patchable) {
        fprintf(stderr, "%s", errstr);
        free(buf);
        free(of_packed);
        free(rb_packed);
        return 1;
    }

    patch_firmware(sum.model, fw_revisions[sum.model], firmware_size, buf, len,
            of_packed, of_packedsize, rb_packed, rb_packedsize);

    /* Write the new firmware */
    fdout = open(outfile, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, 0666);

    if (fdout < 0) {
        fprintf(stderr, "[ERR]  Could not open %s for writing\n", outfile);
        free(buf);
        free(of_packed);
        free(rb_packed);
        return 1;
    }

    n = write(fdout, buf, len);

    if (n != (unsigned)len) {
        fprintf(stderr, "[ERR]  Could not write firmware file\n");
        free(buf);
        free(of_packed);
        free(rb_packed);
        return 1;
    }

    close(fdout);
    free(buf);
    free(of_packed);
    free(rb_packed);
    fprintf(stderr, "\n[INFO] Patching succeeded!\n");

    return 0;
}