• 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 
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