• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "grant_permissions.h"
16 
17 #include <string>
18 #include <vector>
19 
20 #include "access_token.h"
21 #include "accesstoken_kit.h"
22 #include "ipc_skeleton.h"
23 #include "js_native_api.h"
24 #include "log.h"
25 #include "n_napi.h"
26 #include "tokenid_kit.h"
27 
28 namespace OHOS {
29 namespace AppFileService {
30 namespace ModuleFileShare {
31 using namespace OHOS::FileManagement::LibN;
32 using namespace OHOS::Security::AccessToken;
33 using namespace std;
34 
GetErrData(napi_env env,deque<struct PolicyErrorResult> & errorResults)35 static napi_value GetErrData(napi_env env, deque<struct PolicyErrorResult> &errorResults)
36 {
37     napi_value res = nullptr;
38     napi_status status = napi_create_array(env, &res);
39     if (status != napi_ok) {
40         LOGE("Failed to create array");
41         return nullptr;
42     }
43     size_t index = 0;
44     for (auto &iter : errorResults) {
45         NVal obj = NVal::CreateObject(env);
46         obj.AddProp("uri", NVal::CreateUTF8String(env, iter.uri).val_);
47         obj.AddProp("code", NVal::CreateInt32(env, iter.code).val_);
48         obj.AddProp("message", NVal::CreateUTF8String(env, iter.message).val_);
49         status = napi_set_element(env, res, index++, obj.val_);
50         if (status != napi_ok) {
51             LOGE("Failed to set element on data");
52             return nullptr;
53         }
54     }
55     return res;
56 }
57 
GetResultData(napi_env env,const vector<bool> & results)58 static napi_value GetResultData(napi_env env, const vector<bool> &results)
59 {
60     napi_value res = nullptr;
61     napi_status status = napi_create_array(env, &res);
62     if (status != napi_ok) {
63         LOGE("Failed to create array");
64         return nullptr;
65     }
66     size_t index = 0;
67     for (const auto &iter : results) {
68         napi_value value;
69         napi_get_boolean(env, iter, &value);
70         status = napi_set_element(env, res, index++, value);
71         if (status != napi_ok) {
72             LOGE("Failed to set element on data");
73             return nullptr;
74         }
75     }
76     return res;
77 }
78 
GetUriPolicy(napi_env env,napi_value agrv,std::vector<UriPolicyInfo> & uriPolicies,uint32_t index)79 static napi_status GetUriPolicy(napi_env env, napi_value agrv, std::vector<UriPolicyInfo> &uriPolicies, uint32_t index)
80 {
81     napi_value object;
82     napi_status status = napi_get_element(env, agrv, index, &object);
83     if (status != napi_ok) {
84         LOGE("get element failed");
85         return status;
86     }
87     napi_value uriValue;
88     napi_value modeValue;
89     status = napi_get_named_property(env, object, "uri", &uriValue);
90     if (status != napi_ok) {
91         LOGE("get named property failed");
92         return status;
93     }
94     status = napi_get_named_property(env, object, "operationMode", &modeValue);
95     if (status != napi_ok) {
96         LOGE("get named property failed");
97         return status;
98     }
99     auto [succStr, str, ignore] = NVal(env, uriValue).ToUTF8String();
100     auto [succMode, mode] = NVal(env, modeValue).ToUint32();
101     if (!succStr || !succMode) {
102         LOGE("the argument error, succStr = %{public}d, succMode = %{public}d", succStr, succMode);
103         return napi_invalid_arg;
104     }
105     UriPolicyInfo uriPolicy {.uri = str.get(), .mode = mode};
106     uriPolicies.emplace_back(uriPolicy);
107     return napi_ok;
108 }
109 
GetUriPoliciesArg(napi_env env,napi_value agrv,std::vector<UriPolicyInfo> & uriPolicies)110 static napi_status GetUriPoliciesArg(napi_env env, napi_value agrv, std::vector<UriPolicyInfo> &uriPolicies)
111 {
112     uint32_t count;
113     napi_status status = napi_get_array_length(env, agrv, &count);
114     if (status != napi_ok) {
115         LOGE("get array length failed");
116         return status;
117     }
118     if (count > MAX_ARRAY_SIZE) {
119         LOGE("The length of the array is extra-long");
120         return napi_invalid_arg;
121     }
122     for (uint32_t i = 0; i < count; i++) {
123         napi_handle_scope scope;
124         status = napi_open_handle_scope(env, &scope);
125         if (status != napi_ok) {
126             return status;
127         }
128         status = GetUriPolicy(env, agrv, uriPolicies, i);
129         if (status != napi_ok) {
130             napi_close_handle_scope(env, scope);
131             return status;
132         }
133         status = napi_close_handle_scope(env, scope);
134         if (status != napi_ok) {
135             return status;
136         }
137     }
138     return napi_ok;
139 }
140 
CheckPathArray(napi_env env,napi_value agrv,uint32_t & count)141 static napi_status CheckPathArray(napi_env env, napi_value agrv, uint32_t &count)
142 {
143     napi_status status = napi_get_array_length(env, agrv, &count);
144     if (status != napi_ok) {
145         LOGE("get array length failed");
146         return status;
147     }
148     if (count == 0 || count > MAX_ARRAY_SIZE) {
149         LOGE("The length of the array is extra-long or length is 0");
150         return napi_invalid_arg;
151     }
152     return napi_ok;
153 }
154 
GetPathPolicy(napi_env env,napi_value agrv,std::vector<PathPolicyInfo> & pathPolicies,uint32_t index)155 static napi_status GetPathPolicy(napi_env env,
156                                  napi_value agrv,
157                                  std::vector<PathPolicyInfo> &pathPolicies,
158                                  uint32_t index)
159 {
160     napi_value object;
161     napi_status status = napi_get_element(env, agrv, index, &object);
162     if (status != napi_ok) {
163         LOGE("get element failed");
164         return status;
165     }
166     napi_value pathValue;
167     napi_value modeValue;
168     status = napi_get_named_property(env, object, "path", &pathValue);
169     if (status != napi_ok) {
170         LOGE("get named property failed");
171         return status;
172     }
173     status = napi_get_named_property(env, object, "operationMode", &modeValue);
174     if (status != napi_ok) {
175         LOGE("get named property failed");
176         return status;
177     }
178     auto [succStr, str, ignore] = NVal(env, pathValue).ToUTF8String();
179     auto [succMode, mode] = NVal(env, modeValue).ToUint32();
180     if (!succStr || !succMode) {
181         LOGE("the argument error, succStr = %{public}d, succMode = %{public}d", succStr, succMode);
182         return napi_invalid_arg;
183     }
184     PathPolicyInfo pathPolicy {.path = str.get(), .mode = mode};
185     pathPolicies.emplace_back(pathPolicy);
186     return napi_ok;
187 }
188 
GetPathPoliciesArg(napi_env env,napi_value agrv,std::vector<PathPolicyInfo> & pathPolicies)189 static napi_status GetPathPoliciesArg(napi_env env, napi_value agrv, std::vector<PathPolicyInfo> &pathPolicies)
190 {
191     uint32_t count;
192     napi_status status = CheckPathArray(env, agrv, count);
193     if (status != napi_ok) {
194         return status;
195     }
196     for (uint32_t i = 0; i < count; i++) {
197         napi_handle_scope scope;
198         status = napi_open_handle_scope(env, &scope);
199         if (status != napi_ok) {
200             LOGE("open handle scope failed");
201             return status;
202         }
203         status = GetPathPolicy(env, agrv, pathPolicies, i);
204         if (status != napi_ok) {
205             napi_close_handle_scope(env, scope);
206             return status;
207         }
208         status = napi_close_handle_scope(env, scope);
209         if (status != napi_ok) {
210             return status;
211         }
212     }
213     return napi_ok;
214 }
215 
IsSystemApp()216 static bool IsSystemApp()
217 {
218     uint64_t fullTokenId = OHOS::IPCSkeleton::GetCallingFullTokenID();
219     return TokenIdKit::IsSystemAppByFullTokenID(fullTokenId);
220 }
221 
PersistPermission(napi_env env,napi_callback_info info)222 napi_value PersistPermission(napi_env env, napi_callback_info info)
223 {
224     NFuncArg funcArg(env, info);
225     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
226         LOGE("PersistPermission Number of arguments unmatched");
227         NError(E_PARAMS).ThrowErr(env);
228         return nullptr;
229     }
230     std::vector<UriPolicyInfo> uriPolicies;
231     if (GetUriPoliciesArg(env, funcArg[NARG_POS::FIRST], uriPolicies) != napi_ok) {
232         NError(E_PARAMS).ThrowErr(env);
233         return nullptr;
234     }
235     shared_ptr<PolicyErrorArgs> arg = make_shared<PolicyErrorArgs>();
236     if (arg == nullptr) {
237         LOGE("Make_shared is failed");
238         std::tuple<uint32_t, std::string> errInfo =
239             std::make_tuple(E_UNKNOWN_ERROR, "Out of memory, execute make_shared function failed");
240         ErrParam errorParam = [errInfo]() { return errInfo; };
241         NError(errorParam).ThrowErr(env);
242         return nullptr;
243     }
244     auto cbExec = [uriPolicies, arg]() -> NError {
245         arg->errNo = FilePermission::PersistPermission(uriPolicies, arg->errorResults);
246         return NError(arg->errNo);
247     };
248     auto cbCompl = [arg](napi_env env, NError err) -> NVal {
249         if (err) {
250             if (arg->errNo == EPERM) {
251                 napi_value data = err.GetNapiErr(env);
252                 napi_set_named_property(env, data, FILEIO_TAG_ERR_DATA.c_str(), GetErrData(env, arg->errorResults));
253                 return NVal(env, data);
254             }
255             return {env, err.GetNapiErr(env)};
256         }
257         return NVal::CreateUndefined(env);
258     };
259     const string procedureName = "persist_permission";
260     NVal thisVar(env, funcArg.GetThisVar());
261     return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbCompl).val_;
262 }
263 
RevokePermission(napi_env env,napi_callback_info info)264 napi_value RevokePermission(napi_env env, napi_callback_info info)
265 {
266     NFuncArg funcArg(env, info);
267     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
268         LOGE("RevokePermission Number of arguments unmatched");
269         NError(E_PARAMS).ThrowErr(env);
270         return nullptr;
271     }
272     std::vector<UriPolicyInfo> uriPolicies;
273     if (GetUriPoliciesArg(env, funcArg[NARG_POS::FIRST], uriPolicies) != napi_ok) {
274         NError(E_PARAMS).ThrowErr(env);
275         return nullptr;
276     }
277     shared_ptr<PolicyErrorArgs> arg = make_shared<PolicyErrorArgs>();
278     if (arg == nullptr) {
279         LOGE("Make_shared is failed");
280         std::tuple<uint32_t, std::string> errInfo =
281             std::make_tuple(E_UNKNOWN_ERROR, "Out of memory, execute make_shared function failed");
282         ErrParam errorParam = [errInfo]() { return errInfo; };
283         NError(errorParam).ThrowErr(env);
284         return nullptr;
285     }
286     auto cbExec = [uriPolicies, arg]() -> NError {
287         arg->errNo = FilePermission::RevokePermission(uriPolicies, arg->errorResults);
288         return NError(arg->errNo);
289     };
290     auto cbCompl = [arg](napi_env env, NError err) -> NVal {
291         if (err) {
292             if (arg->errNo == EPERM) {
293                 napi_value data = err.GetNapiErr(env);
294                 napi_set_named_property(env, data, FILEIO_TAG_ERR_DATA.c_str(), GetErrData(env, arg->errorResults));
295                 return NVal(env, data);
296             }
297             return {env, err.GetNapiErr(env)};
298         }
299         return NVal::CreateUndefined(env);
300     };
301     const string procedureName = "revoke_permission";
302     NVal thisVar(env, funcArg.GetThisVar());
303     return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbCompl).val_;
304 }
305 
ActivatePermission(napi_env env,napi_callback_info info)306 napi_value ActivatePermission(napi_env env, napi_callback_info info)
307 {
308     NFuncArg funcArg(env, info);
309     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
310         LOGE("ActivatePermission Number of arguments unmatched");
311         NError(E_PARAMS).ThrowErr(env);
312         return nullptr;
313     }
314     std::vector<UriPolicyInfo> uriPolicies;
315     if (GetUriPoliciesArg(env, funcArg[NARG_POS::FIRST], uriPolicies) != napi_ok) {
316         NError(E_PARAMS).ThrowErr(env);
317         return nullptr;
318     }
319     shared_ptr<PolicyErrorArgs> arg = make_shared<PolicyErrorArgs>();
320     if (arg == nullptr) {
321         LOGE("Make_shared is failed");
322         std::tuple<uint32_t, std::string> errInfo =
323             std::make_tuple(E_UNKNOWN_ERROR, "Out of memory, execute make_shared function failed");
324         ErrParam errorParam = [errInfo]() { return errInfo; };
325         NError(errorParam).ThrowErr(env);
326         return nullptr;
327     }
328     auto cbExec = [uriPolicies, arg]() -> NError {
329         arg->errNo = FilePermission::ActivatePermission(uriPolicies, arg->errorResults);
330         return NError(arg->errNo);
331     };
332     auto cbCompl = [arg](napi_env env, NError err) -> NVal {
333         if (err) {
334             if (arg->errNo == EPERM) {
335                 napi_value data = err.GetNapiErr(env);
336                 napi_set_named_property(env, data, FILEIO_TAG_ERR_DATA.c_str(), GetErrData(env, arg->errorResults));
337                 return NVal(env, data);
338             }
339             return {env, err.GetNapiErr(env)};
340         }
341         return NVal::CreateUndefined(env);
342     };
343     const string procedureName = "activate_permission";
344     NVal thisVar(env, funcArg.GetThisVar());
345     return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbCompl).val_;
346 }
347 
DeactivatePermission(napi_env env,napi_callback_info info)348 napi_value DeactivatePermission(napi_env env, napi_callback_info info)
349 {
350     NFuncArg funcArg(env, info);
351     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
352         LOGE("DeactivatePermission Number of arguments unmatched");
353         NError(E_PARAMS).ThrowErr(env);
354         return nullptr;
355     }
356     std::vector<UriPolicyInfo> uriPolicies;
357     if (GetUriPoliciesArg(env, funcArg[NARG_POS::FIRST], uriPolicies) != napi_ok) {
358         NError(E_PARAMS).ThrowErr(env);
359         return nullptr;
360     }
361     shared_ptr<PolicyErrorArgs> arg = make_shared<PolicyErrorArgs>();
362     if (arg == nullptr) {
363         LOGE("Make_shared is failed");
364         std::tuple<uint32_t, std::string> errInfo =
365             std::make_tuple(E_UNKNOWN_ERROR, "Out of memory, execute make_shared function failed");
366         ErrParam errorParam = [errInfo]() { return errInfo; };
367         NError(errorParam).ThrowErr(env);
368         return nullptr;
369     }
370     auto cbExec = [uriPolicies, arg]() -> NError {
371         arg->errNo = FilePermission::DeactivatePermission(uriPolicies, arg->errorResults);
372         return NError(arg->errNo);
373     };
374     auto cbCompl = [arg](napi_env env, NError err) -> NVal {
375         if (err) {
376             if (arg->errNo == EPERM) {
377                 napi_value data = err.GetNapiErr(env);
378                 napi_set_named_property(env, data, FILEIO_TAG_ERR_DATA.c_str(), GetErrData(env, arg->errorResults));
379                 return NVal(env, data);
380             }
381             return {env, err.GetNapiErr(env)};
382         }
383         return NVal::CreateUndefined(env);
384     };
385     const string procedureName = "deactivate_permission";
386     NVal thisVar(env, funcArg.GetThisVar());
387     return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbCompl).val_;
388 }
389 
CheckPersistentPermission(napi_env env,napi_callback_info info)390 napi_value CheckPersistentPermission(napi_env env, napi_callback_info info)
391 {
392     NFuncArg funcArg(env, info);
393     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
394         LOGE("ActivatePermission Number of arguments unmatched");
395         NError(E_PARAMS).ThrowErr(env);
396         return nullptr;
397     }
398     std::vector<UriPolicyInfo> uriPolicies;
399     if (GetUriPoliciesArg(env, funcArg[NARG_POS::FIRST], uriPolicies) != napi_ok) {
400         NError(E_PARAMS).ThrowErr(env);
401         return nullptr;
402     }
403     shared_ptr<PolicyInfoResultArgs> arg = make_shared<PolicyInfoResultArgs>();
404     if (arg == nullptr) {
405         LOGE("Make_shared is failed");
406         std::tuple<uint32_t, std::string> errInfo =
407             std::make_tuple(E_UNKNOWN_ERROR, "Out of memory, execute make_shared function failed");
408         ErrParam errorParam = [errInfo]() { return errInfo; };
409         NError(errorParam).ThrowErr(env);
410         return nullptr;
411     }
412     auto cbExec = [uriPolicies, arg]() -> NError {
413         arg->errNo = FilePermission::CheckPersistentPermission(uriPolicies, arg->resultData);
414         return NError(arg->errNo);
415     };
416     auto cbCompl = [arg](napi_env env, NError err) -> NVal {
417         if (arg->errNo != 0) {
418             return {env, err.GetNapiErr(env)};
419         }
420         return {env, GetResultData(env, arg->resultData)};
421     };
422     const string procedureName = "check_persist_permission";
423     NVal thisVar(env, funcArg.GetThisVar());
424     return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbCompl).val_;
425 }
426 
CheckTokenIdPermission(uint32_t tokenCaller,const string & permission)427 static bool CheckTokenIdPermission(uint32_t tokenCaller, const string &permission)
428 {
429     return AccessTokenKit::VerifyAccessToken(tokenCaller, permission) == PermissionState::PERMISSION_GRANTED;
430 }
431 
CheckArgs(napi_env env,napi_callback_info info,NFuncArg & funcArg)432 static bool CheckArgs(napi_env env, napi_callback_info info, NFuncArg &funcArg)
433 {
434     if (!funcArg.InitArgs(NARG_CNT::THREE)) {
435         LOGE("ActivatePermission Number of arguments unmatched");
436         return false;
437     }
438 
439     auto [succTokenId, tokenId] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32();
440     if (!succTokenId || tokenId == 0) {
441         LOGE("Failed to get tokenid or tokenid is 0");
442         return false;
443     }
444 
445     auto [succPolicyType, policyType] = NVal(env, funcArg[NARG_POS::THIRD]).ToInt32();
446     if (!succPolicyType || policyType < TEMPORARY_TYPE || policyType > PERSISTENT_TYPE) {
447         LOGE("Failed to get policy type or policy type is invalid");
448         return false;
449     }
450     return true;
451 }
452 
CheckPathPermission(napi_env env,napi_callback_info info)453 napi_value CheckPathPermission(napi_env env, napi_callback_info info)
454 {
455     if (!IsSystemApp()) {
456         LOGE("FileShare::CheckPathPermission is not System App!");
457         NError(E_PERMISSION_SYS).ThrowErr(env);
458         return nullptr;
459     }
460 
461     NFuncArg funcArg(env, info);
462     if (!CheckArgs(env, info, funcArg)) {
463         NError(E_PARAMS).ThrowErr(env);
464         return nullptr;
465     }
466 
467     auto [succTokenId, tokenId] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32();
468 
469     uint32_t callerTokenId = OHOS::IPCSkeleton::GetCallingTokenID();
470     if (tokenId != static_cast<int32_t>(callerTokenId)) {
471         if (!CheckTokenIdPermission(callerTokenId, "ohos.permission.CHECK_SANDBOX_POLICY")) {
472             NError(E_PERMISSION).ThrowErr(env);
473             return nullptr;
474         }
475     }
476 
477     std::vector<PathPolicyInfo> pathPolicies;
478     if (GetPathPoliciesArg(env, funcArg[NARG_POS::SECOND], pathPolicies) != napi_ok) {
479         NError(E_PARAMS).ThrowErr(env);
480         return nullptr;
481     }
482 
483     auto [succPolicyType, policyType] = NVal(env, funcArg[NARG_POS::THIRD]).ToInt32();
484 
485     LOGI("check permission target:%{public}d type:%{public}d", tokenId, policyType);
486 
487     shared_ptr<PolicyInfoResultArgs> arg = make_shared<PolicyInfoResultArgs>();
488     if (arg == nullptr) {
489         LOGE("Make_shared is failed");
490         std::tuple<uint32_t, std::string> errInfo =
491             std::make_tuple(E_UNKNOWN_ERROR, "Out of memory, execute make_shared function failed");
492         ErrParam errorParam = [errInfo]() { return errInfo; };
493         NError(errorParam).ThrowErr(env);
494         return nullptr;
495     }
496     auto cbExec = [tokenId {move(tokenId)}, pathPolicies, policyType {move(policyType)}, arg]() -> NError {
497         arg->errNo = FilePermission::CheckPathPermission(tokenId, pathPolicies, policyType, arg->resultData);
498         return NError(arg->errNo);
499     };
500     auto cbCompl = [arg](napi_env env, NError err) -> NVal {
501         if (arg->errNo != 0) {
502             return {env, err.GetNapiErr(env)};
503         }
504         return {env, GetResultData(env, arg->resultData)};
505     };
506     const string procedureName = "check_path_permission";
507     NVal thisVar(env, funcArg.GetThisVar());
508     return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbCompl).val_;
509 }
510 
GrantDecUriPermission(napi_env env,FileManagement::LibN::NFuncArg & funcArg)511 napi_value GrantDecUriPermission(napi_env env, FileManagement::LibN::NFuncArg &funcArg)
512 {
513     LOGI("GrantDecUriPermission");
514     std::vector<UriPolicyInfo> uriPolicies;
515     if (GetUriPoliciesArg(env, funcArg[NARG_POS::FIRST], uriPolicies) != napi_ok) {
516         NError(E_PARAMS).ThrowErr(env);
517         return nullptr;
518     }
519 
520     auto [succBundleName, bundleName, lenBundleName] = NVal(env, funcArg[NARG_POS::SECOND]).ToUTF8String();
521     if (!succBundleName) {
522         LOGE("FileShare::GetJSArgs get bundleName parameter failed!");
523         NError(EINVAL).ThrowErr(env);
524         return nullptr;
525     }
526     std::string targetBundleName = string(bundleName.get());
527 
528     auto [succAppCloneIndex, appCloneIndex] = NVal(env, funcArg[NARG_POS::THIRD]).ToInt32();
529 
530     shared_ptr<PolicyErrorArgs> arg = make_shared<PolicyErrorArgs>();
531     if (arg == nullptr) {
532         LOGE("PolicyInfoResultArgs make_shared is failed");
533         NError(E_NOMEM).ThrowErr(env);
534         return nullptr;
535     }
536     auto cbExec = [uriPolicies, targetBundleName, appCloneIndex {move(appCloneIndex)}, arg]() -> NError {
537         arg->errNo = FilePermission::GrantPermission(uriPolicies, targetBundleName, appCloneIndex, arg->errorResults);
538         return NError(arg->errNo);
539     };
540     auto cbCompl = [arg](napi_env env, NError err) -> NVal {
541         if (err) {
542             if (arg->errNo == EPERM) {
543                 napi_value data = err.GetNapiErr(env);
544                 napi_set_named_property(env, data, FILEIO_TAG_ERR_DATA.c_str(), GetErrData(env, arg->errorResults));
545                 return NVal(env, data);
546             }
547             return {env, err.GetNapiErr(env)};
548         }
549         return NVal::CreateUndefined(env);
550     };
551     const string procedureName = "grant_permission";
552     NVal thisVar(env, funcArg.GetThisVar());
553     return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbCompl).val_;
554 }
555 
556 } // namespace ModuleFileShare
557 } // namespace AppFileService
558 } // namespace OHOS
559