1/* 2 * Copyright (c) 2022 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 "ecmascript/platform/file.h" 17 18#include <windef.h> 19#include <winbase.h> 20#include <winnt.h> 21#include <climits> 22#include <fileapi.h> 23 24#ifdef ERROR 25#undef ERROR 26#endif 27 28#ifdef VOID 29#undef VOID 30#endif 31 32#ifdef CONST 33#undef CONST 34#endif 35 36#include "ecmascript/ecma_macros.h" 37#include "ecmascript/ecma_string.h" 38#include "ecmascript/js_tagged_value-inl.h" 39#include "ecmascript/log_wrapper.h" 40#include "ecmascript/platform/map.h" 41 42namespace panda::ecmascript { 43std::string GetFileDelimiter() 44{ 45 return ";"; 46} 47 48std::string GetPathSeparator() 49{ 50 return "\\"; 51} 52 53bool RealPath(const std::string &path, std::string &realPath, [[maybe_unused]] bool readOnly) 54{ 55 realPath = ""; 56 if (path.empty() || path.size() > PATH_MAX) { 57 LOG_ECMA(WARN) << "File path is illeage"; 58 return false; 59 } 60 char buffer[PATH_MAX] = { '\0' }; 61 if (!_fullpath(buffer, path.c_str(), sizeof(buffer) - 1)) { 62 LOG_ECMA(WARN) << "File path:" << path << " full path failure"; 63 return false; 64 } 65 realPath = std::string(buffer); 66 return true; 67} 68 69bool RealPathByChar(const char *path, char *realPath, int rowLength, bool readOnly) 70{ 71 (void)path; 72 (void)realPath; 73 (void)rowLength; 74 (void)readOnly; 75 return false; 76} 77 78void DPrintf(fd_t fd, const std::string &buffer) 79{ 80 LOG_ECMA(DEBUG) << "Unsupport dprintf fd(" << fd << ") in windows, buffer:" << buffer; 81} 82 83void FSync(fd_t fd) 84{ 85 LOG_ECMA(DEBUG) << "Unsupport fsync fd(" << fd << ") in windows"; 86} 87 88void Close(fd_t fd) 89{ 90 CloseHandle(fd); 91} 92 93MemMap FileMap(const char *fileName, int flag, int prot, int64_t offset) 94{ 95 if (prot == PAGE_PROT_READWRITE) { 96 flag |= FILE_RDONLY | FILE_WRONLY; 97 } 98 fd_t fd = CreateFile(fileName, flag, 0, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); 99 if (fd == INVALID_FD) { 100 LOG_ECMA(ERROR) << fileName << " file open failed"; 101 return MemMap(); 102 } 103 104 LARGE_INTEGER fileSize; 105 if (!GetFileSizeEx(fd, &fileSize)) { 106 CloseHandle(fd); 107 LOG_ECMA(ERROR) << "GetFileSize failed with error code:" << GetLastError(); 108 return MemMap(); 109 } 110 auto size = fileSize.QuadPart; 111 if (size <= 0) { 112 CloseHandle(fd); 113 LOG_HOST_TOOL_ERROR << fileName << " file is empty"; 114 return MemMap(); 115 } 116 117 // 32: high 32 bits 118 fd_t extra = CreateFileMapping(fd, NULL, prot, size >> 32, size & 0xffffffff, nullptr); 119 if (extra == nullptr) { 120 CloseHandle(fd); 121 LOG_ECMA(ERROR) << "CreateFileMapping failed with error code:" << GetLastError(); 122 return MemMap(); 123 } 124 int accessor = (prot == PAGE_PROT_READ) ? FILE_MAP_READ : FILE_MAP_WRITE; 125 void *addr = MapViewOfFile(extra, accessor, offset >> 32, offset & 0xffffffff, size); 126 CloseHandle(extra); 127 CloseHandle(fd); 128 if (addr == nullptr) { 129 LOG_ECMA(ERROR) << "MapViewOfFile failed with error code:" << GetLastError(); 130 } 131 return MemMap(addr, size); 132} 133 134MemMap FileMapForAlignAddress(const char *fileName, int flag, int prot, 135 int64_t offset, uint32_t offStart) 136{ 137 // AOT not used, previewer used 138 LOG_ECMA(INFO) << "Don't used fileName:" << fileName << " flag:" << flag 139 << " prot:" << prot << " offset:" << offset << " offStart:" << offStart; 140 return MemMap(); 141} 142 143int FileUnMap(MemMap addr) 144{ 145 if (UnmapViewOfFile(addr.GetOriginAddr()) == 0) { 146 return FILE_FAILED; 147 } 148 return FILE_SUCCESS; 149} 150 151CString ResolveFilenameFromNative(JSThread *thread, const CString &dirname, 152 CString request) 153{ 154 std::string relativePath; 155 int suffixEnd = static_cast<int>(request.find_last_of('.')); 156 if (request[1] == ':') { // absoluteFilePath 157 relativePath = request.substr(0, suffixEnd) + ".abc"; 158 } else { 159 int pos = static_cast<int>(dirname.find_last_of('\\')); 160 relativePath = dirname.substr(0, pos + 1) + request.substr(0, suffixEnd) + ".abc"; 161 } 162 163 std::string absPath; 164 if (RealPath(relativePath, absPath)) { 165 return absPath.c_str(); 166 } 167 THROW_REFERENCE_ERROR_AND_RETURN(thread, "resolve absolute path fail", CString()); 168} 169 170bool FileExist(const char *filename) 171{ 172 return (_access(filename, 0) != -1); 173} 174 175int Unlink(const char *filename) 176{ 177 return _unlink(filename); 178} 179 180bool TryToRemoveSO([[maybe_unused]] JSThread *thread, [[maybe_unused]] JSHandle<SourceTextModule> module) 181{ 182 return false; 183} 184 185void *LoadLib([[maybe_unused]] const std::string &liname) 186{ 187 LOG_ECMA(INFO) << "Unsupport LoadLib"; 188 return nullptr; 189} 190 191void *FindSymbol([[maybe_unused]] void *handle, [[maybe_unused]] const char *symbol) 192{ 193 LOG_ECMA(INFO) << "Unsupport FindSymbol"; 194 return nullptr; 195} 196 197int CloseLib([[maybe_unused]] void *handle) 198{ 199 LOG_ECMA(INFO) << "Unsupport CloseLib"; 200 return 0; 201} 202 203char *LoadLibError() 204{ 205 LOG_ECMA(INFO) << "Unsupport LoadLibError"; 206 return nullptr; 207} 208} // namespace panda::ecmascript 209