• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (c) 2025 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 #include "open_core.h"
16 
17 #include <cstdio>
18 #include <cstdlib>
19 #include <cstring>
20 
21 #include "file_entity.h"
22 #include "file_instantiator.h"
23 #include "file_utils.h"
24 #include "filemgmt_libhilog.h"
25 #include "fs_utils.h"
26 #if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM)
27 #include "ability_manager_client.h"
28 #include "bundle_info.h"
29 #include "bundle_mgr_proxy.h"
30 #include "datashare_helper.h"
31 #include "file_uri.h"
32 #include "ipc_skeleton.h"
33 #include "iservice_registry.h"
34 #include "remote_uri.h"
35 #include "status_receiver_host.h"
36 #include "system_ability_definition.h"
37 #endif
38 
39 #ifdef FILE_API_TRACE
40 #include "hitrace_meter.h"
41 #endif
42 
43 namespace OHOS {
44 namespace FileManagement {
45 namespace ModuleFileIO {
46 using namespace std;
47 
48 #if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM)
49 using namespace OHOS::DistributedFS::ModuleRemoteUri;
50 using namespace OHOS::AppExecFwk;
51 #endif
52 
53 const std::string PROCEDURE_OPEN_NAME = "FileIOOpen";
54 const std::string MEDIALIBRARY_DATA_URI = "datashare:///media";
55 const std::string FILE_DATA_URI = "file://";
56 const std::string PATH_SHARE = "/data/storage/el2/share";
57 const std::string MODE_RW = "/rw/";
58 const std::string MODE_R = "/r/";
59 const std::string MEDIA = "media";
60 const std::string DOCS = "docs";
61 const std::string DATASHARE = "datashare";
62 const std::string SCHEME_BROKER = "content";
63 #if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM)
64 constexpr uint32_t MAX_WANT_FLAG = 4;
65 #endif
66 
ValidAndConvertFlags(const optional<int32_t> & mode)67 static tuple<bool, uint32_t> ValidAndConvertFlags(const optional<int32_t> &mode)
68 {
69     uint32_t flags = O_RDONLY;
70     if (mode.has_value()) {
71         auto modeValue = mode.value();
72         if (modeValue < 0) {
73             HILOGE("Invalid mode");
74             return { false, flags };
75         }
76         flags = static_cast<uint32_t>(modeValue);
77         uint32_t invalidMode = (O_WRONLY | O_RDWR);
78         if ((flags & invalidMode) == invalidMode) {
79             HILOGE("Invalid mode");
80             return { false, flags };
81         }
82         flags = FsUtils::ConvertFlags(flags);
83     }
84     return { true, flags };
85 }
86 
OpenFileByPath(const string & path,uint32_t mode)87 static int OpenFileByPath(const string &path, uint32_t mode)
88 {
89     unique_ptr<uv_fs_t, decltype(FsUtils::FsReqCleanup) *> openReq = { new uv_fs_t, FsUtils::FsReqCleanup };
90     if (!openReq) {
91         HILOGE("Failed to request heap memory.");
92         return -ENOMEM;
93     }
94     int ret = uv_fs_open(nullptr, openReq.get(), path.c_str(), mode, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, nullptr);
95     return ret;
96 }
97 
98 #if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM)
99 
OpenFileByDatashare(const string & path,uint32_t flags)100 static int OpenFileByDatashare(const string &path, uint32_t flags)
101 {
102     std::shared_ptr<DataShare::DataShareHelper> dataShareHelper = nullptr;
103     sptr<FileIoToken> remote = new (std::nothrow) IRemoteStub<FileIoToken>();
104     if (!remote) {
105         HILOGE("Failed to get remote object");
106         return -ENOMEM;
107     }
108 
109     dataShareHelper = DataShare::DataShareHelper::Creator(remote->AsObject(), MEDIALIBRARY_DATA_URI);
110     if (!dataShareHelper) {
111         HILOGE("Failed to connect to datashare");
112         return -E_PERMISSION;
113     }
114 
115     Uri uri(path);
116     int fd = dataShareHelper->OpenFile(uri, FsUtils::GetModeFromFlags(flags));
117     return fd;
118 }
119 
OpenByFileDataUri(Uri & uri,const string & uriStr,uint32_t mode)120 static tuple<int, string> OpenByFileDataUri(Uri &uri, const string &uriStr, uint32_t mode)
121 {
122     string bundleName = uri.GetAuthority();
123     AppFileService::ModuleFileUri::FileUri fileUri(uriStr);
124     string realPath = fileUri.GetRealPath();
125     if (bundleName == MEDIA) {
126         int res = OpenFileByDatashare(uri.ToString(), mode);
127         if (res < 0) {
128             HILOGE("Failed to open file by Datashare error %{public}d", res);
129         }
130         return { res, uri.ToString() };
131     } else if (bundleName == DOCS && access(realPath.c_str(), F_OK) != 0) {
132         int res = OpenFileByDatashare(uri.ToString(), mode);
133         if (res < 0) {
134             HILOGE("Failed to open file by Datashare error %{public}d", res);
135             return { -ENOENT, uri.ToString() };
136         }
137         return { res, uri.ToString() };
138     }
139     int ret = OpenFileByPath(realPath, mode);
140     if (ret < 0) {
141         HILOGE("Failed to open file for libuv error %{public}d", ret);
142     }
143     return { ret, uriStr };
144 }
145 
OpenFileByBroker(const Uri & uri,uint32_t mode)146 static tuple<int, string> OpenFileByBroker(const Uri &uri, uint32_t mode)
147 {
148     uint32_t flag = (mode % MAX_WANT_FLAG) > 0 ? AAFwk::Want::FLAG_AUTH_WRITE_URI_PERMISSION
149                                             : AAFwk::Want::FLAG_AUTH_READ_URI_PERMISSION;
150     int ret = AAFwk::AbilityManagerClient::GetInstance()->OpenFile(uri, flag);
151     if (ret < 0) {
152         HILOGE("Failed to open file by Broker error %{public}d", ret);
153     }
154     return { ret, uri.ToString() };
155 }
156 
OpenFileByUri(const string & path,uint32_t mode)157 static tuple<int, string> OpenFileByUri(const string &path, uint32_t mode)
158 {
159     Uri uri(path);
160     string uriType = uri.GetScheme();
161     if (uriType == SCHEME_FILE) {
162         return OpenByFileDataUri(uri, path, mode);
163     }
164     if (uriType == SCHEME_BROKER) {
165         return OpenFileByBroker(uri, mode);
166     }
167     int fd = -1;
168     if (uriType == DATASHARE && RemoteUri::IsRemoteUri(path, fd, mode)) {
169         if (fd >= 0) {
170             return { fd, path };
171         }
172         HILOGE("Failed to open file by RemoteUri");
173     }
174     HILOGE("Failed to open file by invalid uri");
175     return { -EINVAL, path };
176 }
177 #endif
178 
DoOpen(const string & path,const optional<int32_t> & mode)179 FsResult<FsFile *> OpenCore::DoOpen(const string &path, const optional<int32_t> &mode)
180 {
181 #ifdef FILE_API_TRACE
182     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
183 #endif
184     auto [succMode, modeValue] = ValidAndConvertFlags(mode);
185     if (!succMode) {
186         return FsResult<FsFile *>::Error(EINVAL);
187     }
188 #if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM)
189     if (path.find("://") != string::npos) {
190         auto [res, uriStr] = OpenFileByUri(path, modeValue);
191         if (res < 0) {
192             return FsResult<FsFile *>::Error(res);
193         }
194         return FileInstantiator::InstantiateFile(res, uriStr, true);
195     }
196 #endif
197     int ret = OpenFileByPath(path, modeValue);
198     if (ret < 0) {
199         HILOGD("Failed to open file for libuv error %{public}d", ret);
200         return FsResult<FsFile *>::Error(ret);
201     }
202     return FileInstantiator::InstantiateFile(ret, path, false);
203 }
204 
205 } // namespace ModuleFileIO
206 } // namespace FileManagement
207 } // namespace OHOS