From 05c8ead94c1b303145a2d1402e5ac6ef21990af3 Mon Sep 17 00:00:00 2001 From: jiangqianrong Date: Thu, 19 Mar 2026 09:33:35 +0800 Subject: [PATCH 01/12] Add ohos fixparts func Signed-off-by: jiangqianrong --- BUILD.gn | 22 ++++ bundle.json | 3 + ohos/ohos_fixparts.cpp | 242 +++++++++++++++++++++++++++++++++++++++ ohos/ohos_fixparts.h | 53 +++++++++ ohos/ohos_mbr_helper.cpp | 187 ++++++++++++++++++++++++++++++ ohos/ohos_mbr_helper.h | 72 ++++++++++++ 6 files changed, 579 insertions(+) create mode 100644 ohos/ohos_fixparts.cpp create mode 100644 ohos/ohos_fixparts.h create mode 100644 ohos/ohos_mbr_helper.cpp create mode 100644 ohos/ohos_mbr_helper.h diff --git a/BUILD.gn b/BUILD.gn index 796246a..f1eb638 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -47,3 +47,25 @@ ohos_executable("sgdisk") { part_name = "gptfdisk" install_images = [ "system" ] } +ohos_executable("ohos_fixparts") { + install_enable = true + sources = [ + "ohos/ohos_fixparts.cpp", + "ohos/ohos_mbr_helper.cpp", + ] + sources += [ + "basicmbr.cc", + "crc32.cc", + "diskio-unix.cc", + "diskio.cc", + "mbrpart.cc", + "support.cc", + ] + public_configs = [ ":gptdisk_config" ] + external_deps = [ + "e2fsprogs:libext2_uuid", + ] + subsystem_name = "thirdparty" + part_name = "gptfdisk" + install_images = [ "system" ] +} \ No newline at end of file diff --git a/bundle.json b/bundle.json index 7125b0c..74b8bf5 100644 --- a/bundle.json +++ b/bundle.json @@ -35,6 +35,9 @@ "inner_kits": [ { "name": "//third_party/gptfdisk:sgdisk" + }, + { + "name": "//third_party/gptfdisk:ohos_fixparts" } ], "test": [] diff --git a/ohos/ohos_fixparts.cpp b/ohos/ohos_fixparts.cpp new file mode 100644 index 0000000..dd53be0 --- /dev/null +++ b/ohos/ohos_fixparts.cpp @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2026 Huawei Device Co., Ltd. + * + * 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 2 of the License, or + * (at your option) any later version. + */ + +#include "ohos_fixparts.h" +#include "../support.h" +#include "../basicmbr.h" +#include +#include +#include +#include +#include +#include + +OhosFixparts::OhosFixparts() { +} + +OhosFixparts::~OhosFixparts() { +} + +MbrResult OhosFixparts::ParseArgs(int argc, char* argv[], OhosFixpartsArgs& args) { + int opt; + int option_index = 0; + + static struct option long_options[] = { + {"print", no_argument, nullptr, 'p'}, + {"typecode", required_argument, nullptr, 't'}, + {"help", no_argument, nullptr, 'h'}, + {nullptr, 0, nullptr, 0} + }; + + while ((opt = getopt_long(argc, argv, "pt:h", long_options, &option_index)) != -1) { + switch (opt) { + case 'p': + args.printMBR = true; + break; + case 't': { + MbrResult result = ParseOption(optarg, args.partitionNum, args.typeCode); + if (result != MbrResult::SUCCESS) { + return result; + } + break; + } + case 'h': + args.showHelp = true; + ShowHelp(argv[0]); + return MbrResult::SUCCESS; + default: + ShowHelp(argv[0]); + return MbrResult::ERROR_UNKNOWN; + } + } + + // Parse device path (remaining argument) + if (optind < argc) { + args.device = argv[optind]; + } + + // Check for extra arguments (should be exactly one device path) + if (optind + 1 < argc) { + std::cerr << "Error: Too many device paths specified" << std::endl; + ShowHelp(argv[0]); + return MbrResult::ERROR_INVALID_DEVICE; + } + + // Validate device path + if (args.device.empty()) { + std::cerr << "Device path is required" << std::endl; + ShowHelp(argv[0]); + return MbrResult::ERROR_INVALID_DEVICE; + } + + return MbrResult::SUCCESS; +} + +MbrResult OhosFixparts::ParseOption(const std::string& option, int& partitionNum, uint8_t& typeCode) { + + // Parse partition number and type code + std::string paramStr = option; + size_t colonPos = paramStr.find(':'); + + if (colonPos == std::string::npos || colonPos == 0 || colonPos == paramStr.length() - 1) { + std::cerr << "Invalid option format (expected partnum:typecode)" << std::endl; + return MbrResult::ERROR_INVALID_PARTITION; + } + + std::string partNumStr = paramStr.substr(0, colonPos); + std::string typeCodeStr = paramStr.substr(colonPos + 1); + + // Validate partition number - manual validation without exceptions + if (partNumStr.empty()) { + std::cerr << "Invalid partition number (must be a number)" << std::endl; + return MbrResult::ERROR_INVALID_PARTITION; + } + + // Check if all characters are digits + for (char c : partNumStr) { + if (!isdigit(c)) { + std::cerr << "Invalid partition number (must be a pure number)" << std::endl; + return MbrResult::ERROR_INVALID_PARTITION; + } + } + + // Convert to integer (safe because we validated all characters are digits) + std::istringstream iss(partNumStr); + iss >> partitionNum; + + if (iss.fail() || !iss.eof()) { + std::cerr << "Invalid partition number (must be a number)" << std::endl; + return MbrResult::ERROR_INVALID_PARTITION; + } + + if (partitionNum < 1 || partitionNum > 128) { + std::cerr << "Invalid partition number (must be 1-128)" << std::endl; + return MbrResult::ERROR_INVALID_PARTITION; + } + + // Validate and parse type code + if (!ParseTypeCode(typeCodeStr, typeCode)) { + std::cerr << "Invalid type code (must be 0x01-0xFF)" << std::endl; + return MbrResult::ERROR_INVALID_TYPECODE; + } + + return MbrResult::SUCCESS; +} + +bool OhosFixparts::ParseTypeCode(const std::string& str, uint8_t& code) { + std::istringstream iss(str); + int value; + + // Check if string starts with 0x/0X or contains only hex digits + bool isHex = false; + if (str.find("0x") == 0 || str.find("0X") == 0) { + isHex = true; + } else { + // Check if all characters are valid hex digits (0-9, a-f, A-F) + for (char c : str) { + if (!isxdigit(c)) { + isHex = false; + break; + } + isHex = true; + } + } + + if (isHex) { + iss >> std::hex >> value; + } else { + iss >> std::dec >> value; + } + + if (iss.fail()) { + return false; + } + + // Validate range before conversion to prevent truncation + if (value < 0x01 || value > 0xFF) { + return false; + } + + code = static_cast(value); + return true; +} + +int OhosFixparts::Run(const OhosFixpartsArgs& args) { + MbrResult result = helper_.LoadMbrData(args.device); + if (result != MbrResult::SUCCESS) { + std::cerr << "Failed to load MBR data: " << helper_.GetLastError() << std::endl; + return static_cast(result); + } + + // Print mode: display MBR partition table + if (args.printMBR) { + helper_.DisplayMBRData(); + return 0; + } + + // Modify mode: change partition type code + std::cout << "Changing partition " << args.partitionNum + << " type code to 0x" << std::hex + << static_cast(args.typeCode) << std::dec << std::endl; + + result = helper_.ChangePartitionType(args.partitionNum, args.typeCode); + if (result != MbrResult::SUCCESS) { + std::cerr << "Failed to change partition type: " << helper_.GetLastError() << std::endl; + return static_cast(result); + } + + result = helper_.SaveMbrData(); + if (result != MbrResult::SUCCESS) { + std::cerr << "Failed to save MBR data: " << helper_.GetLastError() << std::endl; + return static_cast(result); + } + + std::cout << "Partition type code changed successfully." << std::endl; + return 0; +} + +void OhosFixparts::ShowHelp(const char* programName) { + std::cout << "MBR Partition Type Code Modify" << std::endl; + std::cout << std::endl; + std::cout << "Usage (Print Mode):" << std::endl; + std::cout << " " << programName << " -p " << std::endl; + std::cout << " " << programName << " --print " << std::endl; + std::cout << std::endl; + std::cout << "Usage (Modify Mode):" << std::endl; + std::cout << " " << programName << " -t partnum:typecode " << std::endl; + std::cout << " " << programName << " --typecode partnum:typecode " << std::endl; + std::cout << std::endl; + std::cout << "Options:" << std::endl; + std::cout << " -p, --print Print MBR partition table" << std::endl; + std::cout << " -t partnum:typecode Change partition type code" << std::endl; + std::cout << " -h, --help Show this help message" << std::endl; + std::cout << std::endl; + std::cout << "Examples:" << std::endl; + std::cout << " " << programName << " -p /dev/sda" << std::endl; + std::cout << " " << programName << " -t 1:0x07 /dev/sda" << std::endl; + std::cout << " " << programName << " -t 2:0x83 /dev/sda" << std::endl; + std::cout << std::endl; +} + +int main(int argc, char* argv[]) { + OhosFixparts fixparts; + OhosFixpartsArgs args; + + MbrResult result = fixparts.ParseArgs(argc, argv, args); + if (result != MbrResult::SUCCESS) { + return static_cast(result); + } + + // If help was requested, exit successfully + if (args.showHelp) { + return 0; + } + + return fixparts.Run(args); +} \ No newline at end of file diff --git a/ohos/ohos_fixparts.h b/ohos/ohos_fixparts.h new file mode 100644 index 0000000..a1e5aae --- /dev/null +++ b/ohos/ohos_fixparts.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2026 Huawei Device Co., Ltd. + * + * 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 2 of the License, or + * (at your option) any later version. + */ + +#ifndef OHOS_FIXPARTS_H +#define OHOS_FIXPARTS_H + +#include "ohos_mbr_helper.h" +#include + +// Command line arguments structure +struct OhosFixpartsArgs { + std::string device; // Device path + bool printMBR; // Print MBR partition table + bool showHelp; // Show help information + int partitionNum; // Partition number + uint8_t typeCode; // Type code + + OhosFixpartsArgs() + : printMBR(false), showHelp(false), partitionNum(-1), typeCode(0) {} +}; + +// Main program class +class OhosFixparts { +public: + OhosFixparts(); + ~OhosFixparts(); + + // Parse command line arguments + MbrResult ParseArgs(int argc, char* argv[], OhosFixpartsArgs& args); + + // Execute partition type code modification + int Run(const OhosFixpartsArgs& args); + + // Show help information + void ShowHelp(const char* programName); + +private: + OhosMbrHelper helper_; + + // Parse hexadecimal type code + bool ParseTypeCode(const std::string& str, uint8_t& code); + + // Parse option string (format: partnum:typecode) and validate all parameters + MbrResult ParseOption(const std::string& option, int& partitionNum, uint8_t& typeCode); +}; + +#endif // OHOS_FIXPARTS_H \ No newline at end of file diff --git a/ohos/ohos_mbr_helper.cpp b/ohos/ohos_mbr_helper.cpp new file mode 100644 index 0000000..422889b --- /dev/null +++ b/ohos/ohos_mbr_helper.cpp @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2026 Huawei Device Co., Ltd. + * + * 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 2 of the License, or + * (at your option) any later version. + */ + +#include "ohos_mbr_helper.h" +#include "../basicmbr.h" +#include +#include +#include + +OhosMbrHelper::OhosMbrHelper() + : mbrData_(nullptr), loaded_(false) { + mbrData_ = new BasicMBRData(); +} + +OhosMbrHelper::~OhosMbrHelper() { + if (mbrData_ != nullptr) { + delete static_cast(mbrData_); + mbrData_ = nullptr; + } +} + +MbrResult OhosMbrHelper::LoadMbrData(const std::string& device) { + MbrResult result = ValidateDevice(device); + if (result != MbrResult::SUCCESS) { + return result; + } + + device_ = device; + result = ReadMbrFromDevice(); + if (result != MbrResult::SUCCESS) { + return result; + } + + result = ValidateMbrData(); + if (result != MbrResult::SUCCESS) { + return result; + } + + BasicMBRData* mbr = static_cast(mbrData_); + mbr->MakeItLegal(); + loaded_ = true; + + return MbrResult::SUCCESS; +} + +MbrResult OhosMbrHelper::ValidateDevice(const std::string& device) { + if (device.empty()) { + SetError("Device path is empty"); + return MbrResult::ERROR_INVALID_DEVICE; + } + return MbrResult::SUCCESS; +} + +MbrResult OhosMbrHelper::ReadMbrFromDevice() { + BasicMBRData* mbr = static_cast(mbrData_); + + if (!mbr->ReadMBRData(device_)) { + SetError("Failed to read MBR data from device: " + device_); + return MbrResult::ERROR_READ_FAILED; + } + + return MbrResult::SUCCESS; +} + +MbrResult OhosMbrHelper::ValidateMbrData() { + BasicMBRData* mbr = static_cast(mbrData_); + MBRValidity validity = mbr->GetValidity(); + + if (validity == gpt || validity == hybrid) { + SetError("Device appears to be a GPT disk, not MBR"); + return MbrResult::ERROR_GPT_DISK; + } + + if (validity == invalid) { + SetError("Invalid MBR data on device"); + return MbrResult::ERROR_NOT_MBR_DISK; + } + + return MbrResult::SUCCESS; +} + +MbrResult OhosMbrHelper::ChangePartitionType(int partNum, uint8_t typeCode) { + // Check if MBR data is loaded + if (!loaded_) { + SetError("MBR data not loaded. Call LoadMbrData() first."); + return MbrResult::ERROR_READ_FAILED; + } + + // Validate partition number range (1-128) + if (partNum < 1 || partNum > 128) { + std::ostringstream oss; + oss << "Invalid partition number " << partNum << " (must be 1-128)"; + SetError(oss.str()); + return MbrResult::ERROR_INVALID_PARTITION; + } + + // Validate range before conversion to prevent truncation + if (typeCode < 0x01 || typeCode > 0xFF) { + std::ostringstream oss; + oss << "Invalid typecode " << typeCode << " (must be 0x01 - 0xFF)"; + SetError(oss.str()); + return MbrResult::ERROR_INVALID_TYPECODE; + } + + BasicMBRData* mbr = static_cast(mbrData_); + + // Check if partition exists and is not empty + if (mbr->GetLength(partNum - 1) == 0) { + std::ostringstream oss; + oss << "Partition " << partNum << " is empty or does not exist"; + SetError(oss.str()); + return MbrResult::ERROR_EMPTY_PARTITION; + } + + // Set partition type code + int result = mbr->SetPartType(partNum - 1, typeCode); + if (result == 0) { + std::ostringstream oss; + oss << "Failed to set type code for partition " << partNum; + SetError(oss.str()); + return MbrResult::ERROR_UNKNOWN; + } + + return MbrResult::SUCCESS; +} + +MbrResult OhosMbrHelper::SaveMbrData() { + if (!loaded_) { + SetError("MBR data not loaded. Call LoadMbrData() first."); + return MbrResult::ERROR_READ_FAILED; + } + + BasicMBRData* mbr = static_cast(mbrData_); + + if (!mbr->WriteMBRData()) { + SetError("Failed to write MBR data to device: " + device_); + return MbrResult::ERROR_WRITE_FAILED; + } + + mbr->DiskSync(); + return MbrResult::SUCCESS; +} + +std::string OhosMbrHelper::GetLastError() const { + return lastError_; +} + +void OhosMbrHelper::DisplayMBRData() { + if (!loaded_) { + std::cerr << "MBR data not loaded. Call LoadMbrData() first." << std::endl; + return; + } + + BasicMBRData* mbr = static_cast(mbrData_); + + std::cout << "MBR Partition Table:" << std::endl; + std::cout << " # Boot Start Sector End Sector Type Code Size" << std::endl; + + for (int i = 0; i < 4; i++) { + uint64_t length = mbr->GetLength(i); + if (length > 0) { + uint8_t status = mbr->GetStatus(i); + uint8_t typeCode = mbr->GetType(i); + uint64_t firstSector = mbr->GetFirstSector(i); + + std::cout << " " << (i + 1) << " "; + std::cout << (status == 0x80 ? " * " : " "); + std::cout << std::setw(12) << firstSector << " "; + std::cout << std::setw(12) << (firstSector + length - 1) << " "; + std::cout << "0x" << std::setfill('0') << std::setw(2) + << std::hex << static_cast(typeCode) << std::dec; + std::cout << std::setfill(' ') << " "; + std::cout << (length * 512 / (1024 * 1024)) << " MB" << std::endl; + } + } +} + +void OhosMbrHelper::SetError(const std::string& error) { + lastError_ = error; + std::cerr << error << std::endl; +} \ No newline at end of file diff --git a/ohos/ohos_mbr_helper.h b/ohos/ohos_mbr_helper.h new file mode 100644 index 0000000..d9fcfc6 --- /dev/null +++ b/ohos/ohos_mbr_helper.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2026 Huawei Device Co., Ltd. + * + * 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 2 of the License, or + * (at your option) any later version. + */ + +#ifndef OHOS_MBR_HELPER_H +#define OHOS_MBR_HELPER_H + +#include +#include + +// MBR operation result codes +enum class MbrResult { + SUCCESS = 0, + ERROR_INVALID_DEVICE = 1, + ERROR_READ_FAILED = 2, + ERROR_WRITE_FAILED = 3, + ERROR_INVALID_PARTITION = 4, + ERROR_INVALID_TYPECODE = 5, + ERROR_NOT_MBR_DISK = 6, + ERROR_GPT_DISK = 7, + ERROR_EMPTY_PARTITION = 8, + ERROR_UNKNOWN = 100 +}; + +// MBR partition type code modifier class +class OhosMbrHelper { +public: + OhosMbrHelper(); + ~OhosMbrHelper(); + + // Load MBR data + MbrResult LoadMbrData(const std::string& device); + + // Validate device path + MbrResult ValidateDevice(const std::string& device); + + // Read MBR data from device + MbrResult ReadMbrFromDevice(); + + // Validate MBR data + MbrResult ValidateMbrData(); + + // Change partition type code + // partNum: Partition number (1-128) + // typeCode: Type code (0x01-0xFF) + MbrResult ChangePartitionType(int partNum, uint8_t typeCode); + + // Save MBR data to disk + MbrResult SaveMbrData(); + + // Display MBR partition table + void DisplayMBRData(); + + // Get error message + std::string GetLastError() const; + +private: + void* mbrData_; // BasicMBRData object pointer + std::string lastError_; + std::string device_; + bool loaded_; + + // Set error message + void SetError(const std::string& error); +}; + +#endif // OHOS_MBR_HELPER_H \ No newline at end of file From 587e33f21d40444bd3a2013a4f91bae67c8cb092 Mon Sep 17 00:00:00 2001 From: jiangqianrong Date: Thu, 19 Mar 2026 15:02:27 +0800 Subject: [PATCH 02/12] =?UTF-8?q?update:=20=E6=9B=B4=E6=96=B0=E6=96=87?= =?UTF-8?q?=E4=BB=B6=20bundle.json?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: jiangqianrong --- bundle.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bundle.json b/bundle.json index 74b8bf5..07d6304 100644 --- a/bundle.json +++ b/bundle.json @@ -31,7 +31,9 @@ "third_party": [] }, "build": { - "sub_component": [], + "sub_component": [ + "//third_party/gptfdisk:ohos_fixparts" + ], "inner_kits": [ { "name": "//third_party/gptfdisk:sgdisk" From 90b9a0794cec5c572f863b7e6a5f6211c3c08407 Mon Sep 17 00:00:00 2001 From: jiangqianrong Date: Fri, 20 Mar 2026 11:57:34 +0800 Subject: [PATCH 03/12] =?UTF-8?q?update:=20=E6=9B=B4=E6=96=B0=E6=96=87?= =?UTF-8?q?=E4=BB=B6=20BUILD.gn?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: jiangqianrong --- BUILD.gn | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/BUILD.gn b/BUILD.gn index f1eb638..b63e22c 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -47,12 +47,15 @@ ohos_executable("sgdisk") { part_name = "gptfdisk" install_images = [ "system" ] } + ohos_executable("ohos_fixparts") { install_enable = true + sources = [ "ohos/ohos_fixparts.cpp", "ohos/ohos_mbr_helper.cpp", ] + sources += [ "basicmbr.cc", "crc32.cc", @@ -61,11 +64,12 @@ ohos_executable("ohos_fixparts") { "mbrpart.cc", "support.cc", ] + public_configs = [ ":gptdisk_config" ] - external_deps = [ - "e2fsprogs:libext2_uuid", - ] + + external_deps = [ "e2fsprogs:libext2_uuid" ] + subsystem_name = "thirdparty" part_name = "gptfdisk" install_images = [ "system" ] -} \ No newline at end of file +} From c15d923f9a7b34a33f87313c1f149e641d66173a Mon Sep 17 00:00:00 2001 From: jiangqianrong Date: Fri, 20 Mar 2026 11:58:05 +0800 Subject: [PATCH 04/12] =?UTF-8?q?update:=20=E6=9B=B4=E6=96=B0=E6=96=87?= =?UTF-8?q?=E4=BB=B6=20ohos=5Ffixparts.cpp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: jiangqianrong --- ohos/ohos_fixparts.cpp | 160 +++++++++++++++++++---------------------- 1 file changed, 73 insertions(+), 87 deletions(-) diff --git a/ohos/ohos_fixparts.cpp b/ohos/ohos_fixparts.cpp index dd53be0..50dce24 100644 --- a/ohos/ohos_fixparts.cpp +++ b/ohos/ohos_fixparts.cpp @@ -8,31 +8,28 @@ */ #include "ohos_fixparts.h" -#include "../support.h" #include "../basicmbr.h" -#include -#include -#include +#include "../support.h" #include -#include #include +#include +#include +#include +#include -OhosFixparts::OhosFixparts() { -} +OhosFixparts::OhosFixparts() {} -OhosFixparts::~OhosFixparts() { -} +OhosFixparts::~OhosFixparts() {} -MbrResult OhosFixparts::ParseArgs(int argc, char* argv[], OhosFixpartsArgs& args) { +MbrResult OhosFixparts::ParseArgs(int argc, char *argv[], OhosFixpartsArgs &args) +{ int opt; int option_index = 0; - static struct option long_options[] = { - {"print", no_argument, nullptr, 'p'}, - {"typecode", required_argument, nullptr, 't'}, - {"help", no_argument, nullptr, 'h'}, - {nullptr, 0, nullptr, 0} - }; + static struct option long_options[] = {{"print", no_argument, nullptr, 'p'}, + {"typecode", required_argument, nullptr, 't'}, + {"help", no_argument, nullptr, 'h'}, + {nullptr, 0, nullptr, 0}}; while ((opt = getopt_long(argc, argv, "pt:h", long_options, &option_index)) != -1) { switch (opt) { @@ -78,88 +75,90 @@ MbrResult OhosFixparts::ParseArgs(int argc, char* argv[], OhosFixpartsArgs& args return MbrResult::SUCCESS; } -MbrResult OhosFixparts::ParseOption(const std::string& option, int& partitionNum, uint8_t& typeCode) { +MbrResult OhosFixparts::ParseOption(const std::string &option, int &partitionNum, uint8_t &typeCode) +{ // Parse partition number and type code std::string paramStr = option; size_t colonPos = paramStr.find(':'); if (colonPos == std::string::npos || colonPos == 0 || colonPos == paramStr.length() - 1) { - std::cerr << "Invalid option format (expected partnum:typecode)" << std::endl; + std::cerr << "Invalid option format(expected partnum:typecode): "<< option.c_str() << std::endl; return MbrResult::ERROR_INVALID_PARTITION; } std::string partNumStr = paramStr.substr(0, colonPos); std::string typeCodeStr = paramStr.substr(colonPos + 1); - // Validate partition number - manual validation without exceptions - if (partNumStr.empty()) { - std::cerr << "Invalid partition number (must be a number)" << std::endl; - return MbrResult::ERROR_INVALID_PARTITION; - } - - // Check if all characters are digits - for (char c : partNumStr) { - if (!isdigit(c)) { - std::cerr << "Invalid partition number (must be a pure number)" << std::endl; - return MbrResult::ERROR_INVALID_PARTITION; - } - } - - // Convert to integer (safe because we validated all characters are digits) - std::istringstream iss(partNumStr); - iss >> partitionNum; - - if (iss.fail() || !iss.eof()) { - std::cerr << "Invalid partition number (must be a number)" << std::endl; - return MbrResult::ERROR_INVALID_PARTITION; - } - - if (partitionNum < 1 || partitionNum > 128) { - std::cerr << "Invalid partition number (must be 1-128)" << std::endl; - return MbrResult::ERROR_INVALID_PARTITION; + MbrResult result = ParsePartNum(partNumStr, partitionNum); + if (result != MbrResult::SUCCESS) { + return result; } // Validate and parse type code if (!ParseTypeCode(typeCodeStr, typeCode)) { - std::cerr << "Invalid type code (must be 0x01-0xFF)" << std::endl; return MbrResult::ERROR_INVALID_TYPECODE; } return MbrResult::SUCCESS; } -bool OhosFixparts::ParseTypeCode(const std::string& str, uint8_t& code) { - std::istringstream iss(str); - int value; +MbrResult OhosFixparts::ParsePartNum(const std::string &str, int &partitionNum) +{ + // Validate partition number - manual validation without exceptions + if (str.empty()) { + std::cerr << "Invalid partition number: NULL" << std::endl; + return MbrResult::ERROR_INVALID_PARTITION; + } - // Check if string starts with 0x/0X or contains only hex digits - bool isHex = false; - if (str.find("0x") == 0 || str.find("0X") == 0) { - isHex = true; - } else { - // Check if all characters are valid hex digits (0-9, a-f, A-F) - for (char c : str) { - if (!isxdigit(c)) { - isHex = false; - break; - } - isHex = true; + // Check if all characters are digits + for (char c : str) { + if (!isdigit(c)) { + std::cerr << "Invalid partition number(must be a pure number): " << c << std::endl; + return MbrResult::ERROR_INVALID_PARTITION; } } - if (isHex) { - iss >> std::hex >> value; - } else { - iss >> std::dec >> value; + // Convert to integer (safe because we validated all characters are digits) + std::istringstream iss(str); + iss >> partitionNum; + + if (iss.fail() || !iss.eof()) { + std::cerr << "Parse partNum fail: " << std::to_string(iss.fail()) << "/" + << std::to_string(iss.eof()) << " str: " << str.c_str() << std::endl; + return MbrResult::ERROR_INVALID_PARTITION; } - if (iss.fail()) { + if (partitionNum < MIN_MBR_PARTS || partitionNum > MAX_MBR_PARTS) { + std::cerr << "Invalid partition number(must be 1-128): " << str.c_str() << std::endl; + return MbrResult::ERROR_INVALID_PARTITION; + } + + return MbrResult::SUCCESS; +} + +bool OhosFixparts::ParseTypeCode(const std::string &str, uint8_t &code) +{ + int value; + + if (!IsHex(str)) { + std::cerr << "Invalid hex format: " << str.c_str() << std::endl; + return false; + } + + // Parse hex value + std::istringstream iss(str); + iss >> std::hex >> value; + + if (iss.fail() || !iss.eof()) { + std::cerr << "Parse typecode fail: " << std::to_string(iss.fail()) << "/" + << std::to_string(iss.eof()) << " str: " << str.c_str() << std::endl; return false; } // Validate range before conversion to prevent truncation if (value < 0x01 || value > 0xFF) { + std::cerr << "Invalid type code(must be 0x01-0xFF): " << value << std::endl; return false; } @@ -167,7 +166,8 @@ bool OhosFixparts::ParseTypeCode(const std::string& str, uint8_t& code) { return true; } -int OhosFixparts::Run(const OhosFixpartsArgs& args) { +int OhosFixparts::Run(const OhosFixpartsArgs &args) +{ MbrResult result = helper_.LoadMbrData(args.device); if (result != MbrResult::SUCCESS) { std::cerr << "Failed to load MBR data: " << helper_.GetLastError() << std::endl; @@ -181,8 +181,7 @@ int OhosFixparts::Run(const OhosFixpartsArgs& args) { } // Modify mode: change partition type code - std::cout << "Changing partition " << args.partitionNum - << " type code to 0x" << std::hex + std::cout << "Changing partition " << args.partitionNum << " type code to 0x" << std::hex << static_cast(args.typeCode) << std::dec << std::endl; result = helper_.ChangePartitionType(args.partitionNum, args.typeCode); @@ -201,30 +200,17 @@ int OhosFixparts::Run(const OhosFixpartsArgs& args) { return 0; } -void OhosFixparts::ShowHelp(const char* programName) { - std::cout << "MBR Partition Type Code Modify" << std::endl; - std::cout << std::endl; - std::cout << "Usage (Print Mode):" << std::endl; - std::cout << " " << programName << " -p " << std::endl; - std::cout << " " << programName << " --print " << std::endl; - std::cout << std::endl; - std::cout << "Usage (Modify Mode):" << std::endl; - std::cout << " " << programName << " -t partnum:typecode " << std::endl; - std::cout << " " << programName << " --typecode partnum:typecode " << std::endl; - std::cout << std::endl; - std::cout << "Options:" << std::endl; +void OhosFixparts::ShowHelp(const char *programName) +{ + std::cout << "Usage : " << programName << " [OPTION...] " << std::endl; std::cout << " -p, --print Print MBR partition table" << std::endl; std::cout << " -t partnum:typecode Change partition type code" << std::endl; std::cout << " -h, --help Show this help message" << std::endl; std::cout << std::endl; - std::cout << "Examples:" << std::endl; - std::cout << " " << programName << " -p /dev/sda" << std::endl; - std::cout << " " << programName << " -t 1:0x07 /dev/sda" << std::endl; - std::cout << " " << programName << " -t 2:0x83 /dev/sda" << std::endl; - std::cout << std::endl; } -int main(int argc, char* argv[]) { +int main(int argc, char *argv[]) +{ OhosFixparts fixparts; OhosFixpartsArgs args; @@ -239,4 +225,4 @@ int main(int argc, char* argv[]) { } return fixparts.Run(args); -} \ No newline at end of file +} From 09b801a1ad378a98a567376c6a1c96937d7b8778 Mon Sep 17 00:00:00 2001 From: jiangqianrong Date: Fri, 20 Mar 2026 11:59:24 +0800 Subject: [PATCH 05/12] =?UTF-8?q?update:=20=E6=9B=B4=E6=96=B0=E6=96=87?= =?UTF-8?q?=E4=BB=B6=20ohos=5Ffixparts.h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: jiangqianrong --- ohos/ohos_fixparts.h | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/ohos/ohos_fixparts.h b/ohos/ohos_fixparts.h index a1e5aae..bfd77f7 100644 --- a/ohos/ohos_fixparts.h +++ b/ohos/ohos_fixparts.h @@ -15,14 +15,13 @@ // Command line arguments structure struct OhosFixpartsArgs { - std::string device; // Device path - bool printMBR; // Print MBR partition table - bool showHelp; // Show help information - int partitionNum; // Partition number - uint8_t typeCode; // Type code + std::string device; // Device path + bool printMBR; // Print MBR partition table + bool showHelp; // Show help information + int partitionNum; // Partition number + uint8_t typeCode; // Type code - OhosFixpartsArgs() - : printMBR(false), showHelp(false), partitionNum(-1), typeCode(0) {} + OhosFixpartsArgs() : printMBR(false), showHelp(false), partitionNum(-1), typeCode(0) {} }; // Main program class @@ -32,22 +31,25 @@ public: ~OhosFixparts(); // Parse command line arguments - MbrResult ParseArgs(int argc, char* argv[], OhosFixpartsArgs& args); + MbrResult ParseArgs(int argc, char *argv[], OhosFixpartsArgs &args); // Execute partition type code modification - int Run(const OhosFixpartsArgs& args); + int Run(const OhosFixpartsArgs &args); // Show help information - void ShowHelp(const char* programName); + void ShowHelp(const char *programName); private: OhosMbrHelper helper_; // Parse hexadecimal type code - bool ParseTypeCode(const std::string& str, uint8_t& code); + bool ParseTypeCode(const std::string &str, uint8_t &code); + + // Parse partnumber + MbrResult ParsePartNum(const std::string &str, int &partitionNum); // Parse option string (format: partnum:typecode) and validate all parameters - MbrResult ParseOption(const std::string& option, int& partitionNum, uint8_t& typeCode); + MbrResult ParseOption(const std::string &option, int &partitionNum, uint8_t &typeCode); }; -#endif // OHOS_FIXPARTS_H \ No newline at end of file +#endif // OHOS_FIXPARTS_H From da16babec0f5617a80cd3d8b4b7ada684c57f6d0 Mon Sep 17 00:00:00 2001 From: jiangqianrong Date: Fri, 20 Mar 2026 11:59:52 +0800 Subject: [PATCH 06/12] =?UTF-8?q?update:=20=E6=9B=B4=E6=96=B0=E6=96=87?= =?UTF-8?q?=E4=BB=B6=20ohos=5Fmbr=5Fhelper.cpp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: jiangqianrong --- ohos/ohos_mbr_helper.cpp | 75 ++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 42 deletions(-) diff --git a/ohos/ohos_mbr_helper.cpp b/ohos/ohos_mbr_helper.cpp index 422889b..91a0819 100644 --- a/ohos/ohos_mbr_helper.cpp +++ b/ohos/ohos_mbr_helper.cpp @@ -9,23 +9,25 @@ #include "ohos_mbr_helper.h" #include "../basicmbr.h" +#include #include #include -#include -OhosMbrHelper::OhosMbrHelper() - : mbrData_(nullptr), loaded_(false) { +OhosMbrHelper::OhosMbrHelper() : mbrData_(nullptr), loaded_(false) +{ mbrData_ = new BasicMBRData(); } -OhosMbrHelper::~OhosMbrHelper() { +OhosMbrHelper::~OhosMbrHelper() +{ if (mbrData_ != nullptr) { - delete static_cast(mbrData_); + delete static_cast(mbrData_); mbrData_ = nullptr; } } -MbrResult OhosMbrHelper::LoadMbrData(const std::string& device) { +MbrResult OhosMbrHelper::LoadMbrData(const std::string &device) +{ MbrResult result = ValidateDevice(device); if (result != MbrResult::SUCCESS) { return result; @@ -42,14 +44,15 @@ MbrResult OhosMbrHelper::LoadMbrData(const std::string& device) { return result; } - BasicMBRData* mbr = static_cast(mbrData_); + BasicMBRData *mbr = static_cast(mbrData_); mbr->MakeItLegal(); loaded_ = true; return MbrResult::SUCCESS; } -MbrResult OhosMbrHelper::ValidateDevice(const std::string& device) { +MbrResult OhosMbrHelper::ValidateDevice(const std::string &device) +{ if (device.empty()) { SetError("Device path is empty"); return MbrResult::ERROR_INVALID_DEVICE; @@ -57,8 +60,9 @@ MbrResult OhosMbrHelper::ValidateDevice(const std::string& device) { return MbrResult::SUCCESS; } -MbrResult OhosMbrHelper::ReadMbrFromDevice() { - BasicMBRData* mbr = static_cast(mbrData_); +MbrResult OhosMbrHelper::ReadMbrFromDevice() +{ + BasicMBRData *mbr = static_cast(mbrData_); if (!mbr->ReadMBRData(device_)) { SetError("Failed to read MBR data from device: " + device_); @@ -68,8 +72,9 @@ MbrResult OhosMbrHelper::ReadMbrFromDevice() { return MbrResult::SUCCESS; } -MbrResult OhosMbrHelper::ValidateMbrData() { - BasicMBRData* mbr = static_cast(mbrData_); +MbrResult OhosMbrHelper::ValidateMbrData() +{ + BasicMBRData *mbr = static_cast(mbrData_); MBRValidity validity = mbr->GetValidity(); if (validity == gpt || validity == hybrid) { @@ -85,7 +90,8 @@ MbrResult OhosMbrHelper::ValidateMbrData() { return MbrResult::SUCCESS; } -MbrResult OhosMbrHelper::ChangePartitionType(int partNum, uint8_t typeCode) { +MbrResult OhosMbrHelper::ChangePartitionType(int partNum, uint8_t typeCode) +{ // Check if MBR data is loaded if (!loaded_) { SetError("MBR data not loaded. Call LoadMbrData() first."); @@ -93,7 +99,7 @@ MbrResult OhosMbrHelper::ChangePartitionType(int partNum, uint8_t typeCode) { } // Validate partition number range (1-128) - if (partNum < 1 || partNum > 128) { + if (partNum < MIN_MBR_PARTS || partNum > MAX_MBR_PARTS) { std::ostringstream oss; oss << "Invalid partition number " << partNum << " (must be 1-128)"; SetError(oss.str()); @@ -108,7 +114,7 @@ MbrResult OhosMbrHelper::ChangePartitionType(int partNum, uint8_t typeCode) { return MbrResult::ERROR_INVALID_TYPECODE; } - BasicMBRData* mbr = static_cast(mbrData_); + BasicMBRData *mbr = static_cast(mbrData_); // Check if partition exists and is not empty if (mbr->GetLength(partNum - 1) == 0) { @@ -130,13 +136,14 @@ MbrResult OhosMbrHelper::ChangePartitionType(int partNum, uint8_t typeCode) { return MbrResult::SUCCESS; } -MbrResult OhosMbrHelper::SaveMbrData() { +MbrResult OhosMbrHelper::SaveMbrData() +{ if (!loaded_) { SetError("MBR data not loaded. Call LoadMbrData() first."); return MbrResult::ERROR_READ_FAILED; } - BasicMBRData* mbr = static_cast(mbrData_); + BasicMBRData *mbr = static_cast(mbrData_); if (!mbr->WriteMBRData()) { SetError("Failed to write MBR data to device: " + device_); @@ -147,41 +154,25 @@ MbrResult OhosMbrHelper::SaveMbrData() { return MbrResult::SUCCESS; } -std::string OhosMbrHelper::GetLastError() const { +std::string OhosMbrHelper::GetLastError() const +{ return lastError_; } -void OhosMbrHelper::DisplayMBRData() { +void OhosMbrHelper::DisplayMBRData() +{ if (!loaded_) { std::cerr << "MBR data not loaded. Call LoadMbrData() first." << std::endl; return; } - BasicMBRData* mbr = static_cast(mbrData_); + BasicMBRData *mbr = static_cast(mbrData_); - std::cout << "MBR Partition Table:" << std::endl; - std::cout << " # Boot Start Sector End Sector Type Code Size" << std::endl; - - for (int i = 0; i < 4; i++) { - uint64_t length = mbr->GetLength(i); - if (length > 0) { - uint8_t status = mbr->GetStatus(i); - uint8_t typeCode = mbr->GetType(i); - uint64_t firstSector = mbr->GetFirstSector(i); - - std::cout << " " << (i + 1) << " "; - std::cout << (status == 0x80 ? " * " : " "); - std::cout << std::setw(12) << firstSector << " "; - std::cout << std::setw(12) << (firstSector + length - 1) << " "; - std::cout << "0x" << std::setfill('0') << std::setw(2) - << std::hex << static_cast(typeCode) << std::dec; - std::cout << std::setfill(' ') << " "; - std::cout << (length * 512 / (1024 * 1024)) << " MB" << std::endl; - } - } + mbr->DisplayMBRData(); } -void OhosMbrHelper::SetError(const std::string& error) { +void OhosMbrHelper::SetError(const std::string &error) +{ lastError_ = error; std::cerr << error << std::endl; -} \ No newline at end of file +} From 9ed536fc434ee691f171bc32ba167f92e097361c Mon Sep 17 00:00:00 2001 From: jiangqianrong Date: Fri, 20 Mar 2026 12:00:09 +0800 Subject: [PATCH 07/12] =?UTF-8?q?update:=20=E6=9B=B4=E6=96=B0=E6=96=87?= =?UTF-8?q?=E4=BB=B6=20ohos=5Fmbr=5Fhelper.h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: jiangqianrong --- ohos/ohos_mbr_helper.h | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/ohos/ohos_mbr_helper.h b/ohos/ohos_mbr_helper.h index d9fcfc6..75e2672 100644 --- a/ohos/ohos_mbr_helper.h +++ b/ohos/ohos_mbr_helper.h @@ -10,13 +10,13 @@ #ifndef OHOS_MBR_HELPER_H #define OHOS_MBR_HELPER_H -#include #include +#include // MBR operation result codes enum class MbrResult { SUCCESS = 0, - ERROR_INVALID_DEVICE = 1, + ERROR_UNKNOWN = 1, ERROR_READ_FAILED = 2, ERROR_WRITE_FAILED = 3, ERROR_INVALID_PARTITION = 4, @@ -24,9 +24,11 @@ enum class MbrResult { ERROR_NOT_MBR_DISK = 6, ERROR_GPT_DISK = 7, ERROR_EMPTY_PARTITION = 8, - ERROR_UNKNOWN = 100 + ERROR_INVALID_DEVICE = 9 }; +#define MIN_MBR_PARTS 1 + // MBR partition type code modifier class class OhosMbrHelper { public: @@ -34,10 +36,10 @@ public: ~OhosMbrHelper(); // Load MBR data - MbrResult LoadMbrData(const std::string& device); + MbrResult LoadMbrData(const std::string &device); // Validate device path - MbrResult ValidateDevice(const std::string& device); + MbrResult ValidateDevice(const std::string &device); // Read MBR data from device MbrResult ReadMbrFromDevice(); @@ -45,7 +47,7 @@ public: // Validate MBR data MbrResult ValidateMbrData(); - // Change partition type code + // Change partition type code // partNum: Partition number (1-128) // typeCode: Type code (0x01-0xFF) MbrResult ChangePartitionType(int partNum, uint8_t typeCode); @@ -60,13 +62,13 @@ public: std::string GetLastError() const; private: - void* mbrData_; // BasicMBRData object pointer + void *mbrData_; // BasicMBRData object pointer std::string lastError_; std::string device_; bool loaded_; // Set error message - void SetError(const std::string& error); + void SetError(const std::string &error); }; -#endif // OHOS_MBR_HELPER_H \ No newline at end of file +#endif // OHOS_MBR_HELPER_H From 4e53997a515342910e8032717f64439cfd8cdb86 Mon Sep 17 00:00:00 2001 From: jiangqianrong Date: Sat, 21 Mar 2026 15:32:55 +0800 Subject: [PATCH 08/12] =?UTF-8?q?update:=20=E6=9B=B4=E6=96=B0=E6=96=87?= =?UTF-8?q?=E4=BB=B6=20BUILD.gn?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: jiangqianrong --- BUILD.gn | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/BUILD.gn b/BUILD.gn index b63e22c..33ad5a2 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -65,6 +65,11 @@ ohos_executable("ohos_fixparts") { "support.cc", ] + include_dirs = [ + ".", + "//third_party/gptfdisk/", + ] + public_configs = [ ":gptdisk_config" ] external_deps = [ "e2fsprogs:libext2_uuid" ] From d61a4d30aba613c324634798ae8d80de9e667493 Mon Sep 17 00:00:00 2001 From: jiangqianrong Date: Sat, 21 Mar 2026 15:33:27 +0800 Subject: [PATCH 09/12] =?UTF-8?q?update:=20=E6=9B=B4=E6=96=B0=E6=96=87?= =?UTF-8?q?=E4=BB=B6=20ohos=5Ffixparts.cpp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: jiangqianrong --- ohos/ohos_fixparts.cpp | 87 +++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 44 deletions(-) diff --git a/ohos/ohos_fixparts.cpp b/ohos/ohos_fixparts.cpp index 50dce24..c89fad2 100644 --- a/ohos/ohos_fixparts.cpp +++ b/ohos/ohos_fixparts.cpp @@ -8,8 +8,8 @@ */ #include "ohos_fixparts.h" -#include "../basicmbr.h" -#include "../support.h" +#include "basicmbr.h" +#include "support.h" #include #include #include @@ -25,6 +25,7 @@ MbrResult OhosFixparts::ParseArgs(int argc, char *argv[], OhosFixpartsArgs &args { int opt; int option_index = 0; + int typecodeCount = 0; // Count of -t options static struct option long_options[] = {{"print", no_argument, nullptr, 'p'}, {"typecode", required_argument, nullptr, 't'}, @@ -37,10 +38,17 @@ MbrResult OhosFixparts::ParseArgs(int argc, char *argv[], OhosFixpartsArgs &args args.printMBR = true; break; case 't': { + typecodeCount++; + if (typecodeCount > 1) { + std::cerr << "Error: Only one -t option is supported" << std::endl; + ShowHelp(argv[0]); + return MbrResult::ERROR_INVALID_ARGUMENT; + } MbrResult result = ParseOption(optarg, args.partitionNum, args.typeCode); if (result != MbrResult::SUCCESS) { return result; } + args.hasTypeCode = true; break; } case 'h': @@ -58,18 +66,11 @@ MbrResult OhosFixparts::ParseArgs(int argc, char *argv[], OhosFixpartsArgs &args args.device = argv[optind]; } - // Check for extra arguments (should be exactly one device path) - if (optind + 1 < argc) { - std::cerr << "Error: Too many device paths specified" << std::endl; - ShowHelp(argv[0]); - return MbrResult::ERROR_INVALID_DEVICE; - } - // Validate device path if (args.device.empty()) { std::cerr << "Device path is required" << std::endl; ShowHelp(argv[0]); - return MbrResult::ERROR_INVALID_DEVICE; + return MbrResult::ERROR_INVALID_ARGUMENT; } return MbrResult::SUCCESS; @@ -77,14 +78,13 @@ MbrResult OhosFixparts::ParseArgs(int argc, char *argv[], OhosFixpartsArgs &args MbrResult OhosFixparts::ParseOption(const std::string &option, int &partitionNum, uint8_t &typeCode) { - // Parse partition number and type code std::string paramStr = option; size_t colonPos = paramStr.find(':'); if (colonPos == std::string::npos || colonPos == 0 || colonPos == paramStr.length() - 1) { - std::cerr << "Invalid option format(expected partnum:typecode): "<< option.c_str() << std::endl; - return MbrResult::ERROR_INVALID_PARTITION; + std::cerr << "Invalid option format (expected partnum:typecode): " << option.c_str() << std::endl; + return MbrResult::ERROR_INVALID_ARGUMENT; } std::string partNumStr = paramStr.substr(0, colonPos); @@ -97,7 +97,7 @@ MbrResult OhosFixparts::ParseOption(const std::string &option, int &partitionNum // Validate and parse type code if (!ParseTypeCode(typeCodeStr, typeCode)) { - return MbrResult::ERROR_INVALID_TYPECODE; + return MbrResult::ERROR_INVALID_ARGUMENT; } return MbrResult::SUCCESS; @@ -107,15 +107,15 @@ MbrResult OhosFixparts::ParsePartNum(const std::string &str, int &partitionNum) { // Validate partition number - manual validation without exceptions if (str.empty()) { - std::cerr << "Invalid partition number: NULL" << std::endl; - return MbrResult::ERROR_INVALID_PARTITION; + std::cerr << "Invalid partition number: empty string" << std::endl; + return MbrResult::ERROR_INVALID_ARGUMENT; } // Check if all characters are digits for (char c : str) { if (!isdigit(c)) { - std::cerr << "Invalid partition number(must be a pure number): " << c << std::endl; - return MbrResult::ERROR_INVALID_PARTITION; + std::cerr << "Invalid partition number (must be a pure number): " << c << std::endl; + return MbrResult::ERROR_INVALID_ARGUMENT; } } @@ -124,14 +124,14 @@ MbrResult OhosFixparts::ParsePartNum(const std::string &str, int &partitionNum) iss >> partitionNum; if (iss.fail() || !iss.eof()) { - std::cerr << "Parse partNum fail: " << std::to_string(iss.fail()) << "/" - << std::to_string(iss.eof()) << " str: " << str.c_str() << std::endl; - return MbrResult::ERROR_INVALID_PARTITION; + std::cerr << "Parse partNum fail: fail=" << iss.fail() << ", eof=" << iss.eof() << ", str: " << str.c_str() + << std::endl; + return MbrResult::ERROR_INVALID_ARGUMENT; } if (partitionNum < MIN_MBR_PARTS || partitionNum > MAX_MBR_PARTS) { - std::cerr << "Invalid partition number(must be 1-128): " << str.c_str() << std::endl; - return MbrResult::ERROR_INVALID_PARTITION; + std::cerr << "Invalid partition number (must be 1-128): " << str.c_str() << std::endl; + return MbrResult::ERROR_INVALID_ARGUMENT; } return MbrResult::SUCCESS; @@ -139,26 +139,26 @@ MbrResult OhosFixparts::ParsePartNum(const std::string &str, int &partitionNum) bool OhosFixparts::ParseTypeCode(const std::string &str, uint8_t &code) { - int value; + unsigned int value = 0; if (!IsHex(str)) { std::cerr << "Invalid hex format: " << str.c_str() << std::endl; return false; } - // Parse hex value + // Parse hex value using std::istringstream (type-safe, no sscanf) std::istringstream iss(str); iss >> std::hex >> value; if (iss.fail() || !iss.eof()) { - std::cerr << "Parse typecode fail: " << std::to_string(iss.fail()) << "/" - << std::to_string(iss.eof()) << " str: " << str.c_str() << std::endl; + std::cerr << "Parse typecode fail: fail=" << iss.fail() << ", eof=" << iss.eof() << ", str: " << str.c_str() + << std::endl; return false; } // Validate range before conversion to prevent truncation - if (value < 0x01 || value > 0xFF) { - std::cerr << "Invalid type code(must be 0x01-0xFF): " << value << std::endl; + if (value < MIN_TYPE_CODE || value > MAX_TYPE_CODE) { + std::cerr << "Invalid type code (must be 0x01-0xFF): 0x" << std::hex << value << std::dec << std::endl; return false; } @@ -170,33 +170,32 @@ int OhosFixparts::Run(const OhosFixpartsArgs &args) { MbrResult result = helper_.LoadMbrData(args.device); if (result != MbrResult::SUCCESS) { - std::cerr << "Failed to load MBR data: " << helper_.GetLastError() << std::endl; return static_cast(result); } // Print mode: display MBR partition table if (args.printMBR) { helper_.DisplayMBRData(); - return 0; } // Modify mode: change partition type code - std::cout << "Changing partition " << args.partitionNum << " type code to 0x" << std::hex - << static_cast(args.typeCode) << std::dec << std::endl; + if (args.hasTypeCode) { + std::cout << "Changing partition " << args.partitionNum << " type code to 0x" << std::hex + << static_cast(args.typeCode) << std::dec << std::endl; - result = helper_.ChangePartitionType(args.partitionNum, args.typeCode); - if (result != MbrResult::SUCCESS) { - std::cerr << "Failed to change partition type: " << helper_.GetLastError() << std::endl; - return static_cast(result); + result = helper_.ChangePartitionType(args.partitionNum, args.typeCode); + if (result != MbrResult::SUCCESS) { + return static_cast(result); + } + + result = helper_.SaveMbrData(); + if (result != MbrResult::SUCCESS) { + return static_cast(result); + } + + std::cout << "Partition type code changed successfully." << std::endl; } - result = helper_.SaveMbrData(); - if (result != MbrResult::SUCCESS) { - std::cerr << "Failed to save MBR data: " << helper_.GetLastError() << std::endl; - return static_cast(result); - } - - std::cout << "Partition type code changed successfully." << std::endl; return 0; } From 47bf3f1a8382260df37d89efabbaa4dd5a3482a9 Mon Sep 17 00:00:00 2001 From: jiangqianrong Date: Sat, 21 Mar 2026 15:33:45 +0800 Subject: [PATCH 10/12] =?UTF-8?q?update:=20=E6=9B=B4=E6=96=B0=E6=96=87?= =?UTF-8?q?=E4=BB=B6=20ohos=5Ffixparts.h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: jiangqianrong --- ohos/ohos_fixparts.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ohos/ohos_fixparts.h b/ohos/ohos_fixparts.h index bfd77f7..9fd923e 100644 --- a/ohos/ohos_fixparts.h +++ b/ohos/ohos_fixparts.h @@ -18,10 +18,11 @@ struct OhosFixpartsArgs { std::string device; // Device path bool printMBR; // Print MBR partition table bool showHelp; // Show help information + bool hasTypeCode; // Flag to indicate if -t option is present int partitionNum; // Partition number uint8_t typeCode; // Type code - OhosFixpartsArgs() : printMBR(false), showHelp(false), partitionNum(-1), typeCode(0) {} + OhosFixpartsArgs() : printMBR(false), showHelp(false), hasTypeCode(false), partitionNum(-1), typeCode(0) {} }; // Main program class From 207ad9c8e22b364497e59f28ef68407233f8e51d Mon Sep 17 00:00:00 2001 From: jiangqianrong Date: Sat, 21 Mar 2026 15:34:05 +0800 Subject: [PATCH 11/12] =?UTF-8?q?update:=20=E6=9B=B4=E6=96=B0=E6=96=87?= =?UTF-8?q?=E4=BB=B6=20ohos=5Fmbr=5Fhelper.cpp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: jiangqianrong --- ohos/ohos_mbr_helper.cpp | 112 ++++++++++++++------------------------- 1 file changed, 39 insertions(+), 73 deletions(-) diff --git a/ohos/ohos_mbr_helper.cpp b/ohos/ohos_mbr_helper.cpp index 91a0819..44d7e6c 100644 --- a/ohos/ohos_mbr_helper.cpp +++ b/ohos/ohos_mbr_helper.cpp @@ -8,33 +8,33 @@ */ #include "ohos_mbr_helper.h" -#include "../basicmbr.h" + #include #include -#include -OhosMbrHelper::OhosMbrHelper() : mbrData_(nullptr), loaded_(false) +OhosMbrHelper::OhosMbrHelper() : mbrData_(nullptr), device_(""), loaded_(false) { - mbrData_ = new BasicMBRData(); + mbrData_ = new (std::nothrow) BasicMBRData(); + if (mbrData_ == nullptr) { + std::cerr << "Failed to allocate memory for MBR data" << std::endl; + loaded_ = false; + } } OhosMbrHelper::~OhosMbrHelper() { if (mbrData_ != nullptr) { - delete static_cast(mbrData_); + delete mbrData_; mbrData_ = nullptr; } } MbrResult OhosMbrHelper::LoadMbrData(const std::string &device) { - MbrResult result = ValidateDevice(device); - if (result != MbrResult::SUCCESS) { - return result; - } - + // mbrData_ is initialized in constructor, no need to check here device_ = device; - result = ReadMbrFromDevice(); + + MbrResult result = ReadMbrFromDevice(); if (result != MbrResult::SUCCESS) { return result; } @@ -44,28 +44,16 @@ MbrResult OhosMbrHelper::LoadMbrData(const std::string &device) return result; } - BasicMBRData *mbr = static_cast(mbrData_); - mbr->MakeItLegal(); + mbrData_->MakeItLegal(); loaded_ = true; return MbrResult::SUCCESS; } -MbrResult OhosMbrHelper::ValidateDevice(const std::string &device) -{ - if (device.empty()) { - SetError("Device path is empty"); - return MbrResult::ERROR_INVALID_DEVICE; - } - return MbrResult::SUCCESS; -} - MbrResult OhosMbrHelper::ReadMbrFromDevice() { - BasicMBRData *mbr = static_cast(mbrData_); - - if (!mbr->ReadMBRData(device_)) { - SetError("Failed to read MBR data from device: " + device_); + if (!mbrData_->ReadMBRData(device_)) { + std::cerr << "Failed to read MBR data from device: " << device_ << std::endl; return MbrResult::ERROR_READ_FAILED; } @@ -74,17 +62,16 @@ MbrResult OhosMbrHelper::ReadMbrFromDevice() MbrResult OhosMbrHelper::ValidateMbrData() { - BasicMBRData *mbr = static_cast(mbrData_); - MBRValidity validity = mbr->GetValidity(); + MBRValidity validity = mbrData_->GetValidity(); if (validity == gpt || validity == hybrid) { - SetError("Device appears to be a GPT disk, not MBR"); - return MbrResult::ERROR_GPT_DISK; + std::cerr << "Device appears to be a GPT disk, not MBR" << std::endl; + return MbrResult::ERROR_GPT_PART; } if (validity == invalid) { - SetError("Invalid MBR data on device"); - return MbrResult::ERROR_NOT_MBR_DISK; + std::cerr << "Invalid MBR data on device" << std::endl; + return MbrResult::ERROR_NOT_SUPPORT_PART; } return MbrResult::SUCCESS; @@ -94,42 +81,33 @@ MbrResult OhosMbrHelper::ChangePartitionType(int partNum, uint8_t typeCode) { // Check if MBR data is loaded if (!loaded_) { - SetError("MBR data not loaded. Call LoadMbrData() first."); + std::cerr << "MBR data not loaded. Call LoadMbrData() first." << std::endl; return MbrResult::ERROR_READ_FAILED; } // Validate partition number range (1-128) if (partNum < MIN_MBR_PARTS || partNum > MAX_MBR_PARTS) { - std::ostringstream oss; - oss << "Invalid partition number " << partNum << " (must be 1-128)"; - SetError(oss.str()); - return MbrResult::ERROR_INVALID_PARTITION; + std::cerr << "Invalid partition number (must be 1-128): " << partNum << std::endl; + return MbrResult::ERROR_INVALID_ARGUMENT; } // Validate range before conversion to prevent truncation - if (typeCode < 0x01 || typeCode > 0xFF) { - std::ostringstream oss; - oss << "Invalid typecode " << typeCode << " (must be 0x01 - 0xFF)"; - SetError(oss.str()); - return MbrResult::ERROR_INVALID_TYPECODE; + if (typeCode < MIN_TYPE_CODE || typeCode > MAX_TYPE_CODE) { + std::cerr << "Invalid typecode (must be 0x01-0xFF): 0x" << std::hex << static_cast(typeCode) << std::dec + << std::endl; + return MbrResult::ERROR_INVALID_ARGUMENT; } - BasicMBRData *mbr = static_cast(mbrData_); - // Check if partition exists and is not empty - if (mbr->GetLength(partNum - 1) == 0) { - std::ostringstream oss; - oss << "Partition " << partNum << " is empty or does not exist"; - SetError(oss.str()); - return MbrResult::ERROR_EMPTY_PARTITION; + if (mbrData_->GetLength(partNum - 1) == 0) { + std::cerr << "Partition " << partNum << " is empty or does not exist" << std::endl; + return MbrResult::ERROR_INVALID_ARGUMENT; } // Set partition type code - int result = mbr->SetPartType(partNum - 1, typeCode); + int result = mbrData_->SetPartType(partNum - 1, typeCode); if (result == 0) { - std::ostringstream oss; - oss << "Failed to set type code for partition " << partNum; - SetError(oss.str()); + std::cerr << "Failed to set type code for partition: " << partNum << std::endl; return MbrResult::ERROR_UNKNOWN; } @@ -139,26 +117,19 @@ MbrResult OhosMbrHelper::ChangePartitionType(int partNum, uint8_t typeCode) MbrResult OhosMbrHelper::SaveMbrData() { if (!loaded_) { - SetError("MBR data not loaded. Call LoadMbrData() first."); + std::cerr << "MBR data not loaded. Call LoadMbrData() first." << std::endl; return MbrResult::ERROR_READ_FAILED; } - BasicMBRData *mbr = static_cast(mbrData_); - - if (!mbr->WriteMBRData()) { - SetError("Failed to write MBR data to device: " + device_); + if (!mbrData_->WriteMBRData()) { + std::cerr << "Failed to write MBR data to device: " << device_ << std::endl; return MbrResult::ERROR_WRITE_FAILED; } - mbr->DiskSync(); + mbrData_->DiskSync(); return MbrResult::SUCCESS; } -std::string OhosMbrHelper::GetLastError() const -{ - return lastError_; -} - void OhosMbrHelper::DisplayMBRData() { if (!loaded_) { @@ -166,13 +137,8 @@ void OhosMbrHelper::DisplayMBRData() return; } - BasicMBRData *mbr = static_cast(mbrData_); - - mbr->DisplayMBRData(); -} - -void OhosMbrHelper::SetError(const std::string &error) -{ - lastError_ = error; - std::cerr << error << std::endl; + // Reuse existing DisplayMBRData implementation from basicmbr.cc + // This provides more comprehensive MBR information including disk size, + // disk identifier, and detailed partition information + mbrData_->DisplayMBRData(); } From 970fb72923f7eb1387adc7fcc1bc70c274acaf4c Mon Sep 17 00:00:00 2001 From: jiangqianrong Date: Sat, 21 Mar 2026 15:34:25 +0800 Subject: [PATCH 12/12] =?UTF-8?q?update:=20=E6=9B=B4=E6=96=B0=E6=96=87?= =?UTF-8?q?=E4=BB=B6=20ohos=5Fmbr=5Fhelper.h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: jiangqianrong --- ohos/ohos_mbr_helper.h | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/ohos/ohos_mbr_helper.h b/ohos/ohos_mbr_helper.h index 75e2672..fa93bde 100644 --- a/ohos/ohos_mbr_helper.h +++ b/ohos/ohos_mbr_helper.h @@ -13,24 +13,25 @@ #include #include +#include "basicmbr.h" + // MBR operation result codes enum class MbrResult { SUCCESS = 0, ERROR_UNKNOWN = 1, ERROR_READ_FAILED = 2, ERROR_WRITE_FAILED = 3, - ERROR_INVALID_PARTITION = 4, - ERROR_INVALID_TYPECODE = 5, - ERROR_NOT_MBR_DISK = 6, - ERROR_GPT_DISK = 7, - ERROR_EMPTY_PARTITION = 8, - ERROR_INVALID_DEVICE = 9 + ERROR_INVALID_ARGUMENT = 4, + ERROR_NOT_SUPPORT_PART = 5, + ERROR_GPT_PART = 6 }; #define MIN_MBR_PARTS 1 +#define MIN_TYPE_CODE 0x01 +#define MAX_TYPE_CODE 0xFF // MBR partition type code modifier class -class OhosMbrHelper { +class OhosMbrHelper final { public: OhosMbrHelper(); ~OhosMbrHelper(); @@ -38,9 +39,6 @@ public: // Load MBR data MbrResult LoadMbrData(const std::string &device); - // Validate device path - MbrResult ValidateDevice(const std::string &device); - // Read MBR data from device MbrResult ReadMbrFromDevice(); @@ -58,17 +56,10 @@ public: // Display MBR partition table void DisplayMBRData(); - // Get error message - std::string GetLastError() const; - private: - void *mbrData_; // BasicMBRData object pointer - std::string lastError_; + BasicMBRData *mbrData_; // MBR data object pointer (initialized in constructor) std::string device_; bool loaded_; - - // Set error message - void SetError(const std::string &error); }; #endif // OHOS_MBR_HELPER_H