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 #ifndef FOUNDATION_ACE_NAPI_MODULE_MANAGER_NATIVE_MODULE_MANAGER_H 17 #define FOUNDATION_ACE_NAPI_MODULE_MANAGER_NATIVE_MODULE_MANAGER_H 18 19 #include <cstdint> 20 #include <map> 21 #include <mutex> 22 #include <unordered_map> 23 #include <unordered_set> 24 #include <vector> 25 #include <string> 26 #include <pthread.h> 27 28 #include "module_load_checker.h" 29 #include "utils/macros.h" 30 #include "interfaces/inner_api/napi/native_node_api.h" 31 32 #ifdef WINDOWS_PLATFORM 33 #include <winsock2.h> 34 #include <windows.h> 35 using LIBHANDLE = HMODULE; 36 #define LIBFREE FreeLibrary 37 #define LIBSYM GetProcAddress 38 #else 39 #include <dlfcn.h> 40 using LIBHANDLE = void*; 41 #define LIBFREE dlclose 42 #define LIBSYM dlsym 43 #endif 44 45 #define NAPI_PATH_MAX 4096 46 47 class NativeValue; 48 49 class NativeEngine; 50 51 typedef napi_value (*RegisterCallback)(napi_env, napi_value); 52 53 typedef void (*GetJSCodeCallback)(const char** buf, int* bufLen); 54 55 struct NativeModule { 56 const char* name = nullptr; /* .nm_modname from native c++ register info */ 57 const char* moduleName = nullptr; /* moduleName required or imported */ 58 const char* fileName = nullptr; 59 const char* systemFilePath = nullptr; 60 RegisterCallback registerCallback = nullptr; 61 GetJSCodeCallback getABCCode = nullptr; 62 GetJSCodeCallback getJSCode = nullptr; 63 int32_t version = 0; 64 uint32_t flags = 0; 65 uint32_t refCount = 0; 66 NativeModule* next = nullptr; 67 const char* jsCode = nullptr; 68 const uint8_t* jsABCCode = nullptr; 69 int32_t jsCodeLen = 0; 70 bool moduleLoaded = false; 71 bool isAppModule = false; 72 std::unique_ptr<ApiAllowListChecker> apiAllowListChecker = nullptr; 73 }; 74 75 struct NativeModuleHeadTailStruct { 76 NativeModule* headNativeModule = nullptr; 77 NativeModule* tailNativeModule = nullptr; 78 }; 79 class NAPI_EXPORT NativeModuleManager { 80 public: 81 static NativeModuleManager* GetInstance(); 82 static uint64_t Release(); 83 84 void Register(NativeModule* nativeModule); 85 void SetAppLibPath(const std::string& moduleName, const std::vector<std::string>& appLibPath, 86 const bool& isSystemApp = false); 87 NativeModule* LoadNativeModule(const char* moduleName, const char* path, bool isAppModule, 88 std::string& errInfo, bool internal = false, const char* relativePath = ""); 89 void SetNativeEngine(std::string moduleName, NativeEngine* nativeEngine); 90 bool UnloadNativeModule(const std::string& moduleKey); 91 std::string GetModuleFileName(const char* moduleName, bool isAppModule); 92 93 /** 94 * @brief Set the path for searching napi dynamic libraries, only for the previewer. 95 * 96 * @param previewSearchPath the path for searching napi dynamic libraries 97 */ 98 void SetPreviewSearchPath(const std::string& previewSearchPath); 99 100 /** 101 * @brief Set the Module Load Checker delegate 102 * 103 * @param moduleCheckerDelegate The Module Load Checker delegate 104 */ 105 void SetModuleLoadChecker(const std::shared_ptr<ModuleCheckerDelegate>& moduleCheckerDelegate); 106 CheckModuleRestricted(const std::string & moduleName)107 inline bool CheckModuleRestricted(const std::string& moduleName) 108 { 109 const std::string whiteList[] = { 110 "worker", 111 "arkui.uicontext", 112 "arkui.node", 113 "arkui.modifier", 114 "measure", 115 }; 116 117 size_t listLen = sizeof(whiteList) / sizeof(whiteList[0]); 118 for (size_t i = 0; i < listLen; ++i) { 119 if (moduleName == whiteList[i]) { 120 return true; 121 } 122 } 123 124 return false; 125 } 126 127 private: 128 NativeModuleManager(); 129 virtual ~NativeModuleManager(); 130 131 bool GetNativeModulePath(const char* moduleName, const char* path, const char* relativePath, 132 bool isAppModule, char nativeModulePath[][NAPI_PATH_MAX], int32_t pathLength); 133 NativeModule* FindNativeModuleByDisk(const char* moduleName, const char* path, const char* relativePath, 134 bool internal, const bool isAppModule, std::string& errInfo, char nativeModulePath[][NAPI_PATH_MAX], 135 NativeModule* cacheNativeModule); 136 NativeModule* FindNativeModuleByCache(const char* moduleName, 137 char nativeModulePath[][NAPI_PATH_MAX], 138 NativeModule*& cacheNativeModule, 139 NativeModuleHeadTailStruct& cacheHeadTailStruct); 140 bool CheckModuleExist(const char* modulePath); 141 LIBHANDLE LoadModuleLibrary(std::string& moduleKey, const char* path, const char* pathKey, 142 const bool isAppModule, std::string& errInfo, uint32_t& errReason); 143 const uint8_t* GetFileBuffer(const std::string& filePath, const std::string& moduleKey, size_t &len); 144 bool UnloadModuleLibrary(LIBHANDLE handle); 145 bool CloseModuleLibrary(LIBHANDLE handle); 146 void CreateLdNamespace(const std::string moduleName, const char* lib_ld_path, const bool& isSystemApp); 147 bool IsExistedPath(const char* pathKey) const; 148 void EmplaceModuleLib(const std::string moduleKey, LIBHANDLE lib); 149 bool RemoveModuleLib(const std::string moduleKey); 150 void EmplaceModuleBuffer(const std::string moduleKey, const uint8_t* lib); 151 bool RemoveModuleBuffer(const std::string moduleKey); 152 const uint8_t* GetBufferHandle(const std::string& moduleKey) const; 153 void RegisterByBuffer(const std::string& moduleKey, const uint8_t* abcBuffer, size_t len); 154 bool CreateTailNativeModule(); 155 bool CreateHeadNativeModule(); 156 LIBHANDLE GetNativeModuleHandle(const std::string& moduleKey) const; 157 bool RemoveNativeModuleByCache(const std::string& moduleKey); 158 bool RemoveNativeModule(const std::string& moduleKey); 159 bool CheckNativeListChanged(const NativeModule* cacheHeadNativeModule, const NativeModule* cacheTailNativeModule); 160 void MoveApiAllowListCheckerPtr( 161 std::unique_ptr<ApiAllowListChecker>& apiAllowListChecker, NativeModule* nativeModule); 162 #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(__BIONIC__) && !defined(IOS_PLATFORM) && \ 163 !defined(LINUX_PLATFORM) 164 void CreateSharedLibsSonames(); 165 166 char* sharedLibsSonames_ = nullptr; 167 std::map<std::string, Dl_namespace> nsMap_; 168 #endif 169 170 std::mutex nativeModuleListMutex_; 171 NativeModule* headNativeModule_ = nullptr; 172 NativeModule* tailNativeModule_ = nullptr; 173 174 static NativeModuleManager *instance_; 175 pthread_mutex_t mutex_; 176 std::string prefix_; 177 bool isAppModule_ = false; 178 std::string loadingModuleName_; 179 180 std::mutex nativeEngineListMutex_; 181 std::map<std::string, NativeEngine*> nativeEngineList_; 182 183 mutable std::mutex moduleLibMutex_; 184 std::map<std::string, const LIBHANDLE> moduleLibMap_; 185 186 mutable std::mutex moduleBufMutex_; 187 std::map<std::string, const uint8_t*> moduleBufMap_; 188 189 mutable std::mutex appLibPathMapMutex_; 190 std::map<std::string, char*> appLibPathMap_; 191 std::string previewSearchPath_; 192 std::unique_ptr<ModuleLoadChecker> moduleLoadChecker_ = nullptr; 193 }; 194 195 #endif /* FOUNDATION_ACE_NAPI_MODULE_MANAGER_NATIVE_MODULE_MANAGER_H */ 196