/************************************************************************* * Copyright (C) 2008 by Volker Lanz * * Copyright (C) 2016 by Andrius Štikonas * * * * 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 3 of * * the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see .* *************************************************************************/ #include "jobs/restorefilesystemjob.h" #include "backend/corebackend.h" #include "backend/corebackendmanager.h" #include "backend/corebackenddevice.h" #include "backend/corebackendpartitiontable.h" #include "core/partition.h" #include "core/device.h" #include "core/copysourcefile.h" #include "core/copytargetdevice.h" #include "fs/filesystem.h" #include "fs/filesystemfactory.h" #include "util/report.h" #include /** Creates a new RestoreFileSystemJob @param targetdevice the Device the FileSystem is to be restored to @param targetpartition the Partition the FileSystem is to be restore to @param filename the file name with the image file to restore */ RestoreFileSystemJob::RestoreFileSystemJob(Device& targetdevice, Partition& targetpartition, const QString& filename) : Job(), m_TargetDevice(targetdevice), m_TargetPartition(targetpartition), m_FileName(filename) { } qint32 RestoreFileSystemJob::numSteps() const { return 100; } bool RestoreFileSystemJob::run(Report& parent) { // Restoring is file system independent because we currently have no way of // detecting the file system in a given image file. We cannot even find out if the // file the user gave us is a valid image file or just some junk. bool rval = false; Report* report = jobStarted(parent); // Again, a scope for copyTarget and copySource. See MoveFileSystemJob::run() { // FileSystems are restored to _partitions_, so don't use first and last sector of file system here CopyTargetDevice copyTarget(targetDevice(), targetPartition().firstByte(), targetPartition().lastByte()); CopySourceFile copySource(fileName()); if (!copySource.open()) report->line() << xi18nc("@info:progress", "Could not open backup file %1 to restore from.", fileName()); else if (!copyTarget.open()) report->line() << xi18nc("@info:progress", "Could not open target partition %1 to restore to.", targetPartition().deviceNode()); else { rval = copyBlocks(*report, copyTarget, copySource); if (rval) { // create a new file system for what was restored with the length of the image file const qint64 newLastSector = targetPartition().firstSector() + copySource.length() - 1; std::unique_ptr backendDevice = CoreBackendManager::self()->backend()->openDevice(targetDevice()); FileSystem::Type t = FileSystem::Type::Unknown; if (backendDevice) { std::unique_ptr backendPartitionTable = backendDevice->openPartitionTable(); if (backendPartitionTable) t = backendPartitionTable->detectFileSystemBySector(*report, targetDevice(), targetPartition().firstSector()); } FileSystem* fs = FileSystemFactory::create(t, targetPartition().firstSector(), newLastSector, targetPartition().sectorSize()); targetPartition().deleteFileSystem(); targetPartition().setFileSystem(fs); } report->line() << xi18nc("@info:progress", "Closing device. This may take a few seconds."); } } jobFinished(*report, rval); return rval; } QString RestoreFileSystemJob::description() const { return xi18nc("@info:progress", "Restore the file system from file %1 to partition %2", fileName(), targetPartition().deviceNode()); }