diff --git a/recovery/mainwindow.cpp b/recovery/mainwindow.cpp index 4245713d..b2e8d5c3 100644 --- a/recovery/mainwindow.cpp +++ b/recovery/mainwindow.cpp @@ -648,7 +648,9 @@ void MainWindow::onQuery(const QString &msg, const QString &title, QMessageBox:: void MainWindow::on_list_currentRowChanged() { QListWidgetItem *item = ui->list->currentItem(); - ui->actionEdit_config->setEnabled(item && item->data(Qt::UserRole).toMap().contains("partitions")); + ui->actionEdit_config->setEnabled(item + && item->data(Qt::UserRole).toMap().contains("partitions") + && item->data(Qt::UserRole).toMap().value("bootable", true) == true ); } void MainWindow::update_window_title() @@ -1290,6 +1292,7 @@ void MainWindow::updateNeeded() bool enableOk = false; QColor colorNeededLabel = Qt::black; bool bold = false; + bool datapartition = false; _neededMB = 0; QList selected = selectedItems(); @@ -1305,6 +1308,10 @@ void MainWindow::updateNeeded() int startSector = getFileContents("/sys/class/block/mmcblk0p2/start").trimmed().toULongLong(); _neededMB += (RISCOS_SECTOR_OFFSET - startSector)/2048; } + if (entry.value("name").toString().contains("data partition", Qt::CaseInsensitive)) + { + datapartition = true; + } } ui->neededLabel->setText(QString("%1: %2 MB").arg(tr("Needed"), QString::number(_neededMB))); @@ -1318,9 +1325,10 @@ void MainWindow::updateNeeded() } else { - if (_neededMB) + if (_neededMB && !(datapartition && selected.count() == 1)) { - /* Enable OK button if a selection has been made that fits on the card */ + /* Enable OK button if a selection has been made that fits on the card + and it is not only the data partition that has been selected */ enableOk = true; } } diff --git a/recovery/multiimagewritethread.cpp b/recovery/multiimagewritethread.cpp index db6085bb..06f762e3 100644 --- a/recovery/multiimagewritethread.cpp +++ b/recovery/multiimagewritethread.cpp @@ -362,6 +362,11 @@ bool MultiImageWriteThread::processImage(OsInfo *image) qDebug() << "Processing OS:" << os_name; QList *partitions = image->partitions(); + if (partitions->isEmpty()) + { + emit error(tr("No partitions defined in partitions.json")); + return false; + } foreach (PartitionInfo *p, *partitions) { @@ -453,15 +458,6 @@ bool MultiImageWriteThread::processImage(OsInfo *image) _part++; } - emit statusUpdate(tr("%1: Mounting FAT partition").arg(os_name)); - if (QProcess::execute("mount "+partitions->first()->partitionDevice()+" /mnt2") != 0) - { - emit error(tr("%1: Error mounting file system").arg(os_name)); - return false; - } - - emit statusUpdate(tr("%1: Creating os_config.json").arg(os_name)); - QString description = getDescription(image->folder(), image->flavour()); QVariantList vpartitions; foreach (PartitionInfo *p, *partitions) @@ -473,90 +469,106 @@ bool MultiImageWriteThread::processImage(OsInfo *image) QString language = settings.value("language", "en").toString(); QString keyboard = settings.value("keyboard_layout", "gb").toString(); - QVariantMap qm; - qm.insert("flavour", image->flavour()); - qm.insert("release_date", image->releaseDate()); - qm.insert("imagefolder", image->folder()); - qm.insert("description", description); - qm.insert("videomode", videomode); - qm.insert("partitions", vpartitions); - qm.insert("language", language); - qm.insert("keyboard", keyboard); - - Json::saveToFile("/mnt2/os_config.json", qm); - - emit statusUpdate(tr("%1: Saving display mode to config.txt").arg(os_name)); - patchConfigTxt(); - - /* Partition setup script can either reside in the image folder - * or inside the boot partition tarball */ - QString postInstallScript = image->folder()+"/partition_setup.sh"; - if (!QFile::exists(postInstallScript)) - postInstallScript = "/mnt2/partition_setup.sh"; - - if (QFile::exists(postInstallScript)) - { - emit statusUpdate(tr("%1: Running partition setup script").arg(os_name)); - QProcess proc; - QProcessEnvironment env; - QStringList args(postInstallScript); - env.insert("PATH", "/bin:/usr/bin:/sbin:/usr/sbin"); - - /* - Parameters to the partition-setup script are supplied both as - * command line parameters and set as environement variables - * - Boot partition is mounted, working directory is set to its mnt folder - * - * partition_setup.sh part1=/dev/mmcblk0p3 id1=LABEL=BOOT part2=/dev/mmcblk0p4 - * id2=UUID=550e8400-e29b-41d4-a716-446655440000 - */ - int pnr = 1; - foreach (PartitionInfo *p, *partitions) + QByteArray fstypeFirstPartition = partitions->first()->fsType(); + bool firstPartitionIsFat = (fstypeFirstPartition == "FAT" || fstypeFirstPartition == "fat"); + bool firstPartitionIsBootable = image->bootable() && firstPartitionIsFat; + + if (firstPartitionIsBootable) + { + emit statusUpdate(tr("%1: Mounting FAT partition").arg(os_name)); + if (QProcess::execute("mount "+partitions->first()->partitionDevice()+" /mnt2") != 0) { - QString part = p->partitionDevice(); - QString nr = QString::number(pnr); - QString uuid = getUUID(part); - QString label = getLabel(part); - QString id; - if (!label.isEmpty()) - id = "LABEL="+label; - else - id = "UUID="+uuid; + emit error(tr("%1: Error mounting file system").arg(os_name)); + return false; + } - qDebug() << "part" << part << uuid << label; + emit statusUpdate(tr("%1: Creating os_config.json").arg(os_name)); - args << "part"+nr+"="+part << "id"+nr+"="+id; - env.insert("part"+nr, part); - env.insert("id"+nr, id); - pnr++; - } + QVariantMap qm; + qm.insert("flavour", image->flavour()); + qm.insert("release_date", image->releaseDate()); + qm.insert("imagefolder", image->folder()); + qm.insert("description", description); + qm.insert("videomode", videomode); + qm.insert("partitions", vpartitions); + qm.insert("language", language); + qm.insert("keyboard", keyboard); - qDebug() << "Executing: sh" << args; - qDebug() << "Env:" << env.toStringList(); - proc.setProcessChannelMode(proc.MergedChannels); - proc.setProcessEnvironment(env); - proc.setWorkingDirectory("/mnt2"); - proc.start("/bin/sh", args); - proc.waitForFinished(-1); - qDebug() << proc.exitStatus(); + Json::saveToFile("/mnt2/os_config.json", qm); - if (proc.exitCode() != 0) + emit statusUpdate(tr("%1: Saving display mode to config.txt").arg(os_name)); + patchConfigTxt(); + + /* Partition setup script can either reside in the image folder + * or inside the boot partition tarball */ + QString postInstallScript = image->folder()+"/partition_setup.sh"; + if (!QFile::exists(postInstallScript)) + postInstallScript = "/mnt2/partition_setup.sh"; + + if (QFile::exists(postInstallScript)) { - emit error(tr("%1: Error executing partition setup script").arg(os_name)+"\n"+proc.readAll()); - return false; + emit statusUpdate(tr("%1: Running partition setup script").arg(os_name)); + QProcess proc; + QProcessEnvironment env; + QStringList args(postInstallScript); + env.insert("PATH", "/bin:/usr/bin:/sbin:/usr/sbin"); + + /* - Parameters to the partition-setup script are supplied both as + * command line parameters and set as environement variables + * - Boot partition is mounted, working directory is set to its mnt folder + * + * partition_setup.sh part1=/dev/mmcblk0p3 id1=LABEL=BOOT part2=/dev/mmcblk0p4 + * id2=UUID=550e8400-e29b-41d4-a716-446655440000 + */ + int pnr = 1; + foreach (PartitionInfo *p, *partitions) + { + QString part = p->partitionDevice(); + QString nr = QString::number(pnr); + QString uuid = getUUID(part); + QString label = getLabel(part); + QString id; + if (!label.isEmpty()) + id = "LABEL="+label; + else + id = "UUID="+uuid; + + qDebug() << "part" << part << uuid << label; + + args << "part"+nr+"="+part << "id"+nr+"="+id; + env.insert("part"+nr, part); + env.insert("id"+nr, id); + pnr++; + } + + qDebug() << "Executing: sh" << args; + qDebug() << "Env:" << env.toStringList(); + proc.setProcessChannelMode(proc.MergedChannels); + proc.setProcessEnvironment(env); + proc.setWorkingDirectory("/mnt2"); + proc.start("/bin/sh", args); + proc.waitForFinished(-1); + qDebug() << proc.exitStatus(); + + if (proc.exitCode() != 0) + { + emit error(tr("%1: Error executing partition setup script").arg(os_name)+"\n"+proc.readAll()); + return false; + } } - } - PartitionInfo *p = partitions->first(); - if (!p->bcdFile().isEmpty()) - { - emit statusUpdate(tr("%1: Patching BCD file").arg(os_name)); - patchBcdFile("/mnt2/"+p->bcdFile(), p->bcdDiskId(), p->bcdEfiSector(), p->bcdMainSector() ); - } + PartitionInfo *p = partitions->first(); + if (!p->bcdFile().isEmpty()) + { + emit statusUpdate(tr("%1: Patching BCD file").arg(os_name)); + patchBcdFile("/mnt2/"+p->bcdFile(), p->bcdDiskId(), p->bcdEfiSector(), p->bcdMainSector() ); + } - emit statusUpdate(tr("%1: Unmounting FAT partition").arg(os_name)); - if (QProcess::execute("umount /mnt2") != 0) - { - emit error(tr("%1: Error unmounting").arg(os_name)); + emit statusUpdate(tr("%1: Unmounting FAT partition").arg(os_name)); + if (QProcess::execute("umount /mnt2") != 0) + { + emit error(tr("%1: Error unmounting").arg(os_name)); + } } /* Save information about installed operating systems in installed_os.json */ @@ -566,7 +578,7 @@ bool MultiImageWriteThread::processImage(OsInfo *image) ventry["folder"] = image->folder(); ventry["release_date"]= image->releaseDate(); ventry["partitions"] = vpartitions; - ventry["bootable"] = image->bootable(); + ventry["bootable"] = firstPartitionIsBootable; QString iconfilename = image->folder()+"/"+image->flavour()+".png"; iconfilename.replace(" ", "_"); if (QFile::exists(iconfilename))