1fb299fa2Sopenharmony_ci/* 2fb299fa2Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 3fb299fa2Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4fb299fa2Sopenharmony_ci * you may not use this file except in compliance with the License. 5fb299fa2Sopenharmony_ci * You may obtain a copy of the License at 6fb299fa2Sopenharmony_ci * 7fb299fa2Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8fb299fa2Sopenharmony_ci * 9fb299fa2Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10fb299fa2Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11fb299fa2Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fb299fa2Sopenharmony_ci * See the License for the specific language governing permissions and 13fb299fa2Sopenharmony_ci * limitations under the License. 14fb299fa2Sopenharmony_ci */ 15fb299fa2Sopenharmony_ci 16fb299fa2Sopenharmony_ci#include "ptable.h" 17fb299fa2Sopenharmony_ci 18fb299fa2Sopenharmony_ci#include <algorithm> 19fb299fa2Sopenharmony_ci#include <map> 20fb299fa2Sopenharmony_ci#include <sys/stat.h> 21fb299fa2Sopenharmony_ci 22fb299fa2Sopenharmony_ci#include "applypatch/data_writer.h" 23fb299fa2Sopenharmony_ci#include "log/log.h" 24fb299fa2Sopenharmony_ci#include "securec.h" 25fb299fa2Sopenharmony_ci 26fb299fa2Sopenharmony_cinamespace Updater { 27fb299fa2Sopenharmony_ciconstexpr const char *PTABLE_CONFIG_PATH = "/etc/ptable_data.json"; 28fb299fa2Sopenharmony_ciconstexpr const char *PTABLE_DATA_LABEL = "ptableData"; 29fb299fa2Sopenharmony_ciconstexpr const char *EMMC_GPT_DATA_LEN_LABEL = "emmcGptDataLen"; 30fb299fa2Sopenharmony_ciconstexpr const char *LBA_LEN_LABEL = "lbaLen"; 31fb299fa2Sopenharmony_ciconstexpr const char *GPT_HEADER_LEN_LABEL = "gptHeaderLen"; 32fb299fa2Sopenharmony_ciconstexpr const char *BLOCK_SIZE_LABEL = "blockSize"; 33fb299fa2Sopenharmony_ciconstexpr const char *IMG_LUN_SIZE_LABEL = "imgLuSize"; 34fb299fa2Sopenharmony_ciconstexpr const char *START_LUN_NUM_LABEL = "startLunNumber"; 35fb299fa2Sopenharmony_ciconstexpr const char *WRITE_DEVICE_LUN_SIZE_LABEL = "writeDeviceLunSize"; 36fb299fa2Sopenharmony_ciconstexpr const char *DEFAULT_LUN_NUM_LABEL = "defaultLunNum"; 37fb299fa2Sopenharmony_ci 38fb299fa2Sopenharmony_cistd::vector<Ptable::PtnInfo> Ptable::GetPtablePartitionInfo() const 39fb299fa2Sopenharmony_ci{ 40fb299fa2Sopenharmony_ci return partitionInfo_; 41fb299fa2Sopenharmony_ci} 42fb299fa2Sopenharmony_ci 43fb299fa2Sopenharmony_ciuint32_t Ptable::GetPtablePartitionNum() const 44fb299fa2Sopenharmony_ci{ 45fb299fa2Sopenharmony_ci return partitionInfo_.size(); 46fb299fa2Sopenharmony_ci} 47fb299fa2Sopenharmony_ci 48fb299fa2Sopenharmony_cibool Ptable::LoadPtnInfo(const std::vector<PtnInfo> &ptnInfo) 49fb299fa2Sopenharmony_ci{ 50fb299fa2Sopenharmony_ci if (ptnInfo.empty()) { 51fb299fa2Sopenharmony_ci LOG(ERROR) << "ptnInfo is empty"; 52fb299fa2Sopenharmony_ci return false; 53fb299fa2Sopenharmony_ci } 54fb299fa2Sopenharmony_ci partitionInfo_ = ptnInfo; 55fb299fa2Sopenharmony_ci return true; 56fb299fa2Sopenharmony_ci} 57fb299fa2Sopenharmony_ci 58fb299fa2Sopenharmony_civoid Ptable::SetReservedSize(uint64_t reservedSize) 59fb299fa2Sopenharmony_ci{ 60fb299fa2Sopenharmony_ci reservedSize_ = reservedSize; 61fb299fa2Sopenharmony_ci} 62fb299fa2Sopenharmony_ci 63fb299fa2Sopenharmony_cistd::vector<Ptable::PtnInfo>& Ptable::GetPtablePartitionInfoInstance() 64fb299fa2Sopenharmony_ci{ 65fb299fa2Sopenharmony_ci return partitionInfo_; 66fb299fa2Sopenharmony_ci} 67fb299fa2Sopenharmony_ci 68fb299fa2Sopenharmony_cibool Ptable::InitPtable() 69fb299fa2Sopenharmony_ci{ 70fb299fa2Sopenharmony_ci if (!partitionInfo_.empty()) { 71fb299fa2Sopenharmony_ci std::vector<PtnInfo>().swap(partitionInfo_); 72fb299fa2Sopenharmony_ci } 73fb299fa2Sopenharmony_ci if (!ParsePtableData()) { 74fb299fa2Sopenharmony_ci LOG(ERROR) << "parse PtableData from json file error"; 75fb299fa2Sopenharmony_ci return false; 76fb299fa2Sopenharmony_ci } 77fb299fa2Sopenharmony_ci return true; 78fb299fa2Sopenharmony_ci} 79fb299fa2Sopenharmony_ci 80fb299fa2Sopenharmony_cibool Ptable::ParsePtableDataNode(const JsonNode &ptableDataNode) 81fb299fa2Sopenharmony_ci{ 82fb299fa2Sopenharmony_ci std::map<std::string, uint32_t*> ptableDataVars = { 83fb299fa2Sopenharmony_ci {EMMC_GPT_DATA_LEN_LABEL, &ptableData_.emmcGptDataLen}, 84fb299fa2Sopenharmony_ci {LBA_LEN_LABEL, &ptableData_.lbaLen}, 85fb299fa2Sopenharmony_ci {GPT_HEADER_LEN_LABEL, &ptableData_.gptHeaderLen}, 86fb299fa2Sopenharmony_ci {BLOCK_SIZE_LABEL, &ptableData_.blockSize}, 87fb299fa2Sopenharmony_ci {IMG_LUN_SIZE_LABEL, &ptableData_.imgLuSize}, 88fb299fa2Sopenharmony_ci {START_LUN_NUM_LABEL, &ptableData_.startLunNumber}, 89fb299fa2Sopenharmony_ci {WRITE_DEVICE_LUN_SIZE_LABEL, &ptableData_.writeDeviceLunSize}, 90fb299fa2Sopenharmony_ci {DEFAULT_LUN_NUM_LABEL, &ptableData_.defaultLunNum}, 91fb299fa2Sopenharmony_ci }; 92fb299fa2Sopenharmony_ci 93fb299fa2Sopenharmony_ci for (auto dataVar : ptableDataVars) { 94fb299fa2Sopenharmony_ci auto dataValue = ptableDataNode[dataVar.first.c_str()].As<uint32_t>(); 95fb299fa2Sopenharmony_ci if (!dataValue) { 96fb299fa2Sopenharmony_ci LOG(ERROR) << "parse json failed! " << dataVar.first << " is nullptr!"; 97fb299fa2Sopenharmony_ci return false; 98fb299fa2Sopenharmony_ci } 99fb299fa2Sopenharmony_ci *(dataVar.second) = *dataValue; 100fb299fa2Sopenharmony_ci LOG(INFO) << "set " << dataVar.first << " : " << *dataValue; 101fb299fa2Sopenharmony_ci } 102fb299fa2Sopenharmony_ci return true; 103fb299fa2Sopenharmony_ci} 104fb299fa2Sopenharmony_ci 105fb299fa2Sopenharmony_cibool Ptable::ParsePtableData() 106fb299fa2Sopenharmony_ci{ 107fb299fa2Sopenharmony_ci (void)memset_s(&ptableData_, sizeof(ptableData_), 0, sizeof(ptableData_)); 108fb299fa2Sopenharmony_ci std::ifstream ifs(std::string {PTABLE_CONFIG_PATH}); 109fb299fa2Sopenharmony_ci if (!ifs.is_open()) { 110fb299fa2Sopenharmony_ci LOG(ERROR) << PTABLE_CONFIG_PATH << " not exist"; 111fb299fa2Sopenharmony_ci return false; 112fb299fa2Sopenharmony_ci } 113fb299fa2Sopenharmony_ci 114fb299fa2Sopenharmony_ci // get root node 115fb299fa2Sopenharmony_ci std::string content {std::istreambuf_iterator<char> {ifs}, {}}; 116fb299fa2Sopenharmony_ci cJSONPtr root(cJSON_Parse(content.c_str()), cJSON_Delete); 117fb299fa2Sopenharmony_ci if (root == nullptr) { 118fb299fa2Sopenharmony_ci LOG(ERROR) << PTABLE_CONFIG_PATH << " contained json invalid"; 119fb299fa2Sopenharmony_ci return false; 120fb299fa2Sopenharmony_ci } 121fb299fa2Sopenharmony_ci 122fb299fa2Sopenharmony_ci JsonNode node(root.get(), false); 123fb299fa2Sopenharmony_ci const JsonNode &ptableDataNode = node[PTABLE_DATA_LABEL]; 124fb299fa2Sopenharmony_ci bool ret = ParsePtableDataNode(ptableDataNode); 125fb299fa2Sopenharmony_ci ptableData_.dataValid = ret; 126fb299fa2Sopenharmony_ci return ret; 127fb299fa2Sopenharmony_ci} 128fb299fa2Sopenharmony_ci 129fb299fa2Sopenharmony_ciuint32_t Ptable::GetDefaultImageSize() const 130fb299fa2Sopenharmony_ci{ 131fb299fa2Sopenharmony_ci return ptableData_.emmcGptDataLen + ptableData_.defaultLunNum * ptableData_.imgLuSize; 132fb299fa2Sopenharmony_ci} 133fb299fa2Sopenharmony_ci 134fb299fa2Sopenharmony_cibool Ptable::CheckFileExist(const std::string &fileName) 135fb299fa2Sopenharmony_ci{ 136fb299fa2Sopenharmony_ci struct stat buffers; 137fb299fa2Sopenharmony_ci if (memset_s(&buffers, sizeof(buffers), 0, sizeof(buffers)) != EOK) { 138fb299fa2Sopenharmony_ci LOG(WARNING) << "memset_s fail"; 139fb299fa2Sopenharmony_ci } 140fb299fa2Sopenharmony_ci if (stat(fileName.c_str(), &buffers) == 0) { 141fb299fa2Sopenharmony_ci LOG(INFO) << fileName << " is exist"; 142fb299fa2Sopenharmony_ci return true; 143fb299fa2Sopenharmony_ci } 144fb299fa2Sopenharmony_ci LOG(INFO) << fileName << " is not exist"; 145fb299fa2Sopenharmony_ci return false; 146fb299fa2Sopenharmony_ci} 147fb299fa2Sopenharmony_ci 148fb299fa2Sopenharmony_cibool Ptable::MemReadWithOffset(const std::string &filePath, const uint64_t offset, 149fb299fa2Sopenharmony_ci uint8_t *outData, const uint32_t dataSize) 150fb299fa2Sopenharmony_ci{ 151fb299fa2Sopenharmony_ci if (filePath.length() == 0 || outData == nullptr || dataSize == 0) { 152fb299fa2Sopenharmony_ci LOG(ERROR) << "invaild input"; 153fb299fa2Sopenharmony_ci return false; 154fb299fa2Sopenharmony_ci } 155fb299fa2Sopenharmony_ci 156fb299fa2Sopenharmony_ci std::ifstream fin(filePath, std::ios::in); 157fb299fa2Sopenharmony_ci if (fin.fail()) { 158fb299fa2Sopenharmony_ci LOG(ERROR) << "open " << filePath << " fail"; 159fb299fa2Sopenharmony_ci return false; 160fb299fa2Sopenharmony_ci } 161fb299fa2Sopenharmony_ci 162fb299fa2Sopenharmony_ci fin.seekg(offset, std::ios::beg); 163fb299fa2Sopenharmony_ci if (fin.tellg() != static_cast<long long>(offset)) { 164fb299fa2Sopenharmony_ci LOG(ERROR) << "seekp 0x" << std::hex << offset << " bytes in " << filePath << 165fb299fa2Sopenharmony_ci " failed. Now is in 0x" << std::hex << fin.tellg() << std::dec; 166fb299fa2Sopenharmony_ci fin.close(); 167fb299fa2Sopenharmony_ci return false; 168fb299fa2Sopenharmony_ci } 169fb299fa2Sopenharmony_ci 170fb299fa2Sopenharmony_ci if (!fin.read(reinterpret_cast<char *>(outData), dataSize)) { 171fb299fa2Sopenharmony_ci LOG(ERROR) << "read 0x" << std::hex << dataSize << " bytes in " << filePath << 172fb299fa2Sopenharmony_ci " failed. only read 0x" << std::hex << fin.gcount() << std::dec; 173fb299fa2Sopenharmony_ci fin.close(); 174fb299fa2Sopenharmony_ci return false; 175fb299fa2Sopenharmony_ci } 176fb299fa2Sopenharmony_ci fin.close(); 177fb299fa2Sopenharmony_ci return true; 178fb299fa2Sopenharmony_ci} 179fb299fa2Sopenharmony_ci 180fb299fa2Sopenharmony_ciuint32_t Ptable::Reflect(uint32_t data, const uint32_t len) 181fb299fa2Sopenharmony_ci{ 182fb299fa2Sopenharmony_ci uint32_t ref = 0; 183fb299fa2Sopenharmony_ci for (uint32_t i = 0; i < len; i++) { 184fb299fa2Sopenharmony_ci if (data & 0x1) { 185fb299fa2Sopenharmony_ci ref |= (1 << ((len - 1) - i)); 186fb299fa2Sopenharmony_ci } 187fb299fa2Sopenharmony_ci data = (data >> 1); 188fb299fa2Sopenharmony_ci } 189fb299fa2Sopenharmony_ci return ref; 190fb299fa2Sopenharmony_ci} 191fb299fa2Sopenharmony_ci 192fb299fa2Sopenharmony_ciuint32_t Ptable::CalculateCrc32(const uint8_t *buffer, const uint32_t len) 193fb299fa2Sopenharmony_ci{ 194fb299fa2Sopenharmony_ci if (buffer == nullptr || len == 0) { 195fb299fa2Sopenharmony_ci LOG(INFO) << "invaild input"; 196fb299fa2Sopenharmony_ci return 0; 197fb299fa2Sopenharmony_ci } 198fb299fa2Sopenharmony_ci const uint32_t byteLen = 8; // 8:length of unit (i.e. byte) 199fb299fa2Sopenharmony_ci uint32_t msb; 200fb299fa2Sopenharmony_ci const uint64_t polynomial = 0x104C11DB7LL; // IEEE 32bit polynomial 201fb299fa2Sopenharmony_ci uint32_t regs = 0xFFFFFFFF; // init to all ones 202fb299fa2Sopenharmony_ci const uint32_t regsMask = 0xFFFFFFFF; // ensure only 32 bit answer 203fb299fa2Sopenharmony_ci uint32_t regsMsb; 204fb299fa2Sopenharmony_ci for (uint32_t i = 0; i < len; i++) { 205fb299fa2Sopenharmony_ci uint32_t dataByte = buffer[i]; 206fb299fa2Sopenharmony_ci dataByte = Reflect(dataByte, 8); // 8:length of unit (i.e. byte) 207fb299fa2Sopenharmony_ci for (uint32_t j = 0; j < byteLen; j++) { 208fb299fa2Sopenharmony_ci msb = dataByte >> (byteLen - 1); // get MSB 209fb299fa2Sopenharmony_ci msb &= 1; // ensure just 1 bit 210fb299fa2Sopenharmony_ci regsMsb = (regs >> 31) & 1; // 31:32-1, MSB of regs 211fb299fa2Sopenharmony_ci regs = regs << 1; // shift regs for CRC-CCITT 212fb299fa2Sopenharmony_ci if (regsMsb ^ msb) { // MSB is a 1 213fb299fa2Sopenharmony_ci regs = regs ^ polynomial; // XOR with generator poly 214fb299fa2Sopenharmony_ci } 215fb299fa2Sopenharmony_ci regs = regs & regsMask; // Mask off excess upper bits 216fb299fa2Sopenharmony_ci dataByte <<= 1; // get to next bit 217fb299fa2Sopenharmony_ci } 218fb299fa2Sopenharmony_ci } 219fb299fa2Sopenharmony_ci regs = regs & regsMask; 220fb299fa2Sopenharmony_ci uint32_t ret = Reflect(regs, 32) ^ 0xFFFFFFFF; // 32:32bit 221fb299fa2Sopenharmony_ci return ret; 222fb299fa2Sopenharmony_ci} 223fb299fa2Sopenharmony_ci 224fb299fa2Sopenharmony_cibool Ptable::VerifyMbrMagicNum(const uint8_t *buffer, const uint32_t size) 225fb299fa2Sopenharmony_ci{ 226fb299fa2Sopenharmony_ci // avoid checking past end of buffer 227fb299fa2Sopenharmony_ci if (size < (MBR_MAGIC_NUM_POS + 1)) { 228fb299fa2Sopenharmony_ci LOG(ERROR) << "size < (TABLE_SIGNATURE + 1)"; 229fb299fa2Sopenharmony_ci return false; 230fb299fa2Sopenharmony_ci } 231fb299fa2Sopenharmony_ci // check to see if magic number(0x55AA) exists at pos 0x1FE 232fb299fa2Sopenharmony_ci if ((buffer[MBR_MAGIC_NUM_POS] != MBR_MAGIC_NUM_0) || 233fb299fa2Sopenharmony_ci (buffer[MBR_MAGIC_NUM_POS + 1] != MBR_MAGIC_NUM_1)) { 234fb299fa2Sopenharmony_ci LOG(ERROR) << "MBR magic number does not match, magic buffer is " << unsigned(*(buffer + MBR_MAGIC_NUM_POS)); 235fb299fa2Sopenharmony_ci return false; 236fb299fa2Sopenharmony_ci } 237fb299fa2Sopenharmony_ci return true; 238fb299fa2Sopenharmony_ci} 239fb299fa2Sopenharmony_ci 240fb299fa2Sopenharmony_cibool Ptable::CheckProtectiveMbr(const uint8_t *gptImage, const uint32_t imgLen) 241fb299fa2Sopenharmony_ci{ 242fb299fa2Sopenharmony_ci if (!VerifyMbrMagicNum(gptImage, imgLen)) { 243fb299fa2Sopenharmony_ci LOG(ERROR) << "MBR magic number verify failed!"; 244fb299fa2Sopenharmony_ci return false; 245fb299fa2Sopenharmony_ci } 246fb299fa2Sopenharmony_ci 247fb299fa2Sopenharmony_ci // process each of the four partitions in the MBR, find a Protective MBR(0xEE) 248fb299fa2Sopenharmony_ci uint32_t type; 249fb299fa2Sopenharmony_ci for (uint32_t i = 0; i < MBR_GPT_MAX_NUM; i++) { 250fb299fa2Sopenharmony_ci // type 0xEE indicates the protective MBR and GPT partitions exist 251fb299fa2Sopenharmony_ci if (MBR_GPT_ENTRY + i * MBR_GPT_ENTRY_SIZE + GPT_TYPE_SIGN_OFFSET >= imgLen) { 252fb299fa2Sopenharmony_ci LOG(INFO) << "not find Protective MBR(type: 0xEE) in this partition"; 253fb299fa2Sopenharmony_ci return false; 254fb299fa2Sopenharmony_ci } 255fb299fa2Sopenharmony_ci type = gptImage[MBR_GPT_ENTRY + i * MBR_GPT_ENTRY_SIZE + GPT_TYPE_SIGN_OFFSET]; 256fb299fa2Sopenharmony_ci if (type == MBR_PROTECTIVE_GPT_TYPE) { 257fb299fa2Sopenharmony_ci LOG(INFO) << "type is MBR_PROTECTIVE_GPT_TYPE(0xEE), GPT partitions exist"; 258fb299fa2Sopenharmony_ci return true; 259fb299fa2Sopenharmony_ci } 260fb299fa2Sopenharmony_ci LOG(INFO) << "the " << i << " main GPT's type=0x" << std::hex << type << std::dec; 261fb299fa2Sopenharmony_ci } 262fb299fa2Sopenharmony_ci LOG(INFO) << "not find Protective MBR(type: 0xEE) in this partition"; 263fb299fa2Sopenharmony_ci return false; 264fb299fa2Sopenharmony_ci} 265fb299fa2Sopenharmony_ci 266fb299fa2Sopenharmony_cibool Ptable::CheckIfValidGpt(const uint8_t *gptImage, const uint32_t gptImageLen) 267fb299fa2Sopenharmony_ci{ 268fb299fa2Sopenharmony_ci // 8 is the length of EFI_MAGIC_NUMBER 269fb299fa2Sopenharmony_ci if (gptImageLen < 8) { 270fb299fa2Sopenharmony_ci LOG(ERROR) << "gptImageLen is less than 8."; 271fb299fa2Sopenharmony_ci return false; 272fb299fa2Sopenharmony_ci } 273fb299fa2Sopenharmony_ci // get magic number 274fb299fa2Sopenharmony_ci uint64_t gptMagic = GET_LLWORD_FROM_BYTE(gptImage); 275fb299fa2Sopenharmony_ci if (gptMagic != EFI_MAGIC_NUMBER) { 276fb299fa2Sopenharmony_ci LOG(ERROR) << "invaild partiton with gptMagic:0x" << std::hex << gptMagic << std::dec; 277fb299fa2Sopenharmony_ci return false; 278fb299fa2Sopenharmony_ci } 279fb299fa2Sopenharmony_ci return true; 280fb299fa2Sopenharmony_ci} 281fb299fa2Sopenharmony_ci 282fb299fa2Sopenharmony_cibool Ptable::GetCapacity(const std::string &filePath, uint64_t &lunCapacity) 283fb299fa2Sopenharmony_ci{ 284fb299fa2Sopenharmony_ci if (filePath.empty()) { 285fb299fa2Sopenharmony_ci LOG(ERROR) << "filePath is empty or lunCapacity is nullptr"; 286fb299fa2Sopenharmony_ci return false; 287fb299fa2Sopenharmony_ci } 288fb299fa2Sopenharmony_ci std::ifstream fin(filePath, std::ios::in); 289fb299fa2Sopenharmony_ci if (!fin.is_open()) { 290fb299fa2Sopenharmony_ci LOG(ERROR) << "open " << filePath << " fail"; 291fb299fa2Sopenharmony_ci return false; 292fb299fa2Sopenharmony_ci } 293fb299fa2Sopenharmony_ci 294fb299fa2Sopenharmony_ci uint64_t sector = 0; 295fb299fa2Sopenharmony_ci fin >> sector; 296fb299fa2Sopenharmony_ci if (sector == 0) { 297fb299fa2Sopenharmony_ci LOG(ERROR) << "read data from " << filePath << " fail"; 298fb299fa2Sopenharmony_ci fin.close(); 299fb299fa2Sopenharmony_ci return false; 300fb299fa2Sopenharmony_ci } 301fb299fa2Sopenharmony_ci 302fb299fa2Sopenharmony_ci uint64_t capacity = sector * SECTOR_SIZE; 303fb299fa2Sopenharmony_ci LOG(INFO) << "lun capacity = 0x" << std::hex << capacity << std::dec; 304fb299fa2Sopenharmony_ci lunCapacity = capacity; 305fb299fa2Sopenharmony_ci fin.close(); 306fb299fa2Sopenharmony_ci return true; 307fb299fa2Sopenharmony_ci} 308fb299fa2Sopenharmony_ci 309fb299fa2Sopenharmony_cibool Ptable::GetPartitionGptHeaderInfo(const uint8_t *buffer, const uint32_t bufferLen, GPTHeaderInfo& gptHeaderInfo) 310fb299fa2Sopenharmony_ci{ 311fb299fa2Sopenharmony_ci if (buffer == nullptr || bufferLen < LBA_LENGTH) { 312fb299fa2Sopenharmony_ci LOG(ERROR) << "input invalid"; 313fb299fa2Sopenharmony_ci return false; 314fb299fa2Sopenharmony_ci } 315fb299fa2Sopenharmony_ci 316fb299fa2Sopenharmony_ci // Check GPT Signature 317fb299fa2Sopenharmony_ci if (!CheckIfValidGpt(buffer, bufferLen)) { 318fb299fa2Sopenharmony_ci LOG(ERROR) << "invaild partiton with gptMagic"; 319fb299fa2Sopenharmony_ci return false; 320fb299fa2Sopenharmony_ci } 321fb299fa2Sopenharmony_ci gptHeaderInfo.headerSize = GET_LWORD_FROM_BYTE(buffer + HEADER_SIZE_OFFSET); 322fb299fa2Sopenharmony_ci gptHeaderInfo.firstUsableLba = GET_LLWORD_FROM_BYTE(buffer + FIRST_USABLE_LBA_OFFSET); 323fb299fa2Sopenharmony_ci gptHeaderInfo.maxPartitionCount = GET_LWORD_FROM_BYTE(buffer + PARTITION_COUNT_OFFSET); 324fb299fa2Sopenharmony_ci gptHeaderInfo.partitionEntrySize = GET_LWORD_FROM_BYTE(buffer + PENTRY_SIZE_OFFSET); 325fb299fa2Sopenharmony_ci if (gptHeaderInfo.maxPartitionCount == 0 || gptHeaderInfo.partitionEntrySize == 0) { 326fb299fa2Sopenharmony_ci LOG(ERROR) << "invalid gpt header info"; 327fb299fa2Sopenharmony_ci return false; 328fb299fa2Sopenharmony_ci } 329fb299fa2Sopenharmony_ci return true; 330fb299fa2Sopenharmony_ci} 331fb299fa2Sopenharmony_ci 332fb299fa2Sopenharmony_civoid Ptable::PatchBackUpGptHeader(uint8_t *gptHeader, const uint32_t len, uint64_t backGptEntryStart) 333fb299fa2Sopenharmony_ci{ 334fb299fa2Sopenharmony_ci if (std::max({GPT_HEADER_OFFSET, BACKUP_HEADER_OFFSET, PARTITION_ENTRY_OFFSET}) + sizeof(uint64_t) > len || 335fb299fa2Sopenharmony_ci HEADER_CRC_OFFSET + sizeof(uint32_t) > len) { 336fb299fa2Sopenharmony_ci LOG(ERROR) << "input param invalid"; 337fb299fa2Sopenharmony_ci return; 338fb299fa2Sopenharmony_ci } 339fb299fa2Sopenharmony_ci uint64_t gptHeaderOffset = GET_LLWORD_FROM_BYTE(gptHeader + GPT_HEADER_OFFSET); 340fb299fa2Sopenharmony_ci uint64_t backHeaderOffset = GET_LLWORD_FROM_BYTE(gptHeader + BACKUP_HEADER_OFFSET); 341fb299fa2Sopenharmony_ci PUT_LONG_LONG(gptHeader + GPT_HEADER_OFFSET, backHeaderOffset); 342fb299fa2Sopenharmony_ci PUT_LONG_LONG(gptHeader + BACKUP_HEADER_OFFSET, gptHeaderOffset); 343fb299fa2Sopenharmony_ci PUT_LONG_LONG(gptHeader + PARTITION_ENTRY_OFFSET, backGptEntryStart); 344fb299fa2Sopenharmony_ci PUT_LONG(gptHeader + HEADER_CRC_OFFSET, 0); 345fb299fa2Sopenharmony_ci uint32_t crcValue = CalculateCrc32(gptHeader, GPT_CRC_LEN); 346fb299fa2Sopenharmony_ci PUT_LONG(gptHeader + HEADER_CRC_OFFSET, crcValue); 347fb299fa2Sopenharmony_ci LOG(INFO) << "gpt header offset " << gptHeaderOffset << ", back header offset " << backHeaderOffset << 348fb299fa2Sopenharmony_ci ", crc value " << crcValue; 349fb299fa2Sopenharmony_ci} 350fb299fa2Sopenharmony_ci 351fb299fa2Sopenharmony_cibool Ptable::CheckGptHeader(uint8_t *buffer, const uint32_t bufferLen, const uint64_t lbaNum, 352fb299fa2Sopenharmony_ci const GPTHeaderInfo& gptHeaderInfo) 353fb299fa2Sopenharmony_ci{ 354fb299fa2Sopenharmony_ci if (bufferLen < LBA_LENGTH || lbaNum == 0) { 355fb299fa2Sopenharmony_ci LOG(ERROR) << "bufferLen < LBA_LENGTH || lbaNum == 0"; 356fb299fa2Sopenharmony_ci return false; 357fb299fa2Sopenharmony_ci } 358fb299fa2Sopenharmony_ci 359fb299fa2Sopenharmony_ci if (gptHeaderInfo.headerSize < GPT_HEADER_SIZE || gptHeaderInfo.headerSize > bufferLen) { 360fb299fa2Sopenharmony_ci LOG(ERROR) << "GPT Header size is invaild"; 361fb299fa2Sopenharmony_ci return false; 362fb299fa2Sopenharmony_ci } 363fb299fa2Sopenharmony_ci uint32_t orgCrcVal = GET_LWORD_FROM_BYTE(buffer + HEADER_CRC_OFFSET); 364fb299fa2Sopenharmony_ci // Write CRC field to 0 before calculating the crc of the whole rest of GPT header 365fb299fa2Sopenharmony_ci PUT_LONG(buffer + HEADER_CRC_OFFSET, 0); 366fb299fa2Sopenharmony_ci uint32_t crcVal = CalculateCrc32(buffer, gptHeaderInfo.headerSize); 367fb299fa2Sopenharmony_ci if (crcVal != orgCrcVal) { 368fb299fa2Sopenharmony_ci LOG(ERROR) << "Header crc mismatch crcVal = " << std::hex << crcVal << " with orgCrcVal = " << 369fb299fa2Sopenharmony_ci orgCrcVal << std::dec; 370fb299fa2Sopenharmony_ci return false; 371fb299fa2Sopenharmony_ci } 372fb299fa2Sopenharmony_ci PUT_LONG(buffer + HEADER_CRC_OFFSET, crcVal); 373fb299fa2Sopenharmony_ci 374fb299fa2Sopenharmony_ci uint32_t currentLba = GET_LLWORD_FROM_BYTE(buffer + PRIMARY_HEADER_OFFSET); 375fb299fa2Sopenharmony_ci uint32_t lastUsableLba = GET_LLWORD_FROM_BYTE(buffer + LAST_USABLE_LBA_OFFSET); 376fb299fa2Sopenharmony_ci uint32_t partition0 = GET_LLWORD_FROM_BYTE(buffer + PARTITION_ENTRIES_OFFSET); 377fb299fa2Sopenharmony_ci 378fb299fa2Sopenharmony_ci // check for first and last lba range 379fb299fa2Sopenharmony_ci if (gptHeaderInfo.firstUsableLba > lbaNum || lastUsableLba > lbaNum) { 380fb299fa2Sopenharmony_ci LOG(ERROR) << "invalid usable lba " << gptHeaderInfo.firstUsableLba << ", last is " << lastUsableLba << 381fb299fa2Sopenharmony_ci " lbaNum is " << lbaNum; 382fb299fa2Sopenharmony_ci return false; 383fb299fa2Sopenharmony_ci } 384fb299fa2Sopenharmony_ci // check for partition entry size 385fb299fa2Sopenharmony_ci if (gptHeaderInfo.partitionEntrySize != PARTITION_ENTRY_SIZE || 386fb299fa2Sopenharmony_ci gptHeaderInfo.maxPartitionCount > (MIN_PARTITION_ARRAY_SIZE / PARTITION_ENTRY_SIZE)) { 387fb299fa2Sopenharmony_ci LOG(ERROR) << "invalid parition entry size or max count"; 388fb299fa2Sopenharmony_ci return false; 389fb299fa2Sopenharmony_ci } 390fb299fa2Sopenharmony_ci // GPT header should always be the 0x1 LBA, partition entry should always the 0x2 LBA 391fb299fa2Sopenharmony_ci if (currentLba != 0x1 || partition0 != 0x2) { 392fb299fa2Sopenharmony_ci LOG(ERROR) << "starting LBA mismatch"; 393fb299fa2Sopenharmony_ci return false; 394fb299fa2Sopenharmony_ci } 395fb299fa2Sopenharmony_ci LOG(INFO) << "gpt header check ok"; 396fb299fa2Sopenharmony_ci return true; 397fb299fa2Sopenharmony_ci} 398fb299fa2Sopenharmony_ci 399fb299fa2Sopenharmony_cibool Ptable::PartitionCheckGptHeader(const uint8_t *gptImage, const uint32_t len, const uint64_t lbaNum, 400fb299fa2Sopenharmony_ci const uint32_t blockSize, GPTHeaderInfo& gptHeaderInfo) 401fb299fa2Sopenharmony_ci{ 402fb299fa2Sopenharmony_ci if (len < ptableData_.writeDeviceLunSize || lbaNum == 0) { 403fb299fa2Sopenharmony_ci LOG(ERROR) << "len" << len << "ptableData_.writeDeviceLunSize" << ptableData_.writeDeviceLunSize 404fb299fa2Sopenharmony_ci << "lbaNum" << lbaNum; 405fb299fa2Sopenharmony_ci return false; 406fb299fa2Sopenharmony_ci } 407fb299fa2Sopenharmony_ci 408fb299fa2Sopenharmony_ci uint8_t *buffer = new(std::nothrow) uint8_t[blockSize](); 409fb299fa2Sopenharmony_ci if (buffer == nullptr) { 410fb299fa2Sopenharmony_ci LOG(ERROR) << "new buffer failed!"; 411fb299fa2Sopenharmony_ci return false; 412fb299fa2Sopenharmony_ci } 413fb299fa2Sopenharmony_ci if (memcpy_s(buffer, blockSize, gptImage + blockSize, blockSize) != EOK) { 414fb299fa2Sopenharmony_ci LOG(ERROR) << "copy gpt header fail"; 415fb299fa2Sopenharmony_ci delete [] buffer; 416fb299fa2Sopenharmony_ci return false; 417fb299fa2Sopenharmony_ci } 418fb299fa2Sopenharmony_ci 419fb299fa2Sopenharmony_ci if (!CheckGptHeader(buffer, blockSize, lbaNum, gptHeaderInfo)) { 420fb299fa2Sopenharmony_ci LOG(ERROR) << "CheckGptHeader fail"; 421fb299fa2Sopenharmony_ci delete [] buffer; 422fb299fa2Sopenharmony_ci return false; 423fb299fa2Sopenharmony_ci } 424fb299fa2Sopenharmony_ci 425fb299fa2Sopenharmony_ci uint32_t partition0 = GET_LLWORD_FROM_BYTE(&buffer[PARTITION_ENTRIES_OFFSET]); 426fb299fa2Sopenharmony_ci uint32_t orgCrcVal = GET_LWORD_FROM_BYTE(&buffer[PARTITION_CRC_OFFSET]); 427fb299fa2Sopenharmony_ci delete [] buffer; 428fb299fa2Sopenharmony_ci 429fb299fa2Sopenharmony_ci uint32_t crcVal = CalculateCrc32(gptImage + partition0 * blockSize, 430fb299fa2Sopenharmony_ci gptHeaderInfo.maxPartitionCount * gptHeaderInfo.partitionEntrySize); 431fb299fa2Sopenharmony_ci if (crcVal != orgCrcVal) { 432fb299fa2Sopenharmony_ci LOG(ERROR) << "partition entires crc mismatch crcVal =" << std::hex << crcVal << " with orgCrcVal =" << 433fb299fa2Sopenharmony_ci orgCrcVal << std::dec; 434fb299fa2Sopenharmony_ci return false; 435fb299fa2Sopenharmony_ci } 436fb299fa2Sopenharmony_ci LOG(INFO) << "PartitionCheckGptHeader ok"; 437fb299fa2Sopenharmony_ci return true; 438fb299fa2Sopenharmony_ci} 439fb299fa2Sopenharmony_ci 440fb299fa2Sopenharmony_civoid Ptable::PrintPtableInfo() const 441fb299fa2Sopenharmony_ci{ 442fb299fa2Sopenharmony_ci if (partitionInfo_.empty()) { 443fb299fa2Sopenharmony_ci LOG(ERROR) << "ptable vector is empty!"; 444fb299fa2Sopenharmony_ci return; 445fb299fa2Sopenharmony_ci } 446fb299fa2Sopenharmony_ci 447fb299fa2Sopenharmony_ci LOG(INFO) << "ptnInfo : ==========================================="; 448fb299fa2Sopenharmony_ci LOG(INFO) << "partition count = " << std::dec << partitionInfo_.size(); 449fb299fa2Sopenharmony_ci for (size_t i = 0; i < partitionInfo_.size(); i++) { 450fb299fa2Sopenharmony_ci LOG(INFO) << "ptable.entry[" << i << "].name=" << partitionInfo_[i].dispName.c_str() << 451fb299fa2Sopenharmony_ci ", startAddr=0x" << std::hex << partitionInfo_[i].startAddr << ", size=0x" << 452fb299fa2Sopenharmony_ci partitionInfo_[i].partitionSize << ", lun=" << std::dec << partitionInfo_[i].lun; 453fb299fa2Sopenharmony_ci } 454fb299fa2Sopenharmony_ci LOG(INFO) << "ptnInfo : ==========================================="; 455fb299fa2Sopenharmony_ci} 456fb299fa2Sopenharmony_ci 457fb299fa2Sopenharmony_civoid Ptable::PrintPtableInfo(const std::vector<PtnInfo> &ptnInfo) const 458fb299fa2Sopenharmony_ci{ 459fb299fa2Sopenharmony_ci if (ptnInfo.empty()) { 460fb299fa2Sopenharmony_ci LOG(ERROR) << "ptable vector is empty!"; 461fb299fa2Sopenharmony_ci return; 462fb299fa2Sopenharmony_ci } 463fb299fa2Sopenharmony_ci 464fb299fa2Sopenharmony_ci LOG(INFO) << "ptnInfo : ==========================================="; 465fb299fa2Sopenharmony_ci LOG(INFO) << "partition count = " << std::dec << ptnInfo.size(); 466fb299fa2Sopenharmony_ci for (size_t i = 0; i < ptnInfo.size(); i++) { 467fb299fa2Sopenharmony_ci LOG(INFO) << "ptable.entry[" << i << "].name=" << ptnInfo[i].dispName.c_str() << ", startAddr=0x" << 468fb299fa2Sopenharmony_ci std::hex << ptnInfo[i].startAddr << ", size=0x" << ptnInfo[i].partitionSize << ", lun=" << 469fb299fa2Sopenharmony_ci std::dec << ptnInfo[i].lun; 470fb299fa2Sopenharmony_ci } 471fb299fa2Sopenharmony_ci LOG(INFO) << "ptnInfo : ==========================================="; 472fb299fa2Sopenharmony_ci} 473fb299fa2Sopenharmony_ci 474fb299fa2Sopenharmony_civoid Ptable::ParsePartitionName(const uint8_t *data, const uint32_t dataLen, 475fb299fa2Sopenharmony_ci std::string &name, const uint32_t nameLen) 476fb299fa2Sopenharmony_ci{ 477fb299fa2Sopenharmony_ci if (data == nullptr || dataLen == 0 || nameLen == 0) { 478fb299fa2Sopenharmony_ci LOG(ERROR) << "dataLen == 0 || nameLen == 0"; 479fb299fa2Sopenharmony_ci return; 480fb299fa2Sopenharmony_ci } 481fb299fa2Sopenharmony_ci char utf16Name[MAX_GPT_NAME_SIZE] = {0}; 482fb299fa2Sopenharmony_ci if (memcpy_s(utf16Name, sizeof(utf16Name), data, dataLen) != EOK) { 483fb299fa2Sopenharmony_ci LOG(ERROR) << "memcpy name fail"; 484fb299fa2Sopenharmony_ci return; 485fb299fa2Sopenharmony_ci } 486fb299fa2Sopenharmony_ci 487fb299fa2Sopenharmony_ci std::string outName; 488fb299fa2Sopenharmony_ci // convert utf8 to utf16, 2 bytes for 1 charactor of partition name 489fb299fa2Sopenharmony_ci for (uint32_t n = 0; n < nameLen && n < (MAX_GPT_NAME_SIZE / 2) && utf16Name[n * 2] != '\0'; n++) { 490fb299fa2Sopenharmony_ci outName = outName + utf16Name[n * 2]; 491fb299fa2Sopenharmony_ci } 492fb299fa2Sopenharmony_ci for (uint32_t i = 0; i < outName.size(); i++) { 493fb299fa2Sopenharmony_ci outName[i] = static_cast<char>(toupper(outName[i])); 494fb299fa2Sopenharmony_ci } 495fb299fa2Sopenharmony_ci name = outName; 496fb299fa2Sopenharmony_ci return; 497fb299fa2Sopenharmony_ci} 498fb299fa2Sopenharmony_ci 499fb299fa2Sopenharmony_cibool Ptable::WriteBufferToPath(const std::string &path, const uint64_t offset, 500fb299fa2Sopenharmony_ci const uint8_t *buffer, const uint32_t size) 501fb299fa2Sopenharmony_ci{ 502fb299fa2Sopenharmony_ci std::unique_ptr<DataWriter> writer = DataWriter::CreateDataWriter(WRITE_RAW, path, offset); 503fb299fa2Sopenharmony_ci if (writer == nullptr) { 504fb299fa2Sopenharmony_ci LOG(ERROR) << "create writer class failed!"; 505fb299fa2Sopenharmony_ci return false; 506fb299fa2Sopenharmony_ci } 507fb299fa2Sopenharmony_ci bool ret = writer->Write(buffer, size, nullptr); 508fb299fa2Sopenharmony_ci if (!ret) { 509fb299fa2Sopenharmony_ci LOG(ERROR) << "writer to " << path << " with offset " << offset << " failed "; 510fb299fa2Sopenharmony_ci DataWriter::ReleaseDataWriter(writer); 511fb299fa2Sopenharmony_ci return false; 512fb299fa2Sopenharmony_ci } 513fb299fa2Sopenharmony_ci DataWriter::ReleaseDataWriter(writer); 514fb299fa2Sopenharmony_ci return true; 515fb299fa2Sopenharmony_ci} 516fb299fa2Sopenharmony_ci 517fb299fa2Sopenharmony_cibool Ptable::GetPartionInfoByName(const std::string &partitionName, PtnInfo &ptnInfo, int32_t &index) 518fb299fa2Sopenharmony_ci{ 519fb299fa2Sopenharmony_ci if (partitionInfo_.empty()) { 520fb299fa2Sopenharmony_ci LOG(ERROR) << "get partition failed! partitionInfo_ is empty"; 521fb299fa2Sopenharmony_ci return false; 522fb299fa2Sopenharmony_ci } 523fb299fa2Sopenharmony_ci for (int32_t i = 0; i < static_cast<int32_t>(partitionInfo_.size()); i++) { 524fb299fa2Sopenharmony_ci if (partitionInfo_[i].dispName.size() == partitionName.size() && 525fb299fa2Sopenharmony_ci strcasecmp(partitionInfo_[i].dispName.c_str(), partitionName.c_str()) == 0) { 526fb299fa2Sopenharmony_ci index = i; 527fb299fa2Sopenharmony_ci ptnInfo = partitionInfo_[i]; 528fb299fa2Sopenharmony_ci return true; 529fb299fa2Sopenharmony_ci } 530fb299fa2Sopenharmony_ci } 531fb299fa2Sopenharmony_ci LOG(ERROR) << "get partition info failed! Not found partition:" << partitionName; 532fb299fa2Sopenharmony_ci return false; 533fb299fa2Sopenharmony_ci} 534fb299fa2Sopenharmony_ci 535fb299fa2Sopenharmony_cibool Ptable::AdjustGpt(uint8_t *ptnInfoBuf, uint64_t bufSize, const std::string &ptnName, uint64_t preLastLBA, 536fb299fa2Sopenharmony_ci uint64_t lastPtnLastLBA) 537fb299fa2Sopenharmony_ci{ 538fb299fa2Sopenharmony_ci if (ptnInfoBuf == nullptr || bufSize == 0 || ptnName.empty()) { 539fb299fa2Sopenharmony_ci LOG(ERROR) << "invalid input"; 540fb299fa2Sopenharmony_ci return false; 541fb299fa2Sopenharmony_ci } 542fb299fa2Sopenharmony_ci if (ptnName != LAST_PATITION_NAME) { 543fb299fa2Sopenharmony_ci uint64_t firstLBA = GET_LLWORD_FROM_BYTE(&ptnInfoBuf[FIRST_LBA_OFFSET]); 544fb299fa2Sopenharmony_ci uint64_t lastLBA = GET_LLWORD_FROM_BYTE(&ptnInfoBuf[LAST_LBA_OFFSET]); 545fb299fa2Sopenharmony_ci lastLBA = lastLBA - firstLBA + preLastLBA + 1; 546fb299fa2Sopenharmony_ci firstLBA = preLastLBA + 1; 547fb299fa2Sopenharmony_ci PUT_LONG_LONG(ptnInfoBuf + FIRST_LBA_OFFSET, firstLBA); 548fb299fa2Sopenharmony_ci PUT_LONG_LONG(ptnInfoBuf + LAST_LBA_OFFSET, lastLBA); 549fb299fa2Sopenharmony_ci } else { /* this is USERDATA partition */ 550fb299fa2Sopenharmony_ci uint64_t firstLBA = preLastLBA + 1; 551fb299fa2Sopenharmony_ci if (lastPtnLastLBA < firstLBA) { 552fb299fa2Sopenharmony_ci LOG(ERROR) << "patch last partition fail"; 553fb299fa2Sopenharmony_ci return false; 554fb299fa2Sopenharmony_ci } 555fb299fa2Sopenharmony_ci PUT_LONG_LONG(ptnInfoBuf + FIRST_LBA_OFFSET, firstLBA); 556fb299fa2Sopenharmony_ci /* resize last partition by device density */ 557fb299fa2Sopenharmony_ci PUT_LONG_LONG(ptnInfoBuf + LAST_LBA_OFFSET, lastPtnLastLBA); 558fb299fa2Sopenharmony_ci } 559fb299fa2Sopenharmony_ci return true; 560fb299fa2Sopenharmony_ci} 561fb299fa2Sopenharmony_ci 562fb299fa2Sopenharmony_cibool Ptable::ChangeGpt(uint8_t *gptBuf, uint64_t gptSize, GptParseInfo gptInfo, PtnInfo &modifyInfo) 563fb299fa2Sopenharmony_ci{ 564fb299fa2Sopenharmony_ci if (gptBuf == nullptr || gptSize == 0 || gptSize <= gptInfo.imgBlockSize || gptInfo.devBlockSize == 0) { 565fb299fa2Sopenharmony_ci LOG(ERROR) << "input param invalid"; 566fb299fa2Sopenharmony_ci return false; 567fb299fa2Sopenharmony_ci } 568fb299fa2Sopenharmony_ci bool modifyDectect = false; 569fb299fa2Sopenharmony_ci uint8_t *gptHead = gptBuf + gptInfo.imgBlockSize; // skip pmbr 570fb299fa2Sopenharmony_ci uint32_t ptnEntrySize = GET_LLWORD_FROM_BYTE(&gptHead[PENTRY_SIZE_OFFSET]); 571fb299fa2Sopenharmony_ci uint64_t ptnStart = GET_LLWORD_FROM_BYTE(&gptHead[PARTITION_ENTRIES_OFFSET]); 572fb299fa2Sopenharmony_ci uint64_t readSize = ptnStart * gptInfo.imgBlockSize; 573fb299fa2Sopenharmony_ci uint8_t *ptnInfoBuf = gptBuf + readSize; 574fb299fa2Sopenharmony_ci uint64_t preLastLBA = 0; 575fb299fa2Sopenharmony_ci uint64_t lastPtnLastLBA = gptInfo.devDensity / gptInfo.devBlockSize - 1; 576fb299fa2Sopenharmony_ci 577fb299fa2Sopenharmony_ci while (readSize < gptSize) { 578fb299fa2Sopenharmony_ci std::string dispName; 579fb299fa2Sopenharmony_ci // convert utf8 to utf16, 2 bytes for 1 charactor of partition name 580fb299fa2Sopenharmony_ci ParsePartitionName(&ptnInfoBuf[GPT_PARTITION_NAME_OFFSET], MAX_GPT_NAME_SIZE, dispName, MAX_GPT_NAME_SIZE / 2); 581fb299fa2Sopenharmony_ci if (dispName.empty()) { 582fb299fa2Sopenharmony_ci break; 583fb299fa2Sopenharmony_ci } 584fb299fa2Sopenharmony_ci if (modifyDectect) { 585fb299fa2Sopenharmony_ci /* partition after modify part */ 586fb299fa2Sopenharmony_ci if (!AdjustGpt(ptnInfoBuf, gptSize - readSize, dispName, preLastLBA, lastPtnLastLBA)) { 587fb299fa2Sopenharmony_ci return false; 588fb299fa2Sopenharmony_ci } 589fb299fa2Sopenharmony_ci preLastLBA = GET_LLWORD_FROM_BYTE(&ptnInfoBuf[LAST_LBA_OFFSET]); 590fb299fa2Sopenharmony_ci ptnInfoBuf += ptnEntrySize; 591fb299fa2Sopenharmony_ci readSize += static_cast<uint64_t>(ptnEntrySize); 592fb299fa2Sopenharmony_ci continue; 593fb299fa2Sopenharmony_ci } 594fb299fa2Sopenharmony_ci if (dispName == modifyInfo.dispName) { 595fb299fa2Sopenharmony_ci LOG(INFO) << "modify part dectected!! dispName = " << dispName; 596fb299fa2Sopenharmony_ci uint64_t firstLBA = modifyInfo.startAddr / gptInfo.devBlockSize; 597fb299fa2Sopenharmony_ci uint64_t lastLBA = firstLBA + modifyInfo.partitionSize / gptInfo.devBlockSize - 1; 598fb299fa2Sopenharmony_ci if ((dispName == LAST_PATITION_NAME) && (lastLBA != lastPtnLastLBA)) { 599fb299fa2Sopenharmony_ci return false; 600fb299fa2Sopenharmony_ci } 601fb299fa2Sopenharmony_ci PUT_LONG_LONG(ptnInfoBuf + FIRST_LBA_OFFSET, firstLBA); 602fb299fa2Sopenharmony_ci PUT_LONG_LONG(ptnInfoBuf + LAST_LBA_OFFSET, lastLBA); 603fb299fa2Sopenharmony_ci modifyDectect = true; 604fb299fa2Sopenharmony_ci preLastLBA = lastLBA; 605fb299fa2Sopenharmony_ci } 606fb299fa2Sopenharmony_ci ptnInfoBuf += ptnEntrySize; 607fb299fa2Sopenharmony_ci readSize += static_cast<uint64_t>(ptnEntrySize); 608fb299fa2Sopenharmony_ci } 609fb299fa2Sopenharmony_ci return true; 610fb299fa2Sopenharmony_ci} 611fb299fa2Sopenharmony_ci} // namespace Updater