diff --git a/src/fs/filesystem.cpp b/src/fs/filesystem.cpp index 3c7e323..610bdb1 100644 --- a/src/fs/filesystem.cpp +++ b/src/fs/filesystem.cpp @@ -185,6 +185,20 @@ QString FileSystem::readUUID(const QString& deviceNode) const } +/** Give implementations of FileSystem a chance to update the boot sector after the + file system has been moved or copied. + @param report Report to write status information to + @param deviceNode the device node for the Partition the FileSystem is on + @return true on success +*/ +bool FileSystem::updateBootSector(Report& report, const QString& deviceNode) const +{ + Q_UNUSED(report); + Q_UNUSED(deviceNode); + + return true; +} + /** @return the minimum capacity valid for this FileSystem in bytes */ qint64 FileSystem::minCapacity() const { diff --git a/src/fs/filesystem.h b/src/fs/filesystem.h index 8ee87e5..c58dcdd 100644 --- a/src/fs/filesystem.h +++ b/src/fs/filesystem.h @@ -93,6 +93,7 @@ class FileSystem virtual bool check(Report& report, const QString& deviceNode) const; virtual bool updateUUID(Report& report, const QString& deviceNode) const; virtual QString readUUID(const QString& deviceNode) const; + virtual bool updateBootSector(Report& report, const QString& deviceNode) const; virtual SupportType supportGetUsed() const { return SupportNone; } /**< @return SupportType for getting used capacity */ virtual SupportType supportGetLabel() const { return SupportNone; } /**< @return SupportType for reading label*/ diff --git a/src/fs/ntfs.cpp b/src/fs/ntfs.cpp index dabaa53..08e2528 100644 --- a/src/fs/ntfs.cpp +++ b/src/fs/ntfs.cpp @@ -21,12 +21,19 @@ #include "util/externalcommand.h" #include "util/capacity.h" +#include "util/report.h" +#include "util/globallog.h" + +#include +#include #include #include +#include #include #include +#include namespace FS { @@ -163,4 +170,40 @@ namespace FS return cmd.waitFor(-1); } + + bool ntfs::updateBootSector(Report& report, const QString& deviceNode) const + { + report.line() << i18nc("@info/plain", "Updating boot sector for NTFS file system on partition %1.", deviceNode); + + quint32 n = firstSector(); + char* s = reinterpret_cast(&n); + +#if Q_BYTE_ORDER == Q_BIG_ENDIAN + std::swap(s[0], s[3]); + std::swap(s[1], s[2]); +#endif + + QFile device(deviceNode); + if (!device.open(QFile::ReadWrite | QFile::Unbuffered)) + { + log() << i18nc("@info/plain", "Could not open partition %1 for writing when trying to update the NTFS boot sector.", deviceNode); + return false; + } + + if (!device.seek(0x1c)) + { + log() << i18nc("@info/plain", "Could not seek to position 0x1c on partition %1 when trying to update the NTFS boot sector.", deviceNode); + return false; + } + + if (device.write(s, 4) != 4) + { + log() << i18nc("@info/plain", "Could not write new start sector to partition %1 when trying to update the NTFS boot sector.", deviceNode); + return false; + } + + log() << i18nc("@info/plain", "Updated NTFS boot sector for partition %1 successfully.", deviceNode); + + return true; + } } diff --git a/src/fs/ntfs.h b/src/fs/ntfs.h index 8eed5ea..79e6ce2 100644 --- a/src/fs/ntfs.h +++ b/src/fs/ntfs.h @@ -50,6 +50,7 @@ namespace FS virtual bool resize(Report& report, const QString& deviceNode, qint64 length) const; virtual bool writeLabel(Report& report, const QString& deviceNode, const QString& newLabel); virtual bool updateUUID(Report& report, const QString& deviceNode) const; + virtual bool updateBootSector(Report& report, const QString& deviceNode) const; virtual SupportType supportGetUsed() const { return m_GetUsed; } virtual SupportType supportGetLabel() const { return m_GetLabel; } diff --git a/src/jobs/copyfilesystemjob.cpp b/src/jobs/copyfilesystemjob.cpp index 3fab0ba..1483238 100644 --- a/src/jobs/copyfilesystemjob.cpp +++ b/src/jobs/copyfilesystemjob.cpp @@ -92,6 +92,9 @@ bool CopyFileSystemJob::run(Report& parent) } } + if (rval) + rval = targetPartition().fileSystem().updateBootSector(*report, targetPartition().deviceNode()); + jobFinished(*report, rval); return rval; diff --git a/src/jobs/movefilesystemjob.cpp b/src/jobs/movefilesystemjob.cpp index c613a42..d5a3923 100644 --- a/src/jobs/movefilesystemjob.cpp +++ b/src/jobs/movefilesystemjob.cpp @@ -50,7 +50,7 @@ qint32 MoveFileSystemJob::numSteps() const bool MoveFileSystemJob::run(Report& parent) { bool rval = false; - + Report* report = jobStarted(parent); // A scope for moveSource and moveTarget, so CopyTargetDevice's dtor runs before we @@ -73,14 +73,17 @@ bool MoveFileSystemJob::run(Report& parent) const qint64 savedLength = partition().fileSystem().length() - 1; partition().fileSystem().setFirstSector(newStart()); partition().fileSystem().setLastSector(newStart() + savedLength); - } + } else if (!rollbackCopyBlocks(*report, moveTarget, moveSource)) report->line() << i18nc("@info/plain", "Rollback for file system on partition %1 failed.", partition().deviceNode()); - + report->line() << i18nc("@info/plain", "Closing device. This may take a few seconds."); } } - + + if (rval) + rval = partition().fileSystem().updateBootSector(*report, partition().deviceNode()); + jobFinished(*report, rval); return rval;