• 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 "pkg_utils.h"
16 #ifdef _WIN32
17 #include <windows.h>
18 #else
19 #include <climits>
20 #include <sys/mman.h>
21 #endif
22 #include <cstring>
23 #include <fcntl.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
26 #include "utils.h"
27 
28 namespace Hpackage {
29 #ifdef _WIN32
30 #undef ERROR
31 #endif
32 
33 #ifdef __APPLE__
34 #define MAP_POPULATE 0x08000
35 #endif
36 
37 constexpr int32_t MIN_YEAR = 80;
38 constexpr uint32_t TM_YEAR_BITS = 9;
39 constexpr uint32_t TM_MON_BITS = 5;
40 constexpr uint32_t TM_MIN_BITS = 5;
41 constexpr uint32_t TM_HOUR_BITS = 11;
42 constexpr uint32_t BYTE_SIZE = 8;
43 constexpr uint32_t MAX_MEM_SIZE = 1 << 29;
44 constexpr uint32_t SECOND_BUFFER = 2;
45 constexpr uint32_t THIRD_BUFFER = 3;
46 constexpr uint8_t SHIFT_RIGHT_FOUR_BITS = 4;
47 
48 using namespace Updater::Utils;
49 
GetFilePath(const std::string & fileName)50 std::string GetFilePath(const std::string &fileName)
51 {
52     std::size_t pos = fileName.find_last_of('/');
53     if (pos == std::string::npos) {
54         pos = fileName.find_last_of('\\');
55     }
56     return fileName.substr(0, pos + 1);
57 }
58 
GetFileSize(const std::string & fileName)59 size_t GetFileSize(const std::string &fileName)
60 {
61     char realPath[PATH_MAX] = { 0 };
62 #ifdef _WIN32
63     if (_fullpath(realPath, fileName.c_str(), PATH_MAX) == nullptr) {
64 #else
65     if (realpath(fileName.c_str(), realPath) == nullptr) {
66 #endif
67         PKG_LOGE("realPath is null");
68         return 0;
69     }
70     FILE *fp = fopen(realPath, "r");
71     if (fp == nullptr) {
72         PKG_LOGE("Invalid file %s", fileName.c_str());
73         return 0;
74     }
75 
76     if (fseek(fp, 0, SEEK_END) < 0) {
77         PKG_LOGE("return value of fseek < 0");
78         fclose(fp);
79         return 0;
80     }
81     long size = ftell(fp);
82     if (size < 0) {
83         PKG_LOGE("return value of ftell < 0");
84         fclose(fp);
85         return 0;
86     }
87     fclose(fp);
88     // return file size in bytes
89     return static_cast<size_t>(size);
90 }
91 
92 std::string GetName(const std::string &filePath)
93 {
94     return filePath.substr(filePath.find_last_of("/") + 1);
95 }
96 
97 int32_t CheckFile(const std::string &fileName)
98 {
99     // Check if the directory of @fileName is exist or has write permission
100     // If not, Create the directory first.
101     std::string path = GetFilePath(fileName);
102     if (path.empty()) {
103         return PKG_SUCCESS;
104     }
105     if (access(path.c_str(), F_OK) == -1) {
106 #ifdef __WIN32
107         mkdir(path.c_str());
108 #else
109         mkdir(path.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
110 #endif
111     }
112     // If the path writable
113     int ret = access(path.c_str(), R_OK | W_OK);
114     if (ret == -1) {
115         PKG_LOGE("file %s no permission ", fileName.c_str());
116         return PKG_NONE_PERMISSION;
117     }
118     return PKG_SUCCESS;
119 }
120 
121 uint8_t *MapMemory(const std::string &fileName, size_t size)
122 {
123     if (size > MAX_MEM_SIZE) {
124         PKG_LOGE("Size bigger for alloc memory");
125         return nullptr;
126     }
127     void *mappedData = nullptr;
128     // Map the file to memory
129     mappedData = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_POPULATE | MAP_ANON, -1, 0);
130     if (mappedData == MAP_FAILED) {
131         PKG_LOGE("Failed to mmap file %s ", fileName.c_str());
132         return nullptr;
133     }
134     return static_cast<uint8_t *>(mappedData);
135 }
136 
137 void ReleaseMemory(uint8_t *memMap, size_t size)
138 {
139     if (size <= 0 || memMap == nullptr) {
140         PKG_LOGE("Size must > 0");
141         return;
142     }
143     // Flush memory and release memory.
144     msync(static_cast<void *>(memMap), size, MS_ASYNC);
145     munmap(memMap, size);
146 }
147 
148 std::string GetCurrPath()
149 {
150     std::string path;
151     char *buffer = getcwd(nullptr, 0);
152     if (buffer == nullptr) {
153         PKG_LOGE("getcwd error");
154         return "./";
155     }
156     path.assign(buffer);
157     free(buffer);
158     return path + "/";
159 }
160 
161 void ExtraTimeAndDate(time_t when, uint16_t &date, uint16_t &time)
162 {
163     when = static_cast<time_t>((static_cast<unsigned long>(when) + 1) & (~1));
164     struct tm nowTime {};
165 #ifdef __WIN32
166     localtime_s(&nowTime, &when);
167 #else
168     localtime_r(&when, &nowTime);
169 #endif
170     int year = nowTime.tm_year;
171     if (year < MIN_YEAR) {
172         year = MIN_YEAR;
173     }
174     date = static_cast<uint16_t>(static_cast<uint16_t>(year - MIN_YEAR) << TM_YEAR_BITS);
175     date |= static_cast<uint16_t>(static_cast<uint16_t>(nowTime.tm_mon + 1) << TM_MON_BITS);
176     date |= static_cast<uint16_t>(nowTime.tm_mday);
177     time = static_cast<uint16_t>(static_cast<uint16_t>(nowTime.tm_hour) << TM_HOUR_BITS);
178     time |= static_cast<uint16_t>(static_cast<uint16_t>(nowTime.tm_min) << TM_MIN_BITS);
179     time |= static_cast<uint16_t>(static_cast<uint16_t>(nowTime.tm_sec) >> 1);
180 }
181 
182 uint32_t ReadLE32(const uint8_t *buff)
183 {
184     if (buff == nullptr) {
185         PKG_LOGE("buff is null");
186         return 0;
187     }
188     size_t offset = 0;
189     uint32_t value32 = buff[0];
190     offset += BYTE_SIZE;
191     value32 += static_cast<uint32_t>(static_cast<uint32_t>(buff[1]) << offset);
192     offset +=  BYTE_SIZE;
193     value32 += static_cast<uint32_t>(static_cast<uint32_t>(buff[SECOND_BUFFER]) << offset);
194     offset += BYTE_SIZE;
195     value32 += static_cast<uint32_t>(static_cast<uint32_t>(buff[THIRD_BUFFER]) << offset);
196     return value32;
197 }
198 
199 uint64_t ReadLE64(const uint8_t *buff)
200 {
201     if (buff == nullptr) {
202         PKG_LOGE("buff is null");
203         return 0;
204     }
205     uint32_t low = ReadLE32(buff);
206     uint32_t high = ReadLE32(buff + sizeof(uint32_t));
207     uint64_t value = ((static_cast<uint64_t>(high)) << (BYTE_SIZE * sizeof(uint32_t))) | low;
208     return value;
209 }
210 
211 void WriteLE32(uint8_t *buff, uint32_t value)
212 {
213     if (buff == nullptr) {
214         PKG_LOGE("buff is null");
215         return;
216     }
217     size_t offset = 0;
218     buff[0] = static_cast<uint8_t>(value);
219     offset += BYTE_SIZE;
220     buff[1] = static_cast<uint8_t>(value >> offset);
221     offset += BYTE_SIZE;
222     buff[SECOND_BUFFER] = static_cast<uint8_t>(value >> offset);
223     offset += BYTE_SIZE;
224     buff[THIRD_BUFFER] = static_cast<uint8_t>(value >> offset);
225 }
226 
227 uint16_t ReadLE16(const uint8_t *buff)
228 {
229     if (buff == nullptr) {
230         PKG_LOGE("buff is null");
231         return 0;
232     }
233     uint16_t value16 = buff[0];
234     value16 += static_cast<uint16_t>(buff[1] << BYTE_SIZE);
235     return value16;
236 }
237 
238 void WriteLE16(uint8_t *buff, uint16_t value)
239 {
240     if (buff == nullptr) {
241         PKG_LOGE("buff is null");
242         return;
243     }
244     buff[0] = static_cast<uint8_t>(value);
245     buff[1] = static_cast<uint8_t>(value >> BYTE_SIZE);
246 }
247 
248 std::string ConvertShaHex(const std::vector<uint8_t> &shaDigest)
249 {
250     const std::string hexChars = "0123456789abcdef";
251     std::string haxSha256 = "";
252     unsigned int c;
253     for (size_t i = 0; i < shaDigest.size(); ++i) {
254         auto d = shaDigest[i];
255         c = (d >> SHIFT_RIGHT_FOUR_BITS) & 0xf;     // last 4 bits
256         haxSha256.push_back(hexChars[c]);
257         haxSha256.push_back(hexChars[d & 0xf]);
258     }
259     return haxSha256;
260 }
261 } // namespace Hpackage
262 
263 #ifdef _WIN32
mmap(void * addr,size_t length,int prot,int flags,int fd,size_t offset)264 void *mmap([[maybe_unused]] void *addr, [[maybe_unused]] size_t length,
265     [[maybe_unused]] int prot, [[maybe_unused]] int flags, int fd, [[maybe_unused]] size_t offset)
266 {
267     HANDLE FileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
268     if (FileHandle == INVALID_HANDLE_VALUE) {
269         return MAP_FAILED;
270     }
271     HANDLE FileMappingHandle = ::CreateFileMappingW(FileHandle, 0, PAGE_READONLY, 0, 0, 0);
272     if (FileMappingHandle == nullptr) {
273         PKG_LOGE("CreateFileMappingW Failed");
274         return MAP_FAILED;
275     }
276     void *mapAddr = ::MapViewOfFile(FileMappingHandle, FILE_MAP_READ, 0, 0, 0);
277     if (mapAddr == nullptr) {
278         PKG_LOGE("MapViewOfFile Failed");
279         ::CloseHandle(FileMappingHandle);
280         return MAP_FAILED;
281     }
282     ::CloseHandle(FileMappingHandle);
283     return mapAddr;
284 }
285 
msync(void * addr,size_t len,int flags)286 int msync(void *addr, size_t len, [[maybe_unused]] int flags)
287 {
288     return FlushViewOfFile(addr, len);
289 }
290 
munmap(void * addr,size_t len)291 int munmap(void *addr, [[maybe_unused]] size_t len)
292 {
293     return !UnmapViewOfFile(addr);
294 }
295 #endif
296