• 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 
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