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; 57 const char* fileName = nullptr; 58 RegisterCallback registerCallback = nullptr; 59 GetJSCodeCallback getABCCode = nullptr; 60 GetJSCodeCallback getJSCode = nullptr; 61 int32_t version = 0; 62 uint32_t refCount = 0; 63 NativeModule* next = nullptr; 64 const char* jsCode = nullptr; 65 const uint8_t* jsABCCode = nullptr; 66 int32_t jsCodeLen = 0; 67 bool moduleLoaded = false; 68 bool isAppModule = false; 69 std::unique_ptr<ApiAllowListChecker> apiAllowListChecker = nullptr; 70 }; 71 72 class NAPI_EXPORT NativeModuleManager { 73 public: 74 static NativeModuleManager* GetInstance(); 75 static uint64_t Release(); 76 77 void Register(NativeModule* nativeModule); 78 void SetAppLibPath(const std::string& moduleName, const std::vector<std::string>& appLibPath, 79 const bool& isSystemApp = false); 80 NativeModule* LoadNativeModule(const char* moduleName, const char* path, bool isAppModule, 81 bool internal = false, const char* relativePath = "", bool moduleRestricted = false); 82 void SetNativeEngine(std::string moduleName, NativeEngine* nativeEngine); 83 bool UnloadNativeModule(const std::string& moduleKey); 84 std::string GetModuleFileName(const char* moduleName, bool isAppModule); 85 86 /** 87 * @brief Set the path for searching napi dynamic libraries, only for the previewer. 88 * 89 * @param previewSearchPath the path for searching napi dynamic libraries 90 */ 91 void SetPreviewSearchPath(const std::string& previewSearchPath); 92 93 /** 94 * @brief Set the Module Load Checker delegate 95 * 96 * @param moduleCheckerDelegate The Module Load Checker delegate 97 */ 98 void SetModuleLoadChecker(const std::shared_ptr<ModuleCheckerDelegate>& moduleCheckerDelegate); 99 100 private: 101 NativeModuleManager(); 102 virtual ~NativeModuleManager(); 103 104 bool GetNativeModulePath(const char* moduleName, const char* path, const char* relativePath, 105 bool isAppModule, char nativeModulePath[][NAPI_PATH_MAX], int32_t pathLength); 106 NativeModule* FindNativeModuleByDisk(const char* moduleName, const char* path, const char* relativePath, 107 bool internal, const bool isAppModule); 108 NativeModule* FindNativeModuleByCache(const char* moduleName); 109 LIBHANDLE LoadModuleLibrary(std::string& moduleKey, const char* path, const char* pathKey, const bool isAppModule); 110 bool CheckModuleRestricted(const std::string& moduleName); 111 const uint8_t* GetFileBuffer(const std::string& filePath, const std::string& moduleKey, size_t &len); 112 bool UnloadModuleLibrary(LIBHANDLE handle); 113 bool CloseModuleLibrary(LIBHANDLE handle); 114 void CreateLdNamespace(const std::string moduleName, const char* lib_ld_path, const bool& isSystemApp); 115 bool IsExistedPath(const char* pathKey) const; 116 void EmplaceModuleLib(const std::string moduleKey, LIBHANDLE lib); 117 bool RemoveModuleLib(const std::string moduleKey); 118 void EmplaceModuleBuffer(const std::string moduleKey, const uint8_t* lib); 119 bool RemoveModuleBuffer(const std::string moduleKey); 120 const uint8_t* GetBufferHandle(const std::string& moduleKey) const; 121 void RegisterByBuffer(const std::string& moduleKey, const uint8_t* abcBuffer, size_t len); 122 bool CreateNewNativeModule(); 123 LIBHANDLE GetNativeModuleHandle(const std::string& moduleKey) const; 124 bool RemoveNativeModuleByCache(const std::string& moduleKey); 125 bool RemoveNativeModule(const std::string& moduleKey); 126 void MoveApiAllowListCheckerPtr( 127 std::unique_ptr<ApiAllowListChecker>& apiAllowListChecker, NativeModule* nativeModule); 128 #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(__BIONIC__) && !defined(IOS_PLATFORM) && \ 129 !defined(LINUX_PLATFORM) 130 void CreateSharedLibsSonames(); 131 132 char* sharedLibsSonames_ = nullptr; 133 std::map<std::string, Dl_namespace> nsMap_; 134 #endif 135 136 std::mutex nativeModuleListMutex_; 137 NativeModule* firstNativeModule_ = nullptr; 138 NativeModule* lastNativeModule_ = nullptr; 139 140 static NativeModuleManager *instance_; 141 pthread_mutex_t mutex_; 142 std::string prefix_; 143 bool isAppModule_ = false; 144 145 std::mutex nativeEngineListMutex_; 146 std::map<std::string, NativeEngine*> nativeEngineList_; 147 148 mutable std::mutex moduleLibMutex_; 149 std::map<std::string, const LIBHANDLE> moduleLibMap_; 150 151 mutable std::mutex moduleBufMutex_; 152 std::map<std::string, const uint8_t*> moduleBufMap_; 153 154 std::map<std::string, char*> appLibPathMap_; 155 std::string previewSearchPath_; 156 std::unique_ptr<ModuleLoadChecker> moduleLoadChecker_ = nullptr; 157 }; 158 159 #endif /* FOUNDATION_ACE_NAPI_MODULE_MANAGER_NATIVE_MODULE_MANAGER_H */ 160