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
16 #include "file_grant_permission_ffi.h"
17
18 #include "file_permission.h"
19 #include "macro.h"
20 #include "n_error.h"
21 #include "uv.h"
22
23 using namespace OHOS::FFI;
24
25 namespace OHOS {
26 namespace CJSystemapi {
27 namespace FileGrantPermission {
28
29 using namespace OHOS::AppFileService;
30 using namespace OHOS::FileManagement::LibN;
31
MallocCString(const std::string & origin)32 char* MallocCString(const std::string& origin)
33 {
34 if (origin.empty()) {
35 return nullptr;
36 }
37 auto length = origin.length() + 1;
38 char* res = static_cast<char*>(malloc(sizeof(char) * length));
39 if (res == nullptr) {
40 return nullptr;
41 }
42 return std::char_traits<char>::copy(res, origin.c_str(), length);
43 }
44
ConvertUVCode2ErrorCode(int errCode)45 int ConvertUVCode2ErrorCode(int errCode)
46 {
47 if (errCode >= 0) {
48 return errCode;
49 }
50
51 const char* uvErrName = uv_err_name(errCode);
52 if (uvErrName == nullptr) {
53 LOGE("uvErrName is nullptr");
54 return UNKROWN_ERR;
55 }
56 auto uvCode = string_view(uvErrName);
57 if (uvCode2ErrCodeTable.find(uvCode) != uvCode2ErrCodeTable.end()) {
58 return uvCode2ErrCodeTable.at(uvCode);
59 }
60 return UNKROWN_ERR;
61 }
62
ConvertError(int errCode)63 CJError ConvertError(int errCode)
64 {
65 CJError err = { 0, "" };
66 int genericCode = ConvertUVCode2ErrorCode(errCode);
67 auto it = errCodeTable.find(genericCode);
68 if (it != errCodeTable.end()) {
69 err.errorcode = it->second.first;
70 err.message = it->second.second;
71 } else {
72 err.errorcode = errCodeTable.at(UNKROWN_ERR).first;
73 err.message = errCodeTable.at(UNKROWN_ERR).second + ", errno is " + to_string(abs(errCode));
74 }
75 return err;
76 }
77
78 extern "C" {
FfiOHOSFileGPPersistPermission(CArrCPolicyInfo policies,int32_t * code)79 CArrCPolicyErrorResult FfiOHOSFileGPPersistPermission(CArrCPolicyInfo policies, int32_t* code)
80 {
81 CArrCPolicyErrorResult res = { nullptr, 0 };
82 if (policies.head == nullptr || code == nullptr) {
83 LOGE("input is nullptr");
84 return res;
85 }
86 *code = E_UNKNOWN_ERROR;
87 std::vector<UriPolicyInfo> uriPolicies;
88 for (int64_t i = 0; i < policies.size; i++) {
89 auto head = policies.head + i;
90 std::string uriStr(head->uri);
91 UriPolicyInfo uriPolicy { .uri = uriStr, .mode = head->mode };
92 uriPolicies.emplace_back(uriPolicy);
93 }
94
95 shared_ptr<PolicyErrorArgs> arg = make_shared<PolicyErrorArgs>();
96 if (arg == nullptr) {
97 LOGE("Make_shared is failed");
98 return res;
99 }
100 arg->errNo = FilePermission::PersistPermission(uriPolicies, arg->errorResults);
101 CJError err = ConvertError(arg->errNo);
102 if (err.errorcode != 0) {
103 res.size = static_cast<int64_t>(arg->errorResults.size());
104 if (res.size <= 0) {
105 LOGE("size is less than 0");
106 return res;
107 }
108 CPolicyErrorResult* retArrValue =
109 static_cast<CPolicyErrorResult*>(malloc(sizeof(CPolicyErrorResult) * res.size));
110 if (retArrValue == nullptr) {
111 LOGE("malloc is failed");
112 return res;
113 }
114 for (int64_t i = 0; i < res.size; i++) {
115 retArrValue[i].uri = MallocCString(arg->errorResults[i].uri);
116 retArrValue[i].code = arg->errorResults[i].code;
117 retArrValue[i].message = MallocCString(arg->errorResults[i].message);
118 }
119 res.head = retArrValue;
120 }
121 *code = err.errorcode;
122 return res;
123 }
124
FfiOHOSFileGPRevokePermission(CArrCPolicyInfo policies,int32_t * code)125 CArrCPolicyErrorResult FfiOHOSFileGPRevokePermission(CArrCPolicyInfo policies, int32_t* code)
126 {
127 CArrCPolicyErrorResult res = { nullptr, 0 };
128 if (policies.head == nullptr || code == nullptr) {
129 LOGE("input is nullptr");
130 return res;
131 }
132 *code = E_UNKNOWN_ERROR;
133 std::vector<UriPolicyInfo> uriPolicies;
134 for (int64_t i = 0; i < policies.size; i++) {
135 auto head = policies.head + i;
136 std::string uriStr(head->uri);
137 UriPolicyInfo uriPolicy { .uri = uriStr, .mode = head->mode };
138 uriPolicies.emplace_back(uriPolicy);
139 }
140
141 shared_ptr<PolicyErrorArgs> arg = make_shared<PolicyErrorArgs>();
142 if (arg == nullptr) {
143 LOGE("Make_shared is failed");
144 return res;
145 }
146 arg->errNo = FilePermission::RevokePermission(uriPolicies, arg->errorResults);
147 CJError err = ConvertError(arg->errNo);
148 if (err.errorcode != 0) {
149 res.size = static_cast<int64_t>(arg->errorResults.size());
150 if (res.size <= 0) {
151 LOGE("size is less than 0");
152 return res;
153 }
154 CPolicyErrorResult* retArrValue =
155 static_cast<CPolicyErrorResult*>(malloc(sizeof(CPolicyErrorResult) * res.size));
156 if (retArrValue == nullptr) {
157 LOGE("malloc is failed");
158 return res;
159 }
160 for (int64_t i = 0; i < res.size; i++) {
161 retArrValue[i].uri = MallocCString(arg->errorResults[i].uri);
162 retArrValue[i].code = arg->errorResults[i].code;
163 retArrValue[i].message = MallocCString(arg->errorResults[i].message);
164 }
165 res.head = retArrValue;
166 }
167 *code = err.errorcode;
168 return res;
169 }
170
FfiOHOSFileGPActivatePermission(CArrCPolicyInfo policies,int32_t * code)171 CArrCPolicyErrorResult FfiOHOSFileGPActivatePermission(CArrCPolicyInfo policies, int32_t* code)
172 {
173 CArrCPolicyErrorResult res = { nullptr, 0 };
174 if (policies.head == nullptr || code == nullptr) {
175 LOGE("input is nullptr");
176 return res;
177 }
178 *code = E_UNKNOWN_ERROR;
179 std::vector<UriPolicyInfo> uriPolicies;
180 for (int64_t i = 0; i < policies.size; i++) {
181 auto head = policies.head + i;
182 std::string uriStr(head->uri);
183 UriPolicyInfo uriPolicy { .uri = uriStr, .mode = head->mode };
184 uriPolicies.emplace_back(uriPolicy);
185 }
186
187 shared_ptr<PolicyErrorArgs> arg = make_shared<PolicyErrorArgs>();
188 if (arg == nullptr) {
189 LOGE("Make_shared is failed");
190 return res;
191 }
192 arg->errNo = FilePermission::ActivatePermission(uriPolicies, arg->errorResults);
193 CJError err = ConvertError(arg->errNo);
194 if (err.errorcode != 0) {
195 res.size = static_cast<int64_t>(arg->errorResults.size());
196 if (res.size <= 0) {
197 LOGE("size is less than 0");
198 return res;
199 }
200 CPolicyErrorResult* retArrValue =
201 static_cast<CPolicyErrorResult*>(malloc(sizeof(CPolicyErrorResult) * res.size));
202 if (retArrValue == nullptr) {
203 LOGE("malloc is failed");
204 return res;
205 }
206 for (int64_t i = 0; i < res.size; i++) {
207 retArrValue[i].uri = MallocCString(arg->errorResults[i].uri);
208 retArrValue[i].code = arg->errorResults[i].code;
209 retArrValue[i].message = MallocCString(arg->errorResults[i].message);
210 }
211 res.head = retArrValue;
212 }
213 *code = err.errorcode;
214 return res;
215 }
216
FfiOHOSFileGPDeactivatePermission(CArrCPolicyInfo policies,int32_t * code)217 CArrCPolicyErrorResult FfiOHOSFileGPDeactivatePermission(CArrCPolicyInfo policies, int32_t* code)
218 {
219 CArrCPolicyErrorResult res = { nullptr, 0 };
220 if (policies.head == nullptr || code == nullptr) {
221 LOGE("input is nullptr");
222 return res;
223 }
224 *code = E_UNKNOWN_ERROR;
225 std::vector<UriPolicyInfo> uriPolicies;
226 for (int64_t i = 0; i < policies.size; i++) {
227 auto head = policies.head + i;
228 std::string uriStr(head->uri);
229 UriPolicyInfo uriPolicy { .uri = uriStr, .mode = head->mode };
230 uriPolicies.emplace_back(uriPolicy);
231 }
232
233 shared_ptr<PolicyErrorArgs> arg = make_shared<PolicyErrorArgs>();
234 if (arg == nullptr) {
235 LOGE("Make_shared is failed");
236 return res;
237 }
238 arg->errNo = FilePermission::DeactivatePermission(uriPolicies, arg->errorResults);
239 CJError err = ConvertError(arg->errNo);
240 if (err.errorcode != 0) {
241 res.size = static_cast<int64_t>(arg->errorResults.size());
242 if (res.size <= 0) {
243 LOGE("size is 0");
244 return res;
245 }
246 CPolicyErrorResult* retArrValue =
247 static_cast<CPolicyErrorResult*>(malloc(sizeof(CPolicyErrorResult) * res.size));
248 if (retArrValue == nullptr) {
249 LOGE("malloc is failed");
250 return res;
251 }
252 for (int64_t i = 0; i < res.size; i++) {
253 retArrValue[i].uri = MallocCString(arg->errorResults[i].uri);
254 retArrValue[i].code = arg->errorResults[i].code;
255 retArrValue[i].message = MallocCString(arg->errorResults[i].message);
256 }
257 res.head = retArrValue;
258 }
259 *code = err.errorcode;
260 return res;
261 }
262
FfiOHOSFileGPCheckPersistentPermission(CArrCPolicyInfo policies,int32_t * code)263 CArrBool FfiOHOSFileGPCheckPersistentPermission(CArrCPolicyInfo policies, int32_t* code)
264 {
265 CArrBool res = { nullptr, 0 };
266 if (policies.head == nullptr || code == nullptr) {
267 LOGE("input is nullptr");
268 return res;
269 }
270 *code = E_UNKNOWN_ERROR;
271 std::vector<UriPolicyInfo> uriPolicies;
272 for (int64_t i = 0; i < policies.size; i++) {
273 auto head = policies.head + i;
274
275 std::string uriStr(head->uri);
276 UriPolicyInfo uriPolicy { .uri = uriStr, .mode = head->mode };
277 uriPolicies.emplace_back(uriPolicy);
278 }
279
280 shared_ptr<PolicyInfoResultArgs> arg = make_shared<PolicyInfoResultArgs>();
281 if (arg == nullptr) {
282 LOGE("Make_shared is failed");
283 return res;
284 }
285 arg->errNo = FilePermission::CheckPersistentPermission(uriPolicies, arg->resultData);
286 CJError err = ConvertError(arg->errNo);
287 res.size = static_cast<int64_t>(arg->resultData.size());
288 if (res.size <= 0) {
289 LOGE("size is 0");
290 return res;
291 }
292 bool* retArrValue = static_cast<bool*>(malloc(sizeof(bool) * res.size));
293 if (retArrValue == nullptr) {
294 LOGE("malloc is failed");
295 return res;
296 }
297 for (int64_t i = 0; i < res.size; i++) {
298 retArrValue[i] = arg->resultData[i];
299 }
300 res.head = retArrValue;
301 *code = err.errorcode;
302 return res;
303 }
304
FfiOHOSFreeArrBool(CArrBool * tags)305 void FfiOHOSFreeArrBool(CArrBool* tags)
306 {
307 if (tags == nullptr || tags->head == nullptr) {
308 LOGE("input is nullptr");
309 return;
310 }
311
312 free(tags->head);
313 tags->head = nullptr;
314 tags->size = 0;
315 }
316
FfiOHOSFreeArrPolicyErrorResult(CArrCPolicyErrorResult * policies)317 void FfiOHOSFreeArrPolicyErrorResult(CArrCPolicyErrorResult* policies)
318 {
319 if (policies == nullptr || policies->head == nullptr) {
320 LOGE("input is nullptr");
321 return;
322 }
323
324 for (int64_t i = 0; i < policies->size; i++) {
325 free(policies->head[i].uri);
326 free(policies->head[i].message);
327 }
328
329 free(policies->head);
330 policies->head = nullptr;
331 policies->size = 0;
332 }
333 }
334 } // namespace FileGrantPermission
335 } // namespace CJSystemapi
336 } // namespace OHOS