133eb0b6dSopenharmony_ci/* 233eb0b6dSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 333eb0b6dSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 433eb0b6dSopenharmony_ci * you may not use this file except in compliance with the License. 533eb0b6dSopenharmony_ci * You may obtain a copy of the License at 633eb0b6dSopenharmony_ci * 733eb0b6dSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 833eb0b6dSopenharmony_ci * 933eb0b6dSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1033eb0b6dSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1133eb0b6dSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1233eb0b6dSopenharmony_ci * See the License for the specific language governing permissions and 1333eb0b6dSopenharmony_ci * limitations under the License. 1433eb0b6dSopenharmony_ci */ 1533eb0b6dSopenharmony_ci 1633eb0b6dSopenharmony_ci#ifndef FOUNDATION_ACE_NAPI_MODULE_MANAGER_NATIVE_MODULE_MANAGER_H 1733eb0b6dSopenharmony_ci#define FOUNDATION_ACE_NAPI_MODULE_MANAGER_NATIVE_MODULE_MANAGER_H 1833eb0b6dSopenharmony_ci 1933eb0b6dSopenharmony_ci#include <cstdint> 2033eb0b6dSopenharmony_ci#include <map> 2133eb0b6dSopenharmony_ci#include <mutex> 2233eb0b6dSopenharmony_ci#include <unordered_map> 2333eb0b6dSopenharmony_ci#include <unordered_set> 2433eb0b6dSopenharmony_ci#include <vector> 2533eb0b6dSopenharmony_ci#include <string> 2633eb0b6dSopenharmony_ci#include <pthread.h> 2733eb0b6dSopenharmony_ci 2833eb0b6dSopenharmony_ci#include "module_load_checker.h" 2933eb0b6dSopenharmony_ci#include "utils/macros.h" 3033eb0b6dSopenharmony_ci#include "interfaces/inner_api/napi/native_node_api.h" 3133eb0b6dSopenharmony_ci 3233eb0b6dSopenharmony_ci#ifdef WINDOWS_PLATFORM 3333eb0b6dSopenharmony_ci#include <winsock2.h> 3433eb0b6dSopenharmony_ci#include <windows.h> 3533eb0b6dSopenharmony_ciusing LIBHANDLE = HMODULE; 3633eb0b6dSopenharmony_ci#define LIBFREE FreeLibrary 3733eb0b6dSopenharmony_ci#define LIBSYM GetProcAddress 3833eb0b6dSopenharmony_ci#else 3933eb0b6dSopenharmony_ci#include <dlfcn.h> 4033eb0b6dSopenharmony_ciusing LIBHANDLE = void*; 4133eb0b6dSopenharmony_ci#define LIBFREE dlclose 4233eb0b6dSopenharmony_ci#define LIBSYM dlsym 4333eb0b6dSopenharmony_ci#endif 4433eb0b6dSopenharmony_ci 4533eb0b6dSopenharmony_ci#define NAPI_PATH_MAX 4096 4633eb0b6dSopenharmony_ci 4733eb0b6dSopenharmony_ciclass NativeValue; 4833eb0b6dSopenharmony_ci 4933eb0b6dSopenharmony_ciclass NativeEngine; 5033eb0b6dSopenharmony_ci 5133eb0b6dSopenharmony_citypedef napi_value (*RegisterCallback)(napi_env, napi_value); 5233eb0b6dSopenharmony_ci 5333eb0b6dSopenharmony_citypedef void (*GetJSCodeCallback)(const char** buf, int* bufLen); 5433eb0b6dSopenharmony_ci 5533eb0b6dSopenharmony_cistruct NativeModule { 5633eb0b6dSopenharmony_ci const char* name = nullptr; /* .nm_modname from native c++ register info */ 5733eb0b6dSopenharmony_ci const char* moduleName = nullptr; /* moduleName required or imported */ 5833eb0b6dSopenharmony_ci const char* fileName = nullptr; 5933eb0b6dSopenharmony_ci const char* systemFilePath = nullptr; 6033eb0b6dSopenharmony_ci RegisterCallback registerCallback = nullptr; 6133eb0b6dSopenharmony_ci GetJSCodeCallback getABCCode = nullptr; 6233eb0b6dSopenharmony_ci GetJSCodeCallback getJSCode = nullptr; 6333eb0b6dSopenharmony_ci int32_t version = 0; 6433eb0b6dSopenharmony_ci uint32_t flags = 0; 6533eb0b6dSopenharmony_ci uint32_t refCount = 0; 6633eb0b6dSopenharmony_ci NativeModule* next = nullptr; 6733eb0b6dSopenharmony_ci const char* jsCode = nullptr; 6833eb0b6dSopenharmony_ci const uint8_t* jsABCCode = nullptr; 6933eb0b6dSopenharmony_ci int32_t jsCodeLen = 0; 7033eb0b6dSopenharmony_ci bool moduleLoaded = false; 7133eb0b6dSopenharmony_ci bool isAppModule = false; 7233eb0b6dSopenharmony_ci std::unique_ptr<ApiAllowListChecker> apiAllowListChecker = nullptr; 7333eb0b6dSopenharmony_ci}; 7433eb0b6dSopenharmony_ci 7533eb0b6dSopenharmony_cistruct NativeModuleHeadTailStruct { 7633eb0b6dSopenharmony_ci NativeModule* headNativeModule = nullptr; 7733eb0b6dSopenharmony_ci NativeModule* tailNativeModule = nullptr; 7833eb0b6dSopenharmony_ci}; 7933eb0b6dSopenharmony_ciclass NAPI_EXPORT NativeModuleManager { 8033eb0b6dSopenharmony_cipublic: 8133eb0b6dSopenharmony_ci static NativeModuleManager* GetInstance(); 8233eb0b6dSopenharmony_ci static uint64_t Release(); 8333eb0b6dSopenharmony_ci 8433eb0b6dSopenharmony_ci void Register(NativeModule* nativeModule); 8533eb0b6dSopenharmony_ci void SetAppLibPath(const std::string& moduleName, const std::vector<std::string>& appLibPath, 8633eb0b6dSopenharmony_ci const bool& isSystemApp = false); 8733eb0b6dSopenharmony_ci NativeModule* LoadNativeModule(const char* moduleName, const char* path, bool isAppModule, 8833eb0b6dSopenharmony_ci std::string& errInfo, bool internal = false, const char* relativePath = ""); 8933eb0b6dSopenharmony_ci void SetNativeEngine(std::string moduleName, NativeEngine* nativeEngine); 9033eb0b6dSopenharmony_ci bool UnloadNativeModule(const std::string& moduleKey); 9133eb0b6dSopenharmony_ci std::string GetModuleFileName(const char* moduleName, bool isAppModule); 9233eb0b6dSopenharmony_ci 9333eb0b6dSopenharmony_ci /** 9433eb0b6dSopenharmony_ci * @brief Set the path for searching napi dynamic libraries, only for the previewer. 9533eb0b6dSopenharmony_ci * 9633eb0b6dSopenharmony_ci * @param previewSearchPath the path for searching napi dynamic libraries 9733eb0b6dSopenharmony_ci */ 9833eb0b6dSopenharmony_ci void SetPreviewSearchPath(const std::string& previewSearchPath); 9933eb0b6dSopenharmony_ci 10033eb0b6dSopenharmony_ci /** 10133eb0b6dSopenharmony_ci * @brief Set the Module Load Checker delegate 10233eb0b6dSopenharmony_ci * 10333eb0b6dSopenharmony_ci * @param moduleCheckerDelegate The Module Load Checker delegate 10433eb0b6dSopenharmony_ci */ 10533eb0b6dSopenharmony_ci void SetModuleLoadChecker(const std::shared_ptr<ModuleCheckerDelegate>& moduleCheckerDelegate); 10633eb0b6dSopenharmony_ci 10733eb0b6dSopenharmony_ci inline bool CheckModuleRestricted(const std::string& moduleName) 10833eb0b6dSopenharmony_ci { 10933eb0b6dSopenharmony_ci const std::string whiteList[] = { 11033eb0b6dSopenharmony_ci "worker", 11133eb0b6dSopenharmony_ci "arkui.uicontext", 11233eb0b6dSopenharmony_ci "arkui.node", 11333eb0b6dSopenharmony_ci "arkui.modifier", 11433eb0b6dSopenharmony_ci "measure", 11533eb0b6dSopenharmony_ci }; 11633eb0b6dSopenharmony_ci 11733eb0b6dSopenharmony_ci size_t listLen = sizeof(whiteList) / sizeof(whiteList[0]); 11833eb0b6dSopenharmony_ci for (size_t i = 0; i < listLen; ++i) { 11933eb0b6dSopenharmony_ci if (moduleName == whiteList[i]) { 12033eb0b6dSopenharmony_ci return true; 12133eb0b6dSopenharmony_ci } 12233eb0b6dSopenharmony_ci } 12333eb0b6dSopenharmony_ci 12433eb0b6dSopenharmony_ci return false; 12533eb0b6dSopenharmony_ci } 12633eb0b6dSopenharmony_ci 12733eb0b6dSopenharmony_ciprivate: 12833eb0b6dSopenharmony_ci NativeModuleManager(); 12933eb0b6dSopenharmony_ci virtual ~NativeModuleManager(); 13033eb0b6dSopenharmony_ci 13133eb0b6dSopenharmony_ci bool GetNativeModulePath(const char* moduleName, const char* path, const char* relativePath, 13233eb0b6dSopenharmony_ci bool isAppModule, char nativeModulePath[][NAPI_PATH_MAX], int32_t pathLength); 13333eb0b6dSopenharmony_ci NativeModule* FindNativeModuleByDisk(const char* moduleName, const char* path, const char* relativePath, 13433eb0b6dSopenharmony_ci bool internal, const bool isAppModule, std::string& errInfo, char nativeModulePath[][NAPI_PATH_MAX], 13533eb0b6dSopenharmony_ci NativeModule* cacheNativeModule); 13633eb0b6dSopenharmony_ci NativeModule* FindNativeModuleByCache(const char* moduleName, 13733eb0b6dSopenharmony_ci char nativeModulePath[][NAPI_PATH_MAX], 13833eb0b6dSopenharmony_ci NativeModule*& cacheNativeModule, 13933eb0b6dSopenharmony_ci NativeModuleHeadTailStruct& cacheHeadTailStruct); 14033eb0b6dSopenharmony_ci bool CheckModuleExist(const char* modulePath); 14133eb0b6dSopenharmony_ci LIBHANDLE LoadModuleLibrary(std::string& moduleKey, const char* path, const char* pathKey, 14233eb0b6dSopenharmony_ci const bool isAppModule, std::string& errInfo, uint32_t& errReason); 14333eb0b6dSopenharmony_ci const uint8_t* GetFileBuffer(const std::string& filePath, const std::string& moduleKey, size_t &len); 14433eb0b6dSopenharmony_ci bool UnloadModuleLibrary(LIBHANDLE handle); 14533eb0b6dSopenharmony_ci bool CloseModuleLibrary(LIBHANDLE handle); 14633eb0b6dSopenharmony_ci void CreateLdNamespace(const std::string moduleName, const char* lib_ld_path, const bool& isSystemApp); 14733eb0b6dSopenharmony_ci bool IsExistedPath(const char* pathKey) const; 14833eb0b6dSopenharmony_ci void EmplaceModuleLib(const std::string moduleKey, LIBHANDLE lib); 14933eb0b6dSopenharmony_ci bool RemoveModuleLib(const std::string moduleKey); 15033eb0b6dSopenharmony_ci void EmplaceModuleBuffer(const std::string moduleKey, const uint8_t* lib); 15133eb0b6dSopenharmony_ci bool RemoveModuleBuffer(const std::string moduleKey); 15233eb0b6dSopenharmony_ci const uint8_t* GetBufferHandle(const std::string& moduleKey) const; 15333eb0b6dSopenharmony_ci void RegisterByBuffer(const std::string& moduleKey, const uint8_t* abcBuffer, size_t len); 15433eb0b6dSopenharmony_ci bool CreateTailNativeModule(); 15533eb0b6dSopenharmony_ci bool CreateHeadNativeModule(); 15633eb0b6dSopenharmony_ci LIBHANDLE GetNativeModuleHandle(const std::string& moduleKey) const; 15733eb0b6dSopenharmony_ci bool RemoveNativeModuleByCache(const std::string& moduleKey); 15833eb0b6dSopenharmony_ci bool RemoveNativeModule(const std::string& moduleKey); 15933eb0b6dSopenharmony_ci bool CheckNativeListChanged(const NativeModule* cacheHeadNativeModule, const NativeModule* cacheTailNativeModule); 16033eb0b6dSopenharmony_ci void MoveApiAllowListCheckerPtr( 16133eb0b6dSopenharmony_ci std::unique_ptr<ApiAllowListChecker>& apiAllowListChecker, NativeModule* nativeModule); 16233eb0b6dSopenharmony_ci#if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(__BIONIC__) && !defined(IOS_PLATFORM) && \ 16333eb0b6dSopenharmony_ci !defined(LINUX_PLATFORM) 16433eb0b6dSopenharmony_ci void CreateSharedLibsSonames(); 16533eb0b6dSopenharmony_ci 16633eb0b6dSopenharmony_ci char* sharedLibsSonames_ = nullptr; 16733eb0b6dSopenharmony_ci std::map<std::string, Dl_namespace> nsMap_; 16833eb0b6dSopenharmony_ci#endif 16933eb0b6dSopenharmony_ci 17033eb0b6dSopenharmony_ci std::mutex nativeModuleListMutex_; 17133eb0b6dSopenharmony_ci NativeModule* headNativeModule_ = nullptr; 17233eb0b6dSopenharmony_ci NativeModule* tailNativeModule_ = nullptr; 17333eb0b6dSopenharmony_ci 17433eb0b6dSopenharmony_ci static NativeModuleManager *instance_; 17533eb0b6dSopenharmony_ci pthread_mutex_t mutex_; 17633eb0b6dSopenharmony_ci std::string prefix_; 17733eb0b6dSopenharmony_ci bool isAppModule_ = false; 17833eb0b6dSopenharmony_ci std::string loadingModuleName_; 17933eb0b6dSopenharmony_ci 18033eb0b6dSopenharmony_ci std::mutex nativeEngineListMutex_; 18133eb0b6dSopenharmony_ci std::map<std::string, NativeEngine*> nativeEngineList_; 18233eb0b6dSopenharmony_ci 18333eb0b6dSopenharmony_ci mutable std::mutex moduleLibMutex_; 18433eb0b6dSopenharmony_ci std::map<std::string, const LIBHANDLE> moduleLibMap_; 18533eb0b6dSopenharmony_ci 18633eb0b6dSopenharmony_ci mutable std::mutex moduleBufMutex_; 18733eb0b6dSopenharmony_ci std::map<std::string, const uint8_t*> moduleBufMap_; 18833eb0b6dSopenharmony_ci 18933eb0b6dSopenharmony_ci mutable std::mutex appLibPathMapMutex_; 19033eb0b6dSopenharmony_ci std::map<std::string, char*> appLibPathMap_; 19133eb0b6dSopenharmony_ci std::string previewSearchPath_; 19233eb0b6dSopenharmony_ci std::unique_ptr<ModuleLoadChecker> moduleLoadChecker_ = nullptr; 19333eb0b6dSopenharmony_ci}; 19433eb0b6dSopenharmony_ci 19533eb0b6dSopenharmony_ci#endif /* FOUNDATION_ACE_NAPI_MODULE_MANAGER_NATIVE_MODULE_MANAGER_H */ 196