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
16 #include "package_file.h"
17
18 #include <fstream>
19
20 #include "db_errno.h"
21 #include "value_hash_calc.h"
22 #include "parcel.h"
23 #include "platform_specific.h"
24
25 namespace DistributedDB {
26 using std::string;
27 using std::vector;
28 using std::list;
29 using std::ifstream;
30 using std::ofstream;
31 using std::ios;
32 using std::ios_base;
33
34 namespace {
35 constexpr uint32_t MAX_FILE_NAME_LEN = 256;
36 constexpr uint32_t CHECKSUM_LEN = SHA256_DIGEST_LENGTH;
37 constexpr uint32_t CHECKSUM_BLOCK_SIZE = 64;
38 constexpr uint32_t DEVICE_ID_LEN = SHA256_DIGEST_LENGTH;
39 constexpr uint32_t MAGIC_LEN = 16;
40 constexpr uint32_t CURRENT_VERSION = 0;
41 constexpr uint64_t BUFFER_LEN = 4096;
42 const string MAGIC = "HW package file";
43 const string FILE_SEPARATOR = "/";
44 const string INVALID_FILE_WORDS = "..";
45
46 const uint32_t FILE_HEADER_LEN = MAGIC_LEN + CHECKSUM_LEN + DEVICE_ID_LEN + Parcel::GetUInt32Len() * 3;
47 const uint32_t FILE_CONTEXT_LEN = MAX_FILE_NAME_LEN + Parcel::GetUInt32Len() * 2 + Parcel::GetUInt64Len() * 2;
48 }
49
50 struct FileContext {
51 char fileName[MAX_FILE_NAME_LEN] = {0};
52 uint32_t fileType = 0;
53 uint32_t parentID = 0;
54 uint64_t fileLen = 0;
55 uint64_t offset = 0;
56 };
57
Clear(ofstream & target,const string & targetFile)58 static void Clear(ofstream &target, const string &targetFile)
59 {
60 if (target.is_open()) {
61 target.close();
62 }
63 if (OS::RemoveFile(targetFile) != E_OK) {
64 LOGE("Remove file failed.");
65 }
66 }
67
GetChecksum(const string & file,vector<char> & result)68 static int GetChecksum(const string &file, vector<char> &result)
69 {
70 ifstream fileHandle(file, ios::in | ios::binary);
71 if (!fileHandle.good()) {
72 LOGE("[GetChecksum]Error fileHandle! sys[%d]", errno);
73 return -E_INVALID_PATH;
74 }
75 ValueHashCalc calc;
76 int errCode = calc.Initialize();
77 if (errCode != E_OK) {
78 LOGE("[GetChecksum]Calc Initialize fail!");
79 return errCode;
80 }
81 fileHandle.seekg(static_cast<int64_t>(MAGIC_LEN + Parcel::GetUInt32Len() + CHECKSUM_LEN), ios_base::beg);
82 vector<uint8_t> buffer(CHECKSUM_BLOCK_SIZE, 0);
83 bool readEnd = false;
84 while (!readEnd) {
85 fileHandle.read(reinterpret_cast<char *>(buffer.data()), buffer.size());
86 if (fileHandle.eof()) {
87 readEnd = true;
88 } else if (!fileHandle.good()) {
89 LOGE("[GetChecksum]fileHandle error! sys[%d]", errno);
90 return -E_INVALID_PATH;
91 }
92 errCode = calc.Update(buffer);
93 if (errCode != E_OK) {
94 LOGE("[GetChecksum]Calc Update fail!");
95 return errCode;
96 }
97 buffer.assign(CHECKSUM_BLOCK_SIZE, 0);
98 }
99 vector<uint8_t> resultBuf;
100 errCode = calc.GetResult(resultBuf);
101 if (errCode != E_OK) {
102 LOGE("[GetChecksum]Calc GetResult fail!");
103 return errCode;
104 }
105 result.assign(resultBuf.begin(), resultBuf.end());
106 return E_OK;
107 }
108
GetFileContexts(const string & sourcePath,list<FileContext> & fileContexts)109 static int GetFileContexts(const string &sourcePath, list<FileContext> &fileContexts)
110 {
111 list<OS::FileAttr> files;
112 int errCode = OS::GetFileAttrFromPath(sourcePath, files, false);
113 if (errCode != E_OK) {
114 LOGE("[GetFileContexts] get file attr from path fail, errCode = [%d]", errCode);
115 return errCode;
116 }
117 FileContext fileContext;
118 int countLimit = 0;
119 for (auto file = files.begin(); file != files.end(); file++, countLimit++) {
120 if (countLimit > 20) { // Limit number of files 20 for security
121 LOGE("Too deep access for get file context!");
122 return -E_INVALID_PATH;
123 }
124
125 if (file->fileType != OS::FILE && file->fileType != OS::PATH) {
126 continue;
127 }
128
129 errCode = memset_s(fileContext.fileName, MAX_FILE_NAME_LEN, 0, MAX_FILE_NAME_LEN);
130 if (errCode != EOK) {
131 return -E_SECUREC_ERROR;
132 }
133
134 if (file->fileName.size() >= MAX_FILE_NAME_LEN) {
135 LOGE("file name is too long!");
136 return -E_INVALID_FILE;
137 }
138
139 errCode = memcpy_s(fileContext.fileName, MAX_FILE_NAME_LEN, file->fileName.c_str(), file->fileName.size());
140 if (errCode != EOK) {
141 return -E_SECUREC_ERROR;
142 }
143
144 fileContext.fileLen = file->fileLen;
145 fileContext.fileType = file->fileType;
146 fileContexts.push_back(fileContext);
147 }
148 LOGD("Get file contexts, fileContexts size is [%zu]", fileContexts.size());
149 return E_OK;
150 }
151
FileContentCopy(ifstream & sourceFile,ofstream & targetFile,uint64_t fileLen)152 static int FileContentCopy(ifstream &sourceFile, ofstream &targetFile, uint64_t fileLen)
153 {
154 uint64_t leftLen = fileLen;
155 vector<char> buffer(BUFFER_LEN, 0);
156 while (leftLen > 0) {
157 uint64_t readLen = (leftLen > BUFFER_LEN) ? BUFFER_LEN : leftLen;
158 sourceFile.read(buffer.data(), readLen);
159 if (!sourceFile.good()) {
160 LOGE("[FileContentCopy] SourceFile error! sys[%d]", errno);
161 return -E_INVALID_PATH;
162 }
163 targetFile.write(buffer.data(), readLen);
164 if (!targetFile.good()) {
165 LOGE("[FileContentCopy] TargetFile error! sys[%d]", errno);
166 return -E_INVALID_PATH;
167 }
168 leftLen -= readLen;
169 }
170 return E_OK;
171 }
172
PackFileHeader(ofstream & targetFile,const FileInfo & fileInfo,uint32_t fileNum)173 static int PackFileHeader(ofstream &targetFile, const FileInfo &fileInfo, uint32_t fileNum)
174 {
175 if (fileInfo.deviceID.size() != DEVICE_ID_LEN) {
176 return -E_INVALID_ARGS;
177 }
178 vector<uint8_t> buffer(FILE_HEADER_LEN, 0);
179 vector<char> checksum(CHECKSUM_LEN, 0);
180 Parcel parcel(buffer.data(), FILE_HEADER_LEN);
181
182 int errCode = parcel.WriteBlob(MAGIC.c_str(), MAGIC_LEN);
183 if (errCode != E_OK) {
184 return errCode;
185 }
186 // before current version package version is always 0
187 errCode = parcel.WriteUInt32(CURRENT_VERSION);
188 if (errCode != E_OK) {
189 return errCode;
190 }
191 errCode = parcel.WriteBlob(checksum.data(), CHECKSUM_LEN);
192 if (errCode != E_OK) {
193 return errCode;
194 }
195 errCode = parcel.WriteBlob(fileInfo.deviceID.c_str(), DEVICE_ID_LEN);
196 if (errCode != E_OK) {
197 return errCode;
198 }
199 errCode = parcel.WriteUInt32(fileInfo.dbType);
200 if (errCode != E_OK) {
201 return errCode;
202 }
203 errCode = parcel.WriteUInt32(fileNum);
204 if (errCode != E_OK) {
205 return errCode;
206 }
207 targetFile.write(reinterpret_cast<char *>(buffer.data()), buffer.size());
208 if (!targetFile.good()) {
209 LOGE("[PackFileHeader] TargetFile error! sys[%d]", errno);
210 return -E_INVALID_PATH;
211 }
212 return E_OK;
213 }
214
CheckMagicHeader(Parcel & fileHeaderParcel)215 static int CheckMagicHeader(Parcel &fileHeaderParcel)
216 {
217 vector<char> buffer(MAGIC_LEN, 0);
218 (void)fileHeaderParcel.ReadBlob(buffer.data(), MAGIC_LEN);
219 if (fileHeaderParcel.IsError()) {
220 LOGE("[CheckMagicHeader]fileHeaderParcel error!");
221 return -E_PARSE_FAIL;
222 }
223 if (memcmp(MAGIC.c_str(), buffer.data(), MAGIC_LEN) != 0) {
224 return -E_INVALID_FILE;
225 }
226 return E_OK;
227 }
228
UnpackFileHeader(ifstream & sourceFile,const string & sourceFileName,FileInfo & fileInfo,uint32_t & fileNum)229 static int UnpackFileHeader(ifstream &sourceFile, const string &sourceFileName, FileInfo &fileInfo, uint32_t &fileNum)
230 {
231 vector<uint8_t> fileHeader(FILE_HEADER_LEN, 0);
232 sourceFile.read(reinterpret_cast<char *>(fileHeader.data()), FILE_HEADER_LEN);
233 if (!sourceFile.good()) {
234 LOGE("UnpackFileHeader sourceFile error! sys[%d]", errno);
235 return -E_INVALID_FILE;
236 }
237 Parcel parcel(fileHeader.data(), FILE_HEADER_LEN);
238 int errCode = CheckMagicHeader(parcel);
239 if (errCode != E_OK) {
240 return errCode;
241 }
242 uint32_t version;
243 vector<char> buffer(CHECKSUM_LEN, 0);
244 (void)parcel.ReadUInt32(version);
245 (void)parcel.ReadBlob(buffer.data(), CHECKSUM_LEN);
246 if (parcel.IsError()) {
247 LOGE("UnpackFileHeader parcel version error!");
248 return -E_PARSE_FAIL;
249 }
250 vector<char> checksum(CHECKSUM_LEN, 0);
251 errCode = GetChecksum(sourceFileName, checksum);
252 if (errCode != E_OK) {
253 LOGE("Get checksum failed.");
254 return errCode;
255 }
256 if (buffer != checksum) {
257 LOGE("Checksum check failed.");
258 return -E_INVALID_FILE;
259 }
260 buffer.resize(DEVICE_ID_LEN);
261 (void)parcel.ReadBlob(buffer.data(), DEVICE_ID_LEN);
262 if (parcel.IsError()) {
263 return -E_PARSE_FAIL;
264 }
265 fileInfo.deviceID.resize(DEVICE_ID_LEN);
266 fileInfo.deviceID.assign(buffer.begin(), buffer.end());
267 (void)parcel.ReadUInt32(fileInfo.dbType);
268 (void)parcel.ReadUInt32(fileNum);
269 if (parcel.IsError()) {
270 LOGE("UnpackFileHeader parcel dbType error!");
271 return -E_PARSE_FAIL;
272 }
273 return E_OK;
274 }
275
PackFileContext(ofstream & targetFile,const FileContext & fileContext)276 static int PackFileContext(ofstream &targetFile, const FileContext &fileContext)
277 {
278 vector<uint8_t> buffer(FILE_CONTEXT_LEN, 0);
279 Parcel parcel(buffer.data(), FILE_CONTEXT_LEN);
280 int errCode = parcel.WriteBlob(fileContext.fileName, MAX_FILE_NAME_LEN);
281 if (errCode != E_OK) {
282 LOGE("PackFileContext fileContext fileName error!");
283 return errCode;
284 }
285 errCode = parcel.WriteUInt32(fileContext.fileType);
286 if (errCode != E_OK) {
287 return errCode;
288 }
289 errCode = parcel.WriteUInt32(0);
290 if (errCode != E_OK) {
291 return errCode;
292 }
293 errCode = parcel.WriteUInt64(fileContext.fileLen);
294 if (errCode != E_OK) {
295 return errCode;
296 }
297 errCode = parcel.WriteUInt64(fileContext.offset);
298 if (errCode != E_OK) {
299 return errCode;
300 }
301 targetFile.write(reinterpret_cast<char *>(buffer.data()), buffer.size());
302 if (!targetFile.good()) {
303 LOGE("[PackFileContext] TargetFile error! sys[%d]", errno);
304 return -E_INVALID_PATH;
305 }
306 return E_OK;
307 }
308
UnpackFileContext(ifstream & sourceFile,FileContext & fileContext)309 static int UnpackFileContext(ifstream &sourceFile, FileContext &fileContext)
310 {
311 vector<uint8_t> buffer(FILE_CONTEXT_LEN, 0);
312 sourceFile.read(reinterpret_cast<char *>(buffer.data()), buffer.size());
313 if (!sourceFile.good()) {
314 LOGE("[UnpackFileContext] sourceFile read error! sys[%d]", errno);
315 return -E_INVALID_PATH;
316 }
317 Parcel parcel(buffer.data(), FILE_CONTEXT_LEN);
318 (void)parcel.ReadBlob(fileContext.fileName, MAX_FILE_NAME_LEN);
319 (void)parcel.ReadUInt32(fileContext.fileType);
320 (void)parcel.ReadUInt32(fileContext.parentID);
321 (void)parcel.ReadUInt64(fileContext.fileLen);
322 (void)parcel.ReadUInt64(fileContext.offset);
323 if (parcel.IsError()) {
324 return -E_PARSE_FAIL;
325 }
326 return E_OK;
327 }
328
PackFileContent(ofstream & targetFile,const string & sourcePath,const FileContext & fileContext)329 static int PackFileContent(ofstream &targetFile, const string &sourcePath, const FileContext &fileContext)
330 {
331 if (fileContext.fileType != OS::FILE) {
332 return E_OK;
333 }
334 string fileName = sourcePath + fileContext.fileName;
335 ifstream file(fileName, ios::in | ios::binary);
336 if (!file.good()) {
337 LOGE("[PackFileContent] File error! sys[%d]", errno);
338 return -E_INVALID_PATH;
339 }
340 file.seekg(0, ios_base::end);
341 if (!file.good()) {
342 LOGE("[PackFileContent]file error after seekg! sys[%d]", errno);
343 return -E_INVALID_PATH;
344 }
345 if (file.tellg() < 0) {
346 LOGE("[PackFileContent]file error after tellg! sys[%d]", errno);
347 return -E_INVALID_PATH;
348 }
349 uint64_t fileLen = static_cast<uint64_t>(file.tellg());
350 file.seekg(0, ios_base::beg);
351 if (!file.good()) {
352 LOGE("[PackFileContent]file error after seekg fileLen! sys[%d]", errno);
353 return -E_INVALID_PATH;
354 }
355
356 return FileContentCopy(file, targetFile, fileLen);
357 }
358
UnpackFileContent(ifstream & sourceFile,const string & targetPath,const FileContext & fileContext)359 static int UnpackFileContent(ifstream &sourceFile, const string &targetPath, const FileContext &fileContext)
360 {
361 if (fileContext.fileType != OS::FILE) {
362 return E_OK;
363 }
364
365 string fileName = fileContext.fileName;
366 fileName = targetPath + FILE_SEPARATOR + fileName;
367
368 // check if fileName contains the words ".."
369 std::string::size_type pos = fileName.find(INVALID_FILE_WORDS);
370 if (pos != std::string::npos) {
371 LOGE("[UnpackFileContent]fileName contains the words double dot!!!");
372 return -E_INVALID_PATH;
373 }
374
375 ofstream file(fileName, ios::out | ios::binary);
376 if (!file.good()) {
377 file.close();
378 LOGE("[UnpackFileContent]filehandle error. sys[%d]", errno);
379 return -E_INVALID_PATH;
380 }
381 int errCode = FileContentCopy(sourceFile, file, fileContext.fileLen);
382 file.close();
383 return errCode;
384 }
385
WriteChecksum(const string & targetFile)386 static int WriteChecksum(const string &targetFile)
387 {
388 vector<char> checksum(CHECKSUM_LEN, 0);
389 int errCode = GetChecksum(targetFile, checksum);
390 if (errCode != E_OK) {
391 LOGE("Get checksum failed.");
392 return errCode;
393 }
394 ofstream targetHandle(targetFile, ios::in | ios::out | ios::binary);
395 if (!targetHandle.good()) {
396 Clear(targetHandle, targetFile);
397 LOGE("[WriteChecksum]targetHandle error, sys err [%d]", errno);
398 return -E_INVALID_PATH;
399 }
400 targetHandle.seekp(static_cast<int64_t>(MAGIC_LEN + Parcel::GetUInt32Len()), ios_base::beg);
401 if (!targetHandle.good()) {
402 Clear(targetHandle, targetFile);
403 LOGE("[WriteChecksum]targetHandle error after seekp, sys err [%d]", errno);
404 return -E_INVALID_PATH;
405 }
406 targetHandle.write(checksum.data(), checksum.size());
407 if (!targetHandle.good()) {
408 Clear(targetHandle, targetFile);
409 LOGE("[WriteChecksum]targetHandle error after write, sys err [%d]", errno);
410 return -E_INVALID_PATH;
411 }
412 targetHandle.close();
413 return E_OK;
414 }
415
CopyFilePermissions(const string & sourceFile,const string & targetFile)416 static int CopyFilePermissions(const string &sourceFile, const string &targetFile)
417 {
418 uint32_t permissions;
419 int errCode = OS::GetFilePermissions(sourceFile, permissions);
420 if (errCode != E_OK) {
421 LOGE("Get file permissions failed.");
422 return errCode;
423 }
424 errCode = OS::SetFilePermissions(targetFile, permissions);
425 if (errCode != E_OK) {
426 LOGE("Set file permissions failed.");
427 }
428 return errCode;
429 }
430
PackageFiles(const string & sourcePath,const string & targetFile,const FileInfo & fileInfo)431 int PackageFile::PackageFiles(const string &sourcePath, const string &targetFile,
432 const FileInfo &fileInfo)
433 {
434 int errCode = ExePackage(sourcePath, targetFile, fileInfo);
435 if (errno == EKEYREVOKED) {
436 errCode = -E_EKEYREVOKED;
437 LOGE("[PackageFile][PackageFiles] Forbid access files errCode [%d].", errCode);
438 }
439 return errCode;
440 }
441
GetPackageVersion(const std::string & sourceFile,uint32_t & version)442 int PackageFile::GetPackageVersion(const std::string &sourceFile, uint32_t &version)
443 {
444 int errCode = E_OK;
445 vector<uint8_t> fileHeader(FILE_HEADER_LEN, 0);
446 Parcel parcel(fileHeader.data(), FILE_HEADER_LEN);
447
448 ifstream sourceHandle(sourceFile, ios::in | ios::binary);
449 if (!sourceHandle.good()) {
450 LOGE("sourceHandle error, sys err [%d]", errno);
451 errCode = -E_INVALID_PATH;
452 goto END;
453 }
454
455 sourceHandle.read(reinterpret_cast<char *>(fileHeader.data()), FILE_HEADER_LEN);
456 if (!sourceHandle.good()) {
457 LOGE("[GetPackageVersion] read sourceFile handle error! sys[%d]", errno);
458 errCode = -E_INVALID_PATH;
459 goto END;
460 }
461
462 errCode = CheckMagicHeader(parcel);
463 if (errCode != E_OK) { // LCOV_EXCL_BR_LINE
464 errCode = -E_INVALID_PATH;
465 goto END;
466 }
467
468 (void)parcel.ReadUInt32(version);
469 END:
470 if (errno == EKEYREVOKED) {
471 errCode = -E_EKEYREVOKED;
472 LOGE("[PackageFile][PackageFiles] Forbid access files by secLabel, errCode [%d].", errCode);
473 }
474 return errCode;
475 }
476
ExePackage(const string & sourcePath,const string & targetFile,const FileInfo & fileInfo)477 int PackageFile::ExePackage(const string &sourcePath, const string &targetFile, const FileInfo &fileInfo)
478 {
479 list<FileContext> fileContexts;
480 int errCode = GetFileContexts(sourcePath, fileContexts);
481 if (errCode != E_OK) {
482 return errCode;
483 }
484 if (fileContexts.empty()) {
485 return -E_EMPTY_PATH;
486 }
487 bool targetExists = OS::CheckPathExistence(targetFile);
488 ofstream targetHandle(targetFile, ios::out | ios::binary);
489 if (!targetHandle.good()) {
490 Clear(targetHandle, targetFile);
491 LOGE("[PackageFiles]targetHandle error, sys err [%d], [%zu]", errno, fileContexts.size());
492 return -E_INVALID_PATH;
493 }
494
495 std::string fileName = string(fileContexts.front().fileName);
496 errCode = CopyFilePermissionsIfNeed(targetExists, sourcePath, fileName, targetFile, targetHandle);
497 if (errCode != E_OK) {
498 return errCode;
499 }
500
501 errCode = PackFileHeader(targetHandle, fileInfo, static_cast<uint32_t>(fileContexts.size()));
502 if (errCode != E_OK) {
503 Clear(targetHandle, targetFile);
504 LOGE("[PackageFiles]Pack file header err[%d]!!!", errCode);
505 return errCode;
506 }
507 // FILE_HEADER_LEN is 92, FILE_CONTEXT_LEN is 280, fileContexts.size() < UINT_MAX, the offset will never overflow.
508 uint64_t offset = FILE_HEADER_LEN + FILE_CONTEXT_LEN * static_cast<uint64_t>(fileContexts.size());
509 for (auto &file : fileContexts) {
510 file.offset = offset;
511 errCode = PackFileContext(targetHandle, file);
512 if (errCode != E_OK) {
513 Clear(targetHandle, targetFile);
514 LOGE("[PackageFiles]Pack file context err[%d]!!!", errCode);
515 return errCode;
516 }
517 offset += file.fileLen;
518 }
519 for (const auto &file : fileContexts) {
520 // If file type is path no need pack content in PackFileContent
521 errCode = PackFileContent(targetHandle, sourcePath, file);
522 if (errCode != E_OK) {
523 Clear(targetHandle, targetFile);
524 return errCode;
525 }
526 }
527 targetHandle.close();
528 return WriteChecksum(targetFile);
529 }
530
UnpackFile(const string & sourceFile,const string & targetPath,FileInfo & fileInfo)531 int PackageFile::UnpackFile(const string &sourceFile, const string &targetPath, FileInfo &fileInfo)
532 {
533 ifstream sourceHandle(sourceFile, ios::in | ios::binary);
534 if (!sourceHandle.good()) {
535 LOGE("[UnpackFile] sourceHandle error, sys err [%d]", errno);
536 return -E_INVALID_PATH;
537 }
538 uint32_t fileNum;
539 int errCode = UnpackFileHeader(sourceHandle, sourceFile, fileInfo, fileNum);
540 if (errCode != E_OK) {
541 return errCode;
542 }
543 FileContext fileContext;
544 list<FileContext> fileContexts;
545 sourceHandle.seekg(static_cast<int64_t>(FILE_HEADER_LEN), ios_base::beg);
546 if (!sourceHandle.good()) {
547 LOGE("[UnpackFile] sourceHandle error after seekg, sys err [%d]", errno);
548 return -E_INVALID_PATH;
549 }
550 for (uint32_t fileCount = 0; fileCount < fileNum; fileCount++) {
551 errCode = UnpackFileContext(sourceHandle, fileContext);
552 if (errCode != E_OK) {
553 return errCode;
554 }
555 fileContexts.push_back(fileContext);
556 }
557
558 for (const auto &file : fileContexts) {
559 if (file.fileType == OS::PATH) {
560 std::string dirPath = targetPath + "/" + std::string(file.fileName);
561 if (!OS::CheckPathExistence(dirPath) && OS::MakeDBDirectory(dirPath) != E_OK) {
562 return -E_SYSTEM_API_FAIL;
563 }
564 continue;
565 }
566 errCode = UnpackFileContent(sourceHandle, targetPath, file);
567 if (errCode != E_OK) {
568 return errCode;
569 }
570 }
571 return E_OK;
572 }
573
CopyFilePermissionsIfNeed(bool targetExists,const std::string & sourcePath,const std::string & fileName,const std::string & targetFile,std::ofstream & targetHandle)574 int PackageFile::CopyFilePermissionsIfNeed(bool targetExists, const std::string &sourcePath,
575 const std::string &fileName, const std::string &targetFile, std::ofstream &targetHandle)
576 {
577 if (targetExists) {
578 return E_OK;
579 }
580 int errCode = CopyFilePermissions(sourcePath + FILE_SEPARATOR + fileName, targetFile);
581 if (errCode != E_OK) {
582 LOGE("Copy file fail when execute pack files! errCode = [%d]", errCode);
583 Clear(targetHandle, targetFile);
584 }
585 return errCode;
586 }
587 }
588