pmt: reformat code and improve

This commit is contained in:
2025-08-13 09:54:11 +03:00
parent d74f385a68
commit 0bc5f70294
14 changed files with 127 additions and 77 deletions

View File

@@ -17,9 +17,9 @@
#ifndef LIBPMT_LIB_HPP #ifndef LIBPMT_LIB_HPP
#define LIBPMT_LIB_HPP #define LIBPMT_LIB_HPP
#include <CLI/CLI11.hpp>
#include <libhelper/lib.hpp> #include <libhelper/lib.hpp>
#include <libpartition_map/lib.hpp> #include <libpartition_map/lib.hpp>
#include <CLI/CLI11.hpp>
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector> #include <vector>

View File

@@ -40,13 +40,16 @@ std::vector<std::string> splitIfHasDelim(const std::string &s, const char delim,
} }
void setupBufferSize(uint64_t &size, const std::string &entry) { void setupBufferSize(uint64_t &size, const std::string &entry) {
if (Variables->PartMap->hasPartition(entry) && Variables->PartMap->sizeOf(entry) % size != 0) { if (Variables->PartMap->hasPartition(entry) &&
println("%sWARNING%s: Specified buffer size is invalid for %s! Using different buffer size for %s.", Variables->PartMap->sizeOf(entry) % size != 0) {
println("%sWARNING%s: Specified buffer size is invalid for %s! Using "
"different buffer size for %s.",
YELLOW, STYLE_RESET, entry.data(), entry.data()); YELLOW, STYLE_RESET, entry.data(), entry.data());
size = Variables->PartMap->sizeOf(entry) % 4096 == 0 ? 4096 : 1; size = Variables->PartMap->sizeOf(entry) % 4096 == 0 ? 4096 : 1;
} else if (Helper::fileIsExists(entry)) { } else if (Helper::fileIsExists(entry)) {
if (Helper::fileSize(entry) % size != 0) { if (Helper::fileSize(entry) % size != 0) {
println("%sWARNING%s: Specified buffer size is invalid for %s! using different buffer size for %s.", println("%sWARNING%s: Specified buffer size is invalid for %s! using "
"different buffer size for %s.",
YELLOW, STYLE_RESET, entry.data(), entry.data()); YELLOW, STYLE_RESET, entry.data(), entry.data());
size = Helper::fileSize(entry) % 4096 == 0 ? 4096 : 1; size = Helper::fileSize(entry) % 4096 == 0 ? 4096 : 1;
} }

View File

@@ -40,8 +40,10 @@ basic_variables::basic_variables()
: logFile("/sdcard/Documents/last_pmt_logs.log"), onLogical(false), : logFile("/sdcard/Documents/last_pmt_logs.log"), onLogical(false),
quietProcess(false), verboseMode(false), viewVersion(false), quietProcess(false), verboseMode(false), viewVersion(false),
forceProcess(false) { forceProcess(false) {
try { PartMap = new PartitionMap::BuildMap(); } try {
catch (std::exception&) {} PartMap = new PartitionMap::BuildMap();
} catch (std::exception &) {
}
} }
int Main(int argc, char **argv) { int Main(int argc, char **argv) {
@@ -98,7 +100,8 @@ int Main(int argc, char **argv) {
AppMain); AppMain);
FuncManager.registerFunction(std::make_unique<typeFunction>(), AppMain); FuncManager.registerFunction(std::make_unique<typeFunction>(), AppMain);
FuncManager.registerFunction(std::make_unique<rebootFunction>(), AppMain); FuncManager.registerFunction(std::make_unique<rebootFunction>(), AppMain);
// FuncManager.registerFunction(std::make_unique<memoryTestFunction>(), AppMain); // FuncManager.registerFunction(std::make_unique<memoryTestFunction>(),
// AppMain);
CLI11_PARSE(AppMain, argc, argv); CLI11_PARSE(AppMain, argc, argv);
@@ -116,7 +119,7 @@ int Main(int argc, char **argv) {
"(--search-path)"); "(--search-path)");
if (!Helper::hasSuperUser()) { if (!Helper::hasSuperUser()) {
if (!((FuncManager.isUsed("rebootFunction") || FuncManager.isUsed("memoryTestFunction")) && Helper::hasAdbPermissions())) if (!((FuncManager.isUsed("rebootFunction") /* || FuncManager.isUsed("memoryTestFunction") */) && Helper::hasAdbPermissions()))
throw Error( throw Error(
"Partition Manager Tool is requires super-user privileges!\n"); "Partition Manager Tool is requires super-user privileges!\n");
} }

View File

@@ -28,7 +28,8 @@
namespace PartitionManager { namespace PartitionManager {
pair backupFunction::runAsync(const std::string &partitionName, pair backupFunction::runAsync(const std::string &partitionName,
const std::string &outputName, const uint64_t bufferSize) { const std::string &outputName,
const uint64_t bufferSize) {
if (!Variables->PartMap->hasPartition(partitionName)) if (!Variables->PartMap->hasPartition(partitionName))
return {format("Couldn't find partition: %s", partitionName.data()), false}; return {format("Couldn't find partition: %s", partitionName.data()), false};
@@ -114,9 +115,10 @@ bool backupFunction::init(CLI::App &_app) {
cmd->add_option("-O,--output-directory", outputDirectory, cmd->add_option("-O,--output-directory", outputDirectory,
"Directory to save the partition image(s)") "Directory to save the partition image(s)")
->check(CLI::ExistingDirectory); ->check(CLI::ExistingDirectory);
cmd->add_option( cmd->add_option("-b,--buffer-size", bufferSize,
"-b,--buffer-size", bufferSize, "Buffer size for reading partition(s) and writing to file(s)")
"Buffer size for reading partition(s) and writing to file(s)")->transform(CLI::AsSizeValue(false))->default_val("4KB"); ->transform(CLI::AsSizeValue(false))
->default_val("4KB");
return true; return true;
} }

View File

@@ -25,7 +25,8 @@ Copyright 2025 Yağız Zengin
#define EFUN "eraseFunction" #define EFUN "eraseFunction"
namespace PartitionManager { namespace PartitionManager {
pair eraseFunction::runAsync(const std::string &partitionName, const uint64_t bufferSize) { pair eraseFunction::runAsync(const std::string &partitionName,
const uint64_t bufferSize) {
if (!Variables->PartMap->hasPartition(partitionName)) if (!Variables->PartMap->hasPartition(partitionName))
return {format("Couldn't find partition: %s", partitionName.data()), false}; return {format("Couldn't find partition: %s", partitionName.data()), false};
@@ -93,7 +94,9 @@ bool eraseFunction::init(CLI::App &_app) {
->required() ->required()
->delimiter(','); ->delimiter(',');
cmd->add_option("-b,--buffer-size", bufferSize, cmd->add_option("-b,--buffer-size", bufferSize,
"Buffer size for writing zero bytes to partition(s)")->transform(CLI::AsSizeValue(false))->default_val("4KB"); "Buffer size for writing zero bytes to partition(s)")
->transform(CLI::AsSizeValue(false))
->default_val("4KB");
return true; return true;
} }

View File

@@ -26,7 +26,8 @@ Copyright 2025 Yağız Zengin
namespace PartitionManager { namespace PartitionManager {
pair flashFunction::runAsync(const std::string &partitionName, pair flashFunction::runAsync(const std::string &partitionName,
const std::string &imageName, const uint64_t bufferSize) { const std::string &imageName,
const uint64_t bufferSize) {
if (!Helper::fileIsExists(imageName)) if (!Helper::fileIsExists(imageName))
return {format("Couldn't find image file: %s", imageName.data()), false}; return {format("Couldn't find image file: %s", imageName.data()), false};
if (!Variables->PartMap->hasPartition(partitionName)) if (!Variables->PartMap->hasPartition(partitionName))
@@ -100,7 +101,9 @@ bool flashFunction::init(CLI::App &_app) {
->required(); ->required();
cmd->add_option( cmd->add_option(
"-b,--buffer-size", bufferSize, "-b,--buffer-size", bufferSize,
"Buffer size for reading image(s) and writing to partition(s)")->transform(CLI::AsSizeValue(false))->default_val("4KB"); "Buffer size for reading image(s) and writing to partition(s)")
->transform(CLI::AsSizeValue(false))
->default_val("4KB");
cmd->add_option("-I,--image-directory", imageDirectory, cmd->add_option("-I,--image-directory", imageDirectory,
"Directory to find image(s) and flash to partition(s)"); "Directory to find image(s) and flash to partition(s)");

View File

@@ -36,13 +36,17 @@ bool infoFunction::init(CLI::App &_app) {
->delimiter(','); ->delimiter(',');
cmd->add_flag("-J,--json", jsonFormat, cmd->add_flag("-J,--json", jsonFormat,
"Print info(s) as JSON body. The body of each partition will " "Print info(s) as JSON body. The body of each partition will "
"be written separately")->default_val(false); "be written separately")
->default_val(false);
cmd->add_option("--json-partition-name", jNamePartition, cmd->add_option("--json-partition-name", jNamePartition,
"Speficy partition name element for JSON body")->default_val("name"); "Speficy partition name element for JSON body")
->default_val("name");
cmd->add_option("--json-size-name", jNameSize, cmd->add_option("--json-size-name", jNameSize,
"Speficy size element name for JSON body")->default_val("size"); "Speficy size element name for JSON body")
->default_val("size");
cmd->add_option("--json-logical-name", jNameLogical, cmd->add_option("--json-logical-name", jNameLogical,
"Speficy logical element name for JSON body")->default_val("isLogical"); "Speficy logical element name for JSON body")
->default_val("isLogical");
return true; return true;
} }

View File

@@ -14,38 +14,52 @@ Copyright 2025 Yağız Zengin
limitations under the License. limitations under the License.
*/ */
#include <chrono>
#include <random>
#include <fcntl.h>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include "functions.hpp" #include "functions.hpp"
#include <PartitionManager/PartitionManager.hpp> #include <PartitionManager/PartitionManager.hpp>
#include <chrono>
#include <cstdlib>
#include <cstring>
#include <fcntl.h>
#include <random>
#include <unistd.h>
#define MTFUN "memoryTestFunction" #define MTFUN "memoryTestFunction"
namespace PartitionManager { namespace PartitionManager {
bool memoryTestFunction::init(CLI::App &_app) { bool memoryTestFunction::init(CLI::App &_app) {
LOGN(MTFUN, INFO) << "Initializing variables of memory test function." << std::endl; LOGN(MTFUN, INFO) << "Initializing variables of memory test function."
<< std::endl;
cmd = _app.add_subcommand("memtest", "Test your write/read speed of device."); cmd = _app.add_subcommand("memtest", "Test your write/read speed of device.");
cmd->add_option("testDirectory", testPath, "Path to test directory")->default_val("/data/local/tmp")->check([&](const std::string &val) { cmd->add_option("testDirectory", testPath, "Path to test directory")
->default_val("/data/local/tmp")
->check([&](const std::string &val) {
if (val != "/data/local/tmp" && !Helper::directoryIsExists(val)) if (val != "/data/local/tmp" && !Helper::directoryIsExists(val))
return std::string("Couldn't find directory: " + val + ", no root? Try executing in ADB shell."); return std::string("Couldn't find directory: " + val +
", no root? Try executing in ADB shell.");
return std::string(); return std::string();
}); });
cmd->add_option("-b,--buffer-size", bufferSize, "Buffer size for reading partition(s) and writing to file(s)")->transform(CLI::AsSizeValue(false))->default_val("4MB"); cmd->add_option("-b,--buffer-size", bufferSize,
cmd->add_option("-s,--file-size", testFileSize, "File size of test file")->transform(CLI::AsSizeValue(false))->default_val("1GB"); "Buffer size for reading partition(s) and writing to file(s)")
cmd->add_flag("--no-write-test", doNotWriteTest, "Don't write test data to disk")->default_val(false); ->transform(CLI::AsSizeValue(false))
cmd->add_flag("--no-read-test", doNotReadTest, "Don't read test data from disk")->default_val(false); ->default_val("4MB");
cmd->add_option("-s,--file-size", testFileSize, "File size of test file")
->transform(CLI::AsSizeValue(false))
->default_val("1GB");
cmd->add_flag("--no-write-test", doNotWriteTest,
"Don't write test data to disk")
->default_val(false);
cmd->add_flag("--no-read-test", doNotReadTest,
"Don't read test data from disk")
->default_val(false);
return true; return true;
} }
bool memoryTestFunction::run() { bool memoryTestFunction::run() {
if (doNotReadTest && doNotWriteTest) if (doNotReadTest && doNotWriteTest)
throw Error("There must be at least one test transaction, but all of them are blocked"); throw Error("There must be at least one test transaction, but all of them "
"are blocked");
LOGN(MTFUN, INFO) << "Starting memory test on " << testPath << std::endl; LOGN(MTFUN, INFO) << "Starting memory test on " << testPath << std::endl;
Helper::garbageCollector collector; Helper::garbageCollector collector;
@@ -57,13 +71,16 @@ bool memoryTestFunction::run() {
std::mt19937 rng(std::random_device{}()); std::mt19937 rng(std::random_device{}());
std::uniform_int_distribution<int> dist(0, 255); std::uniform_int_distribution<int> dist(0, 255);
for (size_t i = 0; i < bufferSize; i++) buffer[i] = static_cast<char>(dist(rng)); for (size_t i = 0; i < bufferSize; i++)
buffer[i] = static_cast<char>(dist(rng));
if (!doNotWriteTest) { if (!doNotWriteTest) {
const int wfd = Helper::openAndAddToCloseList(test, collector, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, 0644); const int wfd = Helper::openAndAddToCloseList(
if (wfd < 0) throw Error("Can't open/create test file: %s", strerror(errno)); test, collector, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, 0644);
if (wfd < 0)
throw Error("Can't open/create test file: %s", strerror(errno));
LOGN(MTFUN, INFO) << "Write test started!" << std::endl; LOGN(MTFUN, INFO) << "Sequential write test started!" << std::endl;
const auto startWrite = std::chrono::high_resolution_clock::now(); const auto startWrite = std::chrono::high_resolution_clock::now();
ssize_t bytesWritten = 0; ssize_t bytesWritten = 0;
while (bytesWritten < testFileSize) { while (bytesWritten < testFileSize) {
@@ -73,23 +90,31 @@ bool memoryTestFunction::run() {
} }
const auto endWrite = std::chrono::high_resolution_clock::now(); const auto endWrite = std::chrono::high_resolution_clock::now();
const double writeTime = std::chrono::duration<double>(endWrite - startWrite).count(); const double writeTime =
println("Write speed: %f MB/s", (static_cast<double>(testFileSize) / (1024.0 * 1024.0)) / writeTime); std::chrono::duration<double>(endWrite - startWrite).count();
LOGN(MTFUN, INFO) << "Write test done!" << std::endl; println("Sequential write speed: %f MB/s",
(static_cast<double>(testFileSize) / (1024.0 * 1024.0)) /
writeTime);
LOGN(MTFUN, INFO) << "Sequential write test done!" << std::endl;
} }
if (!doNotReadTest) { if (!doNotReadTest) {
const int rfd = Helper::openAndAddToCloseList(test, collector, O_RDONLY | O_SYNC); const int rfd =
Helper::openAndAddToCloseList(test, collector, O_RDONLY | O_SYNC);
if (rfd < 0) throw Error("Can't open test file: %s", strerror(errno)); if (rfd < 0) throw Error("Can't open test file: %s", strerror(errno));
LOGN(MTFUN, INFO) << "Read test started!" << std::endl; LOGN(MTFUN, INFO) << "Sequential read test started!" << std::endl;
const auto startRead = std::chrono::high_resolution_clock::now(); const auto startRead = std::chrono::high_resolution_clock::now();
while (read(rfd, buffer, bufferSize) > 0) {} while (read(rfd, buffer, bufferSize) > 0) {
}
const auto endRead = std::chrono::high_resolution_clock::now(); const auto endRead = std::chrono::high_resolution_clock::now();
const double read_time = std::chrono::duration<double>(endRead - startRead).count(); const double read_time =
println("Read speed: %f MB/s", (static_cast<double>(testFileSize) / (1024.0 * 1024.0)) / read_time); std::chrono::duration<double>(endRead - startRead).count();
LOGN(MTFUN, INFO) << "Read test done!" << std::endl; println("Sequential read speed: %f MB/s",
(static_cast<double>(testFileSize) / (1024.0 * 1024.0)) /
read_time);
LOGN(MTFUN, INFO) << "Sequential read test done!" << std::endl;
} }
Helper::eraseEntry(test); Helper::eraseEntry(test);

View File

@@ -36,16 +36,21 @@ bool partitionSizeFunction::init(CLI::App &_app) {
->required() ->required()
->delimiter(','); ->delimiter(',');
cmd->add_flag("--as-byte", asByte, cmd->add_flag("--as-byte", asByte,
"Tell input size of partition list as byte.")->default_val(false); "Tell input size of partition list as byte.")
->default_val(false);
cmd->add_flag("--as-kilobyte", asKiloBytes, cmd->add_flag("--as-kilobyte", asKiloBytes,
"Tell input size of partition list as kilobyte.")->default_val(false); "Tell input size of partition list as kilobyte.")
->default_val(false);
cmd->add_flag("--as-megabyte", asMega, cmd->add_flag("--as-megabyte", asMega,
"Tell input size of partition list as megabyte.")->default_val(false); "Tell input size of partition list as megabyte.")
->default_val(false);
cmd->add_flag("--as-gigabyte", asGiga, cmd->add_flag("--as-gigabyte", asGiga,
"Tell input size of partition list as gigabyte.")->default_val(false); "Tell input size of partition list as gigabyte.")
->default_val(false);
cmd->add_flag("--only-size", onlySize, cmd->add_flag("--only-size", onlySize,
"Tell input size of partition list as not printing multiple " "Tell input size of partition list as not printing multiple "
"and partition name.")->default_val(false); "and partition name.")
->default_val(false);
return true; return true;
} }

View File

@@ -27,11 +27,15 @@ bool typeFunction::init(CLI::App &_app) {
->required() ->required()
->delimiter(','); ->delimiter(',');
cmd->add_option("-b,--buffer-size", bufferSize, cmd->add_option("-b,--buffer-size", bufferSize,
"Buffer size for max seek depth")->transform(CLI::AsSizeValue(false))->default_val("4KB"); "Buffer size for max seek depth")
->transform(CLI::AsSizeValue(false))
->default_val("4KB");
cmd->add_flag("--only-check-android-magics", onlyCheckAndroidMagics, cmd->add_flag("--only-check-android-magics", onlyCheckAndroidMagics,
"Only check Android magic values.")->default_val(false); "Only check Android magic values.")
->default_val(false);
cmd->add_flag("--only-check-filesystem-magics", onlyCheckFileSystemMagics, cmd->add_flag("--only-check-filesystem-magics", onlyCheckFileSystemMagics,
"Only check filesystem magic values.")->default_val(false); "Only check filesystem magic values.")
->default_val(false);
return true; return true;
} }

View File

@@ -251,9 +251,7 @@ bool basic_partition_map_builder::operator()(const std::string_view path) {
return readDirectory(path); return readDirectory(path);
} }
Map_t& basic_partition_map_builder::operator*() { Map_t &basic_partition_map_builder::operator*() { return _current_map; }
return _current_map;
}
const Map_t &basic_partition_map_builder::operator*() const { const Map_t &basic_partition_map_builder::operator*() const {
return _current_map; return _current_map;