diff --git a/src/fs/udf.cpp b/src/fs/udf.cpp index a33ae44..f34c5f3 100644 --- a/src/fs/udf.cpp +++ b/src/fs/udf.cpp @@ -30,9 +30,12 @@ namespace FS { -constexpr qint64 MIN_UDF_BLOCKS = 282; +constexpr qint64 MIN_UDF_BLOCKS = 300; constexpr qint64 MAX_UDF_BLOCKS = ((1ULL << 32) - 1); +FileSystem::CommandSupportType udf::m_GetUsed = FileSystem::cmdSupportNone; +FileSystem::CommandSupportType udf::m_SetLabel = FileSystem::cmdSupportNone; +FileSystem::CommandSupportType udf::m_UpdateUUID = FileSystem::cmdSupportNone; FileSystem::CommandSupportType udf::m_Create = FileSystem::cmdSupportNone; bool udf::oldMkudffsVersion = false; @@ -43,6 +46,8 @@ udf::udf(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QStrin void udf::init() { + m_GetUsed = findExternal(QStringLiteral("udfinfo"), {}, 1) ? cmdSupportFileSystem : cmdSupportNone; + m_SetLabel = m_UpdateUUID = findExternal(QStringLiteral("udflabel"), {}, 1) ? cmdSupportFileSystem : cmdSupportNone; m_Create = findExternal(QStringLiteral("mkudffs"), {}, 1) ? cmdSupportFileSystem : cmdSupportNone; if (m_Create == cmdSupportFileSystem) { @@ -54,7 +59,11 @@ void udf::init() bool udf::supportToolFound() const { - return m_Create != cmdSupportNone; + return + m_GetUsed != cmdSupportNone && + m_SetLabel != cmdSupportNone && + m_UpdateUUID != cmdSupportNone && + m_Create != cmdSupportNone; } FileSystem::SupportTool udf::supportToolName() const @@ -93,6 +102,36 @@ QValidator* udf::labelValidator(QObject *parent) const return m_LabelValidator; } +qint64 udf::readUsedCapacity(const QString& deviceNode) const +{ + ExternalCommand cmd(QStringLiteral("udfinfo"), { QStringLiteral("--utf8"), deviceNode }); + if (!cmd.run(-1) || cmd.exitCode() != 0) + return -1; + + QRegularExpressionMatch reBlockSize = QRegularExpression(QStringLiteral("^blocksize=([0-9]+)$"), QRegularExpression::MultilineOption).match(cmd.output()); + QRegularExpressionMatch reUsedBlocks = QRegularExpression(QStringLiteral("^usedblocks=([0-9]+)$"), QRegularExpression::MultilineOption).match(cmd.output()); + + if (!reBlockSize.hasMatch() || !reUsedBlocks.hasMatch()) + return -1; + + qint64 blockSize = reBlockSize.captured(1).toLongLong(); + qint64 usedBlocks = reUsedBlocks.captured(1).toLongLong(); + + return usedBlocks * blockSize; +} + +bool udf::writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) +{ + ExternalCommand cmd(report, QStringLiteral("udflabel"), { QStringLiteral("--utf8"), deviceNode, newLabel }); + return cmd.run(-1) && cmd.exitCode() == 0; +} + +bool udf::updateUUID(Report& report, const QString& deviceNode) const +{ + ExternalCommand cmd(report, QStringLiteral("udflabel"), { QStringLiteral("--utf8"), QStringLiteral("--uuid=random"), deviceNode }); + return cmd.run(-1) && cmd.exitCode() == 0; +} + bool udf::create(Report& report, const QString& deviceNode) { return createWithLabel(report, deviceNode, QString()); diff --git a/src/fs/udf.h b/src/fs/udf.h index bc2a5c9..f49df36 100644 --- a/src/fs/udf.h +++ b/src/fs/udf.h @@ -42,9 +42,15 @@ public: public: void init() override; + qint64 readUsedCapacity(const QString& deviceNode) const override; bool create(Report& report, const QString& deviceNode) override; bool createWithLabel(Report& report, const QString& deviceNode, const QString& label) override; + bool writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) override; + bool updateUUID(Report& report, const QString& deviceNode) const override; + CommandSupportType supportGetUsed() const override { + return m_GetUsed; + } CommandSupportType supportGetLabel() const override { return cmdSupportCore; } @@ -63,6 +69,12 @@ public: CommandSupportType supportBackup() const override { return cmdSupportCore; } + CommandSupportType supportSetLabel() const override { + return m_SetLabel; + } + CommandSupportType supportUpdateUUID() const override { + return m_UpdateUUID; + } CommandSupportType supportGetUUID() const override { return cmdSupportCore; } @@ -75,6 +87,9 @@ public: bool supportToolFound() const override; public: + static CommandSupportType m_GetUsed; + static CommandSupportType m_SetLabel; + static CommandSupportType m_UpdateUUID; static CommandSupportType m_Create; private: