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

@@ -40,14 +40,17 @@ std::vector<std::string> splitIfHasDelim(const std::string &s, const char delim,
}
void setupBufferSize(uint64_t &size, const std::string &entry) {
if (Variables->PartMap->hasPartition(entry) && Variables->PartMap->sizeOf(entry) % size != 0) {
println("%sWARNING%s: Specified buffer size is invalid for %s! Using different buffer size for %s.",
if (Variables->PartMap->hasPartition(entry) &&
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());
size = Variables->PartMap->sizeOf(entry) % 4096 == 0 ? 4096 : 1;
} else if (Helper::fileIsExists(entry)) {
if (Helper::fileSize(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());
println("%sWARNING%s: Specified buffer size is invalid for %s! using "
"different buffer size for %s.",
YELLOW, STYLE_RESET, entry.data(), entry.data());
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),
quietProcess(false), verboseMode(false), viewVersion(false),
forceProcess(false) {
try { PartMap = new PartitionMap::BuildMap(); }
catch (std::exception&) {}
try {
PartMap = new PartitionMap::BuildMap();
} catch (std::exception &) {
}
}
int Main(int argc, char **argv) {
@@ -98,7 +100,8 @@ int Main(int argc, char **argv) {
AppMain);
FuncManager.registerFunction(std::make_unique<typeFunction>(), 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);
@@ -116,7 +119,7 @@ int Main(int argc, char **argv) {
"(--search-path)");
if (!Helper::hasSuperUser()) {
if (!((FuncManager.isUsed("rebootFunction") || FuncManager.isUsed("memoryTestFunction")) && Helper::hasAdbPermissions()))
if (!((FuncManager.isUsed("rebootFunction") /* || FuncManager.isUsed("memoryTestFunction") */) && Helper::hasAdbPermissions()))
throw Error(
"Partition Manager Tool is requires super-user privileges!\n");
}

View File

@@ -28,7 +28,8 @@
namespace PartitionManager {
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))
return {format("Couldn't find partition: %s", partitionName.data()), false};
@@ -75,7 +76,7 @@ pair backupFunction::runAsync(const std::string &partitionName,
LOGN(BFUN, INFO) << "Writing partition " << partitionName
<< " to file: " << outputName << std::endl;
auto *buffer = new(std::nothrow) char[bufferSize];
auto *buffer = new (std::nothrow) char[bufferSize];
collector.delAfterProgress(buffer);
memset(buffer, 0x00, bufferSize);
@@ -114,9 +115,10 @@ bool backupFunction::init(CLI::App &_app) {
cmd->add_option("-O,--output-directory", outputDirectory,
"Directory to save the partition image(s)")
->check(CLI::ExistingDirectory);
cmd->add_option(
"-b,--buffer-size", bufferSize,
"Buffer size for reading partition(s) and writing to file(s)")->transform(CLI::AsSizeValue(false))->default_val("4KB");
cmd->add_option("-b,--buffer-size", bufferSize,
"Buffer size for reading partition(s) and writing to file(s)")
->transform(CLI::AsSizeValue(false))
->default_val("4KB");
return true;
}

View File

@@ -25,7 +25,8 @@ Copyright 2025 Yağız Zengin
#define EFUN "eraseFunction"
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))
return {format("Couldn't find partition: %s", partitionName.data()), false};
@@ -62,7 +63,7 @@ pair eraseFunction::runAsync(const std::string &partitionName, const uint64_t bu
LOGN(EFUN, INFO) << "Writing zero bytes to partition: " << partitionName
<< std::endl;
auto *buffer = new(std::nothrow) char[bufferSize];
auto *buffer = new (std::nothrow) char[bufferSize];
collector.delAfterProgress(buffer);
memset(buffer, 0x00, bufferSize);
@@ -93,7 +94,9 @@ bool eraseFunction::init(CLI::App &_app) {
->required()
->delimiter(',');
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;
}

View File

@@ -26,7 +26,8 @@ Copyright 2025 Yağız Zengin
namespace PartitionManager {
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))
return {format("Couldn't find image file: %s", imageName.data()), false};
if (!Variables->PartMap->hasPartition(partitionName))
@@ -73,7 +74,7 @@ pair flashFunction::runAsync(const std::string &partitionName,
LOGN(FFUN, INFO) << "Writing image " << imageName
<< " to partition: " << partitionName << std::endl;
auto *buffer = new(std::nothrow) char[bufferSize];
auto *buffer = new (std::nothrow) char[bufferSize];
collector.delAfterProgress(buffer);
memset(buffer, 0x00, bufferSize);
@@ -99,8 +100,10 @@ bool flashFunction::init(CLI::App &_app) {
cmd->add_option("imageFile(s)", rawImageNames, "Name(s) of image file(s)")
->required();
cmd->add_option(
"-b,--buffer-size", bufferSize,
"Buffer size for reading image(s) and writing to partition(s)")->transform(CLI::AsSizeValue(false))->default_val("4KB");
"-b,--buffer-size", bufferSize,
"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,
"Directory to find image(s) and flash to partition(s)");

View File

@@ -36,13 +36,17 @@ bool infoFunction::init(CLI::App &_app) {
->delimiter(',');
cmd->add_flag("-J,--json", jsonFormat,
"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,
"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,
"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,
"Speficy logical element name for JSON body")->default_val("isLogical");
"Speficy logical element name for JSON body")
->default_val("isLogical");
return true;
}

View File

@@ -5,7 +5,7 @@ Copyright 2025 Yağız Zengin
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,56 +14,73 @@ Copyright 2025 Yağız Zengin
limitations under the License.
*/
#include <chrono>
#include <random>
#include <fcntl.h>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include "functions.hpp"
#include <PartitionManager/PartitionManager.hpp>
#include <chrono>
#include <cstdlib>
#include <cstring>
#include <fcntl.h>
#include <random>
#include <unistd.h>
#define MTFUN "memoryTestFunction"
namespace PartitionManager {
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->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))
return std::string("Couldn't find directory: " + val + ", no root? Try executing in ADB shell.");
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("-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);
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))
return std::string("Couldn't find directory: " + val +
", no root? Try executing in ADB shell.");
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("-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;
}
bool memoryTestFunction::run() {
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;
Helper::garbageCollector collector;
const std::string test = testPath + "/test.bin";
LOGN(MTFUN, INFO) << "Generating random data for testing" << std::endl;
auto *buffer = new(std::nothrow) char[bufferSize];
auto *buffer = new (std::nothrow) char[bufferSize];
collector.delAfterProgress(buffer);
std::mt19937 rng(std::random_device{}());
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) {
const int wfd = Helper::openAndAddToCloseList(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));
const int wfd = Helper::openAndAddToCloseList(
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();
ssize_t bytesWritten = 0;
while (bytesWritten < testFileSize) {
@@ -73,23 +90,31 @@ bool memoryTestFunction::run() {
}
const auto endWrite = std::chrono::high_resolution_clock::now();
const double writeTime = std::chrono::duration<double>(endWrite - startWrite).count();
println("Write speed: %f MB/s", (static_cast<double>(testFileSize) / (1024.0 * 1024.0)) / writeTime);
LOGN(MTFUN, INFO) << "Write test done!" << std::endl;
const double writeTime =
std::chrono::duration<double>(endWrite - startWrite).count();
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) {
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));
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();
while (read(rfd, buffer, bufferSize) > 0) {}
while (read(rfd, buffer, bufferSize) > 0) {
}
const auto endRead = std::chrono::high_resolution_clock::now();
const double read_time = std::chrono::duration<double>(endRead - startRead).count();
println("Read speed: %f MB/s", (static_cast<double>(testFileSize) / (1024.0 * 1024.0)) / read_time);
LOGN(MTFUN, INFO) << "Read test done!" << std::endl;
const double read_time =
std::chrono::duration<double>(endRead - startRead).count();
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);

View File

@@ -36,16 +36,21 @@ bool partitionSizeFunction::init(CLI::App &_app) {
->required()
->delimiter(',');
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,
"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,
"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,
"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,
"Tell input size of partition list as not printing multiple "
"and partition name.")->default_val(false);
"and partition name.")
->default_val(false);
return true;
}

View File

@@ -27,11 +27,15 @@ bool typeFunction::init(CLI::App &_app) {
->required()
->delimiter(',');
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,
"Only check Android magic values.")->default_val(false);
"Only check Android magic values.")
->default_val(false);
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;
}