• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "update_processor.h"
16 #include <cstdio>
17 #include <memory>
18 #include <string>
19 #include <unistd.h>
20 #include <pthread.h>
21 #include "securec.h"
22 #include "applypatch/data_writer.h"
23 #include "applypatch/partition_record.h"
24 #include "applypatch/update_progress.h"
25 #include "dump.h"
26 #include "log.h"
27 #include "package/hash_data_verifier.h"
28 #include "pkg_manager.h"
29 #ifdef UPDATER_USE_PTABLE
30 #include "ptable_manager.h"
31 #endif
32 #include "script_instruction.h"
33 #include "script_manager.h"
34 #include "slot_info/slot_info.h"
35 #include "updater_main.h"
36 #include "updater/updater_const.h"
37 #include "update_bin/bin_process.h"
38 #include "scope_guard.h"
39 #include "bin_chunk_update.h"
40 
41 #define TYPE_ZIP_HEADER  0xaa
42 
43 using namespace Uscript;
44 using namespace Hpackage;
45 using namespace Updater;
46 
47 namespace Updater {
48 constexpr uint32_t BUFFER_SIZE = 50 * 1024;
49 constexpr uint32_t MAX_UPDATER_BUFFER_SIZE = 2 * BUFFER_SIZE;
50 constexpr uint32_t BYTE_SHIFT_8 = 8;
51 constexpr uint32_t BYTE_SHIFT_16 = 16;
52 constexpr uint32_t BYTE_SHIFT_24 = 24;
53 constexpr uint32_t SECOND_BUFFER = 2;
54 constexpr uint32_t THIRD_BUFFER = 3;
55 
56 enum UpdateStatus {
57     UPDATE_STATE_INIT = 0,
58     UPDATE_STATE_ONGOING,
59     UPDATE_STATE_FAILED,
60     UPDATE_STATE_SUCCESSFUL,
61     UPDATE_STATE_MAX
62 };
63 
ReadLE16(std::istream & is,uint16_t & value)64 bool ReadLE16(std::istream& is, uint16_t& value)
65 {
66     char buf[2] = {0}; // 2:定义2字节缓冲区,用于读取小端序的16位无符号整数(每字节8位)
67     if (!is.read(buf, sizeof(buf))) {
68         return false;
69     }
70     value = static_cast<uint16_t>(static_cast<unsigned char>(buf[0])) |
71            (static_cast<uint16_t>(static_cast<unsigned char>(buf[1])) << BYTE_SHIFT_8);
72     return true;
73 }
74 
ReadLE32(std::istream & is,uint32_t & value)75 bool ReadLE32(std::istream& is, uint32_t& value)
76 {
77     char buf[4] = {0}; // 4:定义4字节缓冲区,用于读取小端序的32位无符号整数(每字节8位)
78     if (!is.read(buf, sizeof(buf))) {
79         return false;
80     }
81     value = static_cast<uint32_t>(static_cast<unsigned char>(buf[0])) |
82            (static_cast<uint32_t>(static_cast<unsigned char>(buf[1])) << BYTE_SHIFT_8) |
83            (static_cast<uint32_t>(static_cast<unsigned char>(buf[SECOND_BUFFER])) << BYTE_SHIFT_16) |
84            (static_cast<uint32_t>(static_cast<unsigned char>(buf[THIRD_BUFFER])) << BYTE_SHIFT_24);
85     return true;
86 }
ProcessUpdateFile(const std::string & packagePath,FILE * pipeWrite)87 static int ProcessUpdateFile(const std::string &packagePath, FILE* pipeWrite)
88 {
89     std::shared_ptr<Updater::BinChunkUpdate> binChunkUpdate_ {};
90     // 打开输入文件
91     std::ifstream inFile(packagePath, std::ios::binary);
92     if (!inFile) {
93         LOG(ERROR) << "Error: Failed to open " << packagePath;
94         return UPDATE_ERROR;
95     }
96 
97     uint16_t type = 0;
98     if (!ReadLE16(inFile, type)) {
99         LOG(ERROR) << "Failed to read type";
100         return UPDATE_ERROR;
101     }
102 
103     if (type != TYPE_ZIP_HEADER) {
104         LOG(ERROR) << "Unsupported header type: 0x" << std::hex << type;
105         inFile.close();
106         return UPDATE_ERROR;
107     }
108     uint32_t length = 0;
109     if (!ReadLE32(inFile, length)) {
110         LOG(ERROR) << "Failed to read length";
111         return UPDATE_ERROR;
112     }
113 
114     if (!inFile.seekg(length, std::ios::cur)) {
115         inFile.close();
116         LOG(ERROR) << "Failed to seekg length";
117         return UPDATE_ERROR;
118     }
119 
120     // 读取剩余数据
121     std::vector<uint8_t> buffer_stream(BUFFER_SIZE);
122     binChunkUpdate_ = std::make_unique<Updater::BinChunkUpdate>(MAX_UPDATER_BUFFER_SIZE);
123     while (!inFile.eof()) {
124         inFile.read(reinterpret_cast<char*>(buffer_stream.data()), buffer_stream.size());
125         size_t readBytes = inFile.gcount();
126         uint32_t dealLen = 0;
127         if (readBytes > 0) {
128             UpdateResultCode ret = binChunkUpdate_->StartBinChunkUpdate(
129                 buffer_stream.data(), static_cast<uint32_t>(readBytes), dealLen);
130             if (STREAM_UPDATE_SUCCESS == ret) {
131                 LOG(INFO) << "StreamInstallProcesser ThreadExecuteFunc STREM_UPDATE_SUCCESS";
132             } else if (STREAM_UPDATE_FAILURE == ret) {
133                 LOG(ERROR) << "StreamInstallProcesser ThreadExecuteFunc STREM_UPDATE_FAILURE";
134                 return UPDATE_ERROR;
135             } else if (STREAM_UPDATE_COMPLETE == ret) {
136                 LOG(INFO) << "StreamInstallProcesser ThreadExecuteFunc STREM_UPDATE_COMPLETE";
137                 break;
138             }
139         }
140     }
141     inFile.close();
142     return UPDATE_SUCCESS;
143 }
144 
ProcessUpdaterStream(bool retry,int pipeFd,const std::string & packagePath,const std::string & keyPath)145 int ProcessUpdaterStream(bool retry, int pipeFd, const std::string &packagePath, const std::string &keyPath)
146 {
147     UPDATER_INIT_RECORD;
148     UpdaterInit::GetInstance().InvokeEvent(UPDATER_BINARY_INIT_EVENT);
149     Dump::GetInstance().RegisterDump("DumpHelperLog", std::make_unique<DumpHelperLog>());
150 
151     // 初始化管道
152     std::unique_ptr<FILE, decltype(&fclose)> pipeWrite(fdopen(pipeFd, "w"), fclose);
153     if (pipeWrite == nullptr) {
154         LOG(ERROR) << "Fail to fdopen, err: " << strerror(errno);
155         UPDATER_LAST_WORD(strerror(errno), "Fail to fdopen");
156         return EXIT_INVALID_ARGS;
157     }
158 
159     int ret = -1;
160     Detail::ScopeGuard guard([&] {
161         (void)fprintf(pipeWrite.get(), "subProcessResult:%d\n", ret);
162         (void)fflush(pipeWrite.get());
163     });
164     setlinebuf(pipeWrite.get());
165 
166     // 初始化包管理器
167     PkgManager::PkgManagerPtr pkgManager = PkgManager::CreatePackageInstance();
168     if (pkgManager == nullptr) {
169         LOG(ERROR) << "pkgManager is nullptr";
170         UPDATER_LAST_WORD(EXIT_INVALID_ARGS, "pkgManager is nullptr");
171         return EXIT_INVALID_ARGS;
172     }
173 
174     // 加载包
175     std::vector<std::string> components;
176     int loadRet = pkgManager->LoadPackage(packagePath, keyPath, components);
177     if (loadRet != PKG_SUCCESS) {
178         LOG(ERROR) << "Fail to load package";
179         PkgManager::ReleasePackageInstance(pkgManager);
180         UPDATER_LAST_WORD("Fail to load package", packagePath, keyPath);
181         return EXIT_INVALID_ARGS;
182     }
183 
184 #ifdef UPDATER_USE_PTABLE
185     // 分区表操作
186     if (!PackagePtable::GetInstance().WritePtableWithFile()) {
187         LOG(ERROR) << "write ptable with file fail";
188         PkgManager::ReleasePackageInstance(pkgManager);
189         UPDATER_LAST_WORD("Error to write ptable with file");
190         return EXIT_EXEC_SCRIPT_ERROR;
191     }
192     if (!DevicePtable::GetInstance().LoadPartitionInfo()) {
193         PkgManager::ReleasePackageInstance(pkgManager);
194         return EXIT_EXEC_SCRIPT_ERROR;
195     }
196 #endif
197 
198     // 调用核心函数并传递管道
199     ret = ProcessUpdateFile(packagePath, pipeWrite.get());
200     if (ret != UPDATE_SUCCESS) {
201         LOG(ERROR) << "ProcessUpdaterStream failed with code: " << ret;
202     }
203 
204     // 释放资源
205     PkgManager::ReleasePackageInstance(pkgManager);
206     return ret;
207 }
208 } // Updater