1 /*
2  * Copyright (c) 2022-2023 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 "raw_file_manager.h"
17 
18 #include <climits>
19 #include <cstdio>
20 #include <cstdlib>
21 #include <dirent.h>
22 #include <fcntl.h>
23 #include <securec.h>
24 #include <unistd.h>
25 
26 #include "auto_mutex.h"
27 #include "raw_dir.h"
28 #include "raw_file.h"
29 #include "resource_manager.h"
30 #include "resource_manager_addon.h"
31 #include "resource_manager_impl.h"
32 #include "hilog_wrapper.h"
33 
34 #ifdef __WINNT__
35 #include <shlwapi.h>
36 #include <windows.h>
37 #endif
38 
39 using namespace OHOS::Global::Resource;
40 
41 Lock g_rawDirLock;
42 Lock g_rawFileLock;
43 Lock g_rawFile64Lock;
44 struct NativeResourceManager {
45     std::shared_ptr<ResourceManager> resManager = nullptr;
46 };
47 
48 struct FileNameCache {
49     std::vector<std::string> names;
50 };
51 
52 struct RawDir {
53     std::shared_ptr<ResourceManager> resManager = nullptr;
54     struct FileNameCache fileNameCache;
55 };
56 
57 struct ActualOffset {
58     int64_t offset;
ActualOffsetActualOffset59     explicit ActualOffset() : offset(0) {}
60 };
61 
62 struct RawFile {
63     const std::string filePath;
64     int64_t offset;
65     int64_t length;
66     FILE* pf;
67     uint8_t* buffer;
68     const NativeResourceManager *resMgr;
69     std::unique_ptr<ActualOffset> actualOffset;
70 
RawFileRawFile71     explicit RawFile(const std::string &path) : filePath(path), offset(0), length(0),
72         pf(nullptr), buffer(nullptr), resMgr(nullptr), actualOffset(std::make_unique<ActualOffset>()) {}
73 
~RawFileRawFile74     ~RawFile()
75     {
76         if (buffer != nullptr) {
77             delete[] buffer;
78             buffer = nullptr;
79         }
80         if (pf != nullptr) {
81             fclose(pf);
82             pf = nullptr;
83         }
84     }
85 
openRawFile86     bool open()
87     {
88         pf = std::fopen(filePath.c_str(), "rb");
89         return pf != nullptr;
90     }
91 };
92 
OH_ResourceManager_InitNativeResourceManager(napi_env env,napi_value jsResMgr)93 NativeResourceManager *OH_ResourceManager_InitNativeResourceManager(napi_env env, napi_value jsResMgr)
94 {
95     napi_valuetype valueType;
96     napi_typeof(env, jsResMgr, &valueType);
97     if (valueType != napi_object) {
98         RESMGR_HILOGE(RESMGR_RAWFILE_TAG, "jsResMgr is not an object");
99         return nullptr;
100     }
101     std::shared_ptr<ResourceManagerAddon> *addonPtr = nullptr;
102     napi_status status = napi_unwrap(env, jsResMgr, reinterpret_cast<void **>(&addonPtr));
103     if (status != napi_ok) {
104         RESMGR_HILOGE(RESMGR_RAWFILE_TAG, "Failed to get native resourcemanager");
105         return nullptr;
106     }
107     if (addonPtr == nullptr) {
108         RESMGR_HILOGE(RESMGR_RAWFILE_TAG, "Failed to unwrap, addonPtr is null");
109         return nullptr;
110     }
111     std::unique_ptr<NativeResourceManager> result = std::make_unique<NativeResourceManager>();
112     result->resManager = (*addonPtr)->GetResMgr();
113     return result.release();
114 }
115 
OH_ResourceManager_ReleaseNativeResourceManager(NativeResourceManager * resMgr)116 void OH_ResourceManager_ReleaseNativeResourceManager(NativeResourceManager *resMgr)
117 {
118     if (resMgr != nullptr) {
119         delete resMgr;
120         resMgr = nullptr;
121     }
122 }
123 
IsLoadHap(const NativeResourceManager * mgr,std::string & hapPath)124 static bool IsLoadHap(const NativeResourceManager *mgr, std::string &hapPath)
125 {
126     return mgr->resManager->IsLoadHap(hapPath) == RState::SUCCESS ? true : false;
127 }
128 
LoadRawDirFromHap(const NativeResourceManager * mgr,const std::string dirName)129 RawDir *LoadRawDirFromHap(const NativeResourceManager *mgr, const std::string dirName)
130 {
131     std::unique_ptr<RawDir> result = std::make_unique<RawDir>();
132     RState state = mgr->resManager->GetRawFileList(dirName, result->fileNameCache.names);
133     if (state != RState::SUCCESS) {
134         RESMGR_HILOGD(RESMGR_RAWFILE_TAG, "failed to get RawDir dirName, %{public}s", dirName.c_str());
135         return nullptr;
136     }
137     return result.release();
138 }
139 
OH_ResourceManager_OpenRawDir(const NativeResourceManager * mgr,const char * dirName)140 RawDir *OH_ResourceManager_OpenRawDir(const NativeResourceManager *mgr, const char *dirName)
141 {
142     AutoMutex mutex(g_rawDirLock);
143     if (mgr == nullptr || dirName == nullptr) {
144         return nullptr;
145     }
146     std::string hapPath;
147     if (IsLoadHap(mgr, hapPath)) {
148         return LoadRawDirFromHap(mgr, dirName);
149     }
150     ResourceManagerImpl* impl = static_cast<ResourceManagerImpl *>(mgr->resManager.get());
151     std::string tempName = dirName;
152     const std::string rawFileDirName = tempName.empty() ? "rawfile" : "rawfile/";
153     if (tempName.length() < rawFileDirName.length()
154         || (tempName.compare(0, rawFileDirName.length(), rawFileDirName) != 0)) {
155         tempName = rawFileDirName + tempName;
156     }
157     std::unique_ptr<RawDir> result = std::make_unique<RawDir>();
158     std::vector<std::string> resourcesPaths = impl->GetResourcePaths();
159     for (auto iter = resourcesPaths.begin(); iter != resourcesPaths.end(); iter++) {
160         std::string currentPath = *iter + tempName;
161         DIR* dir = opendir(currentPath.c_str());
162         if (dir == nullptr) {
163             continue;
164         }
165         struct dirent *dirp = readdir(dir);
166         while (dirp != nullptr) {
167             if (std::strcmp(dirp->d_name, ".") == 0 ||
168                 std::strcmp(dirp->d_name, "..") == 0) {
169                 dirp = readdir(dir);
170                 continue;
171             }
172             if (dirp->d_type == DT_REG || dirp->d_type == DT_DIR) {
173                 result->fileNameCache.names.push_back(tempName + "/" + dirp->d_name);
174             }
175 
176             dirp = readdir(dir);
177         }
178         closedir(dir);
179     }
180     return result.release();
181 }
182 
LoadRawFileFromHap(const NativeResourceManager * mgr,const char * fileName,const std::string hapPath)183 RawFile *LoadRawFileFromHap(const NativeResourceManager *mgr, const char *fileName, const std::string hapPath)
184 {
185     size_t len;
186     std::unique_ptr<uint8_t[]> tmpBuf;
187     RState state = mgr->resManager->GetRawFileFromHap(fileName, len, tmpBuf);
188     if (state != SUCCESS) {
189         RESMGR_HILOGD(RESMGR_RAWFILE_TAG, "failed to get %{public}s rawfile", fileName);
190         return nullptr;
191     }
192     auto result = std::make_unique<RawFile>(fileName);
193     result->buffer = tmpBuf.release();
194     if (result->buffer == nullptr) {
195         RESMGR_HILOGE(RESMGR_RAWFILE_TAG, "failed get file buffer");
196         return nullptr;
197     }
198     int zipFd = open(hapPath.c_str(), O_RDONLY);
199     if (zipFd < 0) {
200         RESMGR_HILOGE(RESMGR_RAWFILE_TAG, "failed open file %{public}s", hapPath.c_str());
201         return nullptr;
202     }
203     result->pf = fdopen(zipFd, "r");
204     result->length = static_cast<long>(len);
205     result->resMgr = mgr;
206     return result.release();
207 }
208 
OH_ResourceManager_OpenRawFile(const NativeResourceManager * mgr,const char * fileName)209 RawFile *OH_ResourceManager_OpenRawFile(const NativeResourceManager *mgr, const char *fileName)
210 {
211     AutoMutex mutex(g_rawFileLock);
212     if (mgr == nullptr || fileName == nullptr) {
213         return nullptr;
214     }
215 
216     std::string hapPath;
217     if (IsLoadHap(mgr, hapPath)) {
218         return LoadRawFileFromHap(mgr, fileName, hapPath);
219     }
220 
221     std::string filePath;
222     RState state = mgr->resManager->GetRawFilePathByName(fileName, filePath);
223     if (state != SUCCESS) {
224         return nullptr;
225     }
226     auto result = std::make_unique<RawFile>(filePath);
227     if (!result->open()) {
228         return nullptr;
229     }
230 
231     std::fseek(result->pf, 0, SEEK_END);
232     result->length = ftell(result->pf);
233     std::fseek(result->pf, 0, SEEK_SET);
234     return result.release();
235 }
236 
OH_ResourceManager_GetRawFileCount(RawDir * rawDir)237 int OH_ResourceManager_GetRawFileCount(RawDir *rawDir)
238 {
239     if (rawDir == nullptr) {
240         return 0;
241     }
242     return rawDir->fileNameCache.names.size();
243 }
244 
OH_ResourceManager_GetRawFileName(RawDir * rawDir,int index)245 const char *OH_ResourceManager_GetRawFileName(RawDir *rawDir, int index)
246 {
247     if (rawDir == nullptr || index < 0) {
248         return nullptr;
249     }
250     uint32_t rawFileCount = rawDir->fileNameCache.names.size();
251     if (rawFileCount == 0 || index >= static_cast<int>(rawFileCount)) {
252         return nullptr;
253     }
254     return rawDir->fileNameCache.names[index].c_str();
255 }
256 
OH_ResourceManager_CloseRawDir(RawDir * rawDir)257 void OH_ResourceManager_CloseRawDir(RawDir *rawDir)
258 {
259     AutoMutex mutex(g_rawDirLock);
260     if (rawDir != nullptr) {
261         delete rawDir;
262         rawDir = nullptr;
263     }
264 }
265 
OH_ResourceManager_ReadRawFile(const RawFile * rawFile,void * buf,size_t length)266 int OH_ResourceManager_ReadRawFile(const RawFile *rawFile, void *buf, size_t length)
267 {
268     if (rawFile == nullptr || rawFile->actualOffset == nullptr || buf == nullptr || length == 0) {
269         return 0;
270     }
271     if (rawFile->buffer != nullptr) {
272         size_t len = static_cast<size_t>(OH_ResourceManager_GetRawFileRemainingLength(rawFile));
273         if (length > len) {
274             length = len;
275         }
276         int ret = memcpy_s(buf, length, rawFile->buffer + rawFile->actualOffset->offset, length);
277         if (ret != 0) {
278             RESMGR_HILOGE(RESMGR_RAWFILE_TAG, "failed to copy to buf");
279             return 0;
280         }
281         rawFile->actualOffset->offset += static_cast<int64_t>(length);
282         return static_cast<int>(length);
283     } else {
284         return std::fread(buf, 1, length, rawFile->pf);
285     }
286 }
287 
OH_ResourceManager_SeekRawFile(const RawFile * rawFile,long offset,int whence)288 int OH_ResourceManager_SeekRawFile(const RawFile *rawFile, long offset, int whence)
289 {
290     if (rawFile == nullptr || rawFile->actualOffset == nullptr || abs(offset) > rawFile->length) {
291         return -1;
292     }
293 
294     int origin = 0;
295     switch (whence) {
296         case SEEK_SET:
297             origin = SEEK_SET;
298             rawFile->actualOffset->offset = offset;
299             break;
300         case SEEK_CUR:
301             origin = SEEK_CUR;
302             rawFile->actualOffset->offset = rawFile->actualOffset->offset + offset;
303             break;
304         case SEEK_END:
305             origin = SEEK_END;
306             rawFile->actualOffset->offset = rawFile->length + offset;
307             break;
308         default:
309             return -1;
310     }
311 
312     if (rawFile->actualOffset->offset < 0 || rawFile->actualOffset->offset > rawFile->length) {
313         return -1;
314     }
315 
316     return std::fseek(rawFile->pf, rawFile->actualOffset->offset, origin);
317 }
318 
OH_ResourceManager_GetRawFileSize(RawFile * rawFile)319 long OH_ResourceManager_GetRawFileSize(RawFile *rawFile)
320 {
321     if (rawFile == nullptr || rawFile->actualOffset == nullptr) {
322         return 0;
323     }
324 
325     return static_cast<long>(rawFile->length);
326 }
327 
OH_ResourceManager_GetRawFileRemainingLength(const RawFile * rawFile)328 long OH_ResourceManager_GetRawFileRemainingLength(const RawFile *rawFile)
329 {
330     if (rawFile == nullptr || rawFile->actualOffset == nullptr ||
331         rawFile->length < rawFile->actualOffset->offset) {
332         return 0;
333     }
334 
335     return static_cast<long>(rawFile->length - rawFile->actualOffset->offset);
336 }
337 
OH_ResourceManager_CloseRawFile(RawFile * rawFile)338 void OH_ResourceManager_CloseRawFile(RawFile *rawFile)
339 {
340     AutoMutex mutex(g_rawFileLock);
341     if (rawFile != nullptr) {
342         delete rawFile;
343         rawFile = nullptr;
344     }
345 }
346 
OH_ResourceManager_GetRawFileOffset(const RawFile * rawFile)347 long OH_ResourceManager_GetRawFileOffset(const RawFile *rawFile)
348 {
349     if (rawFile == nullptr || rawFile->actualOffset == nullptr) {
350         return 0;
351     }
352     return static_cast<long>(rawFile->actualOffset->offset);
353 }
354 
GetRawFileDescriptorFromHap(const RawFile * rawFile,RawFileDescriptor & descriptor)355 static bool GetRawFileDescriptorFromHap(const RawFile *rawFile, RawFileDescriptor &descriptor)
356 {
357     ResourceManager::RawFileDescriptor resMgrDescriptor;
358     RState state = rawFile->resMgr->resManager->
359         GetRawFdNdkFromHap(rawFile->filePath, resMgrDescriptor);
360     if (state != SUCCESS) {
361         RESMGR_HILOGE(RESMGR_RAWFILE_TAG, "GetRawFileDescriptorFromHap failed");
362         return false;
363     }
364     descriptor.fd = resMgrDescriptor.fd;
365     descriptor.length = static_cast<long>(resMgrDescriptor.length);
366     descriptor.start = static_cast<long>(resMgrDescriptor.offset);
367     return true;
368 }
369 
OH_ResourceManager_GetRawFileDescriptor(const RawFile * rawFile,RawFileDescriptor & descriptor)370 bool OH_ResourceManager_GetRawFileDescriptor(const RawFile *rawFile, RawFileDescriptor &descriptor)
371 {
372     return OH_ResourceManager_GetRawFileDescriptorData(rawFile, &descriptor);
373 }
374 
OH_ResourceManager_GetRawFileDescriptorData(const RawFile * rawFile,RawFileDescriptor * descriptor)375 bool OH_ResourceManager_GetRawFileDescriptorData(const RawFile *rawFile, RawFileDescriptor *descriptor)
376 {
377     if (rawFile == nullptr || rawFile->actualOffset == nullptr) {
378         return false;
379     }
380     if (rawFile->resMgr != nullptr) {
381         return GetRawFileDescriptorFromHap(rawFile, *descriptor);
382     }
383     char paths[PATH_MAX] = {0};
384 #ifdef __WINNT__
385     if (!PathCanonicalizeA(paths, rawFile->filePath.c_str())) {
386         RESMGR_HILOGE(RESMGR_RAWFILE_TAG, "failed to PathCanonicalizeA the rawFile path");
387     }
388 #else
389     if (realpath(rawFile->filePath.c_str(), paths) == nullptr) {
390         RESMGR_HILOGE(RESMGR_RAWFILE_TAG, "failed to realpath the rawFile path");
391     }
392 #endif
393     int fd = open(paths, O_RDONLY);
394     if (fd > 0) {
395         descriptor->fd = fd;
396         descriptor->length = static_cast<long>(rawFile->length);
397         descriptor->start = static_cast<long>(rawFile->actualOffset->offset);
398     } else {
399         return false;
400     }
401     return true;
402 }
403 
OH_ResourceManager_ReleaseRawFileDescriptor(const RawFileDescriptor & descriptor)404 bool OH_ResourceManager_ReleaseRawFileDescriptor(const RawFileDescriptor &descriptor)
405 {
406     return OH_ResourceManager_ReleaseRawFileDescriptorData(&descriptor);
407 }
408 
OH_ResourceManager_ReleaseRawFileDescriptorData(const RawFileDescriptor * descriptor)409 bool OH_ResourceManager_ReleaseRawFileDescriptorData(const RawFileDescriptor *descriptor)
410 {
411     if (descriptor->fd > 0) {
412         return close(descriptor->fd) == 0;
413     }
414     return true;
415 }
416 
417 struct Raw {
418     const std::string filePath;
419     int64_t offset; // offset base on the rawfile
420     int64_t length;
421     int64_t start; // offset base on the Hap
422     FILE* pf;
423     const NativeResourceManager *resMgr;
424 
RawRaw425     explicit Raw(const std::string &path) : filePath(path), offset(0), length(0), start(0),
426         pf(nullptr), resMgr(nullptr) {}
427 
~RawRaw428     ~Raw()
429     {
430         if (pf != nullptr) {
431             fclose(pf);
432             pf = nullptr;
433         }
434     }
435 
openRaw436     bool open()
437     {
438         pf = std::fopen(filePath.c_str(), "rb");
439         return pf != nullptr;
440     }
441 };
442 
443 struct RawFile64 {
444     std::unique_ptr<Raw> raw;
RawFile64RawFile64445     explicit RawFile64(std::unique_ptr<Raw> raw) : raw(std::move(raw)) {}
446 };
447 
LoadRawFileFromHap64(const NativeResourceManager * mgr,const char * fileName,const std::string hapPath)448 RawFile64 *LoadRawFileFromHap64(const NativeResourceManager *mgr, const char *fileName, const std::string hapPath)
449 {
450     ResourceManager::RawFileDescriptor resMgrDescriptor;
451     RState state = mgr->resManager->GetRawFdNdkFromHap(fileName, resMgrDescriptor);
452     if (state != SUCCESS) {
453         RESMGR_HILOGD(RESMGR_RAWFILE_TAG, "failed to get %{public}s rawfile descriptor", fileName);
454         return nullptr;
455     }
456     auto result = std::make_unique<Raw>(fileName);
457     result->pf = fdopen(resMgrDescriptor.fd, "rb");
458     if (result->pf == nullptr) {
459         if (resMgrDescriptor.fd > 0) {
460             close(resMgrDescriptor.fd);
461             resMgrDescriptor.fd = 0;
462         }
463         RESMGR_HILOGE(RESMGR_RAWFILE_TAG, "failed to open %{public}s rawfile descriptor", fileName);
464         return nullptr;
465     }
466     result->length = resMgrDescriptor.length;
467     result->start = resMgrDescriptor.offset;
468     result->resMgr = mgr;
469     std::fseek(result->pf, result->start, SEEK_SET);
470     return new RawFile64(std::move(result));
471 }
472 
OH_ResourceManager_OpenRawFile64(const NativeResourceManager * mgr,const char * fileName)473 RawFile64 *OH_ResourceManager_OpenRawFile64(const NativeResourceManager *mgr, const char *fileName)
474 {
475     AutoMutex mutex(g_rawFile64Lock);
476     if (mgr == nullptr || fileName == nullptr) {
477         return nullptr;
478     }
479 
480     std::string hapPath;
481     if (IsLoadHap(mgr, hapPath)) {
482         return LoadRawFileFromHap64(mgr, fileName, hapPath);
483     }
484     std::string filePath;
485     RState state = mgr->resManager->GetRawFilePathByName(fileName, filePath);
486     if (state != SUCCESS) {
487         return nullptr;
488     }
489     auto result = std::make_unique<Raw>(filePath);
490     if (!result->open()) {
491         return nullptr;
492     }
493 
494     std::fseek(result->pf, 0, SEEK_END);
495     result->length = ftell(result->pf);
496     std::fseek(result->pf, 0, SEEK_SET);
497     return new RawFile64(std::move(result));
498 }
499 
OH_ResourceManager_ReadRawFile64(const RawFile64 * rawFile,void * buf,int64_t length)500 int64_t OH_ResourceManager_ReadRawFile64(const RawFile64 *rawFile, void *buf, int64_t length)
501 {
502     if (rawFile == nullptr || rawFile->raw == nullptr || buf == nullptr || length == 0) {
503         return 0;
504     }
505     int64_t len = OH_ResourceManager_GetRawFileRemainingLength64(rawFile);
506     if (length > len) {
507         length = len;
508     }
509     size_t ret = std::fread(buf, 1, length, rawFile->raw->pf);
510     if (ret == 0) {
511         RESMGR_HILOGE(RESMGR_RAWFILE_TAG, "failed to fread");
512         return 0;
513     }
514     rawFile->raw->offset += length;
515     return static_cast<int64_t>(ret);
516 }
517 
OH_ResourceManager_SeekRawFile64(const RawFile64 * rawFile,int64_t offset,int whence)518 int OH_ResourceManager_SeekRawFile64(const RawFile64 *rawFile, int64_t offset, int whence)
519 {
520     if (rawFile == nullptr || rawFile->raw == nullptr || abs(offset) > rawFile->raw->length) {
521         return -1;
522     }
523 
524     int origin = 0;
525     int64_t actualOffset = 0;
526     switch (whence) {
527         case SEEK_SET:
528             origin = SEEK_SET;
529             rawFile->raw->offset = offset;
530             actualOffset = rawFile->raw->start + offset;
531             break;
532         case SEEK_CUR:
533             origin = SEEK_CUR;
534             rawFile->raw->offset = rawFile->raw->offset + offset;
535             actualOffset = offset;
536             break;
537         case SEEK_END:
538             origin = SEEK_SET;
539             rawFile->raw->offset = rawFile->raw->length + offset;
540             actualOffset = rawFile->raw->start + rawFile->raw->length + offset;
541             break;
542         default:
543             return -1;
544     }
545 
546     if (rawFile->raw->offset < 0 || rawFile->raw->offset > rawFile->raw->length) {
547         return -1;
548     }
549 
550     return std::fseek(rawFile->raw->pf, actualOffset, origin);
551 }
552 
OH_ResourceManager_GetRawFileSize64(RawFile64 * rawFile)553 int64_t OH_ResourceManager_GetRawFileSize64(RawFile64 *rawFile)
554 {
555     if (rawFile == nullptr || rawFile->raw == nullptr) {
556         return 0;
557     }
558 
559     return rawFile->raw->length;
560 }
561 
OH_ResourceManager_GetRawFileRemainingLength64(const RawFile64 * rawFile)562 int64_t OH_ResourceManager_GetRawFileRemainingLength64(const RawFile64 *rawFile)
563 {
564     if (rawFile == nullptr || rawFile->raw == nullptr ||
565         rawFile->raw->length < rawFile->raw->offset) {
566         return 0;
567     }
568 
569     return rawFile->raw->length - rawFile->raw->offset;
570 }
571 
OH_ResourceManager_CloseRawFile64(RawFile64 * rawFile)572 void OH_ResourceManager_CloseRawFile64(RawFile64 *rawFile)
573 {
574     AutoMutex mutex(g_rawFile64Lock);
575     if (rawFile != nullptr) {
576         delete rawFile;
577         rawFile = nullptr;
578     }
579 }
580 
OH_ResourceManager_GetRawFileOffset64(const RawFile64 * rawFile)581 int64_t OH_ResourceManager_GetRawFileOffset64(const RawFile64 *rawFile)
582 {
583     if (rawFile == nullptr || rawFile->raw == nullptr) {
584         return 0;
585     }
586     return rawFile->raw->offset;
587 }
588 
GetRawFileDescriptorFromHap64(const RawFile64 * rawFile,RawFileDescriptor64 * descriptor)589 static bool GetRawFileDescriptorFromHap64(const RawFile64 *rawFile, RawFileDescriptor64 *descriptor)
590 {
591     ResourceManager::RawFileDescriptor resMgrDescriptor;
592     RState state = rawFile->raw->resMgr->resManager->
593         GetRawFdNdkFromHap(rawFile->raw->filePath, resMgrDescriptor);
594     if (state != SUCCESS) {
595         RESMGR_HILOGE(RESMGR_RAWFILE_TAG, "GetRawFileDescriptorFromHap64 failed");
596         return false;
597     }
598     descriptor->fd = resMgrDescriptor.fd;
599     descriptor->length = resMgrDescriptor.length;
600     descriptor->start = resMgrDescriptor.offset;
601     return true;
602 }
603 
OH_ResourceManager_GetRawFileDescriptor64(const RawFile64 * rawFile,RawFileDescriptor64 * descriptor)604 bool OH_ResourceManager_GetRawFileDescriptor64(const RawFile64 *rawFile, RawFileDescriptor64 *descriptor)
605 {
606     if (rawFile == nullptr || rawFile->raw == nullptr) {
607         return false;
608     }
609     if (rawFile->raw->resMgr != nullptr) {
610         return GetRawFileDescriptorFromHap64(rawFile, descriptor);
611     }
612     char paths[PATH_MAX] = {0};
613 #ifdef __WINNT__
614     if (!PathCanonicalizeA(paths, rawFile->raw->filePath.c_str())) {
615         RESMGR_HILOGE(RESMGR_RAWFILE_TAG, "failed to PathCanonicalizeA the rawFile path");
616     }
617 #else
618     if (realpath(rawFile->raw->filePath.c_str(), paths) == nullptr) {
619         RESMGR_HILOGE(RESMGR_RAWFILE_TAG, "failed to realpath the rawFile path");
620     }
621 #endif
622     int fd = open(paths, O_RDONLY);
623     if (fd > 0) {
624         descriptor->fd = fd;
625         descriptor->length = rawFile->raw->length;
626         descriptor->start = rawFile->raw->offset;
627     } else {
628         return false;
629     }
630     return true;
631 }
632 
OH_ResourceManager_ReleaseRawFileDescriptor64(const RawFileDescriptor64 * descriptor)633 bool OH_ResourceManager_ReleaseRawFileDescriptor64(const RawFileDescriptor64 *descriptor)
634 {
635     if (descriptor->fd > 0) {
636         return close(descriptor->fd) == 0;
637     }
638     return true;
639 }
640 
OH_ResourceManager_IsRawDir(const NativeResourceManager * mgr,const char * path)641 bool OH_ResourceManager_IsRawDir(const NativeResourceManager *mgr, const char *path)
642 {
643     bool result = false;
644     if (mgr == nullptr || path == nullptr) {
645         return result;
646     }
647     RState state = mgr->resManager->IsRawDirFromHap(path, result);
648     if (state != SUCCESS) {
649         RESMGR_HILOGD(RESMGR_RAWFILE_TAG, "failed to determine whether the path is a directory");
650         return result;
651     }
652     return result;
653 }