diff --git a/BUILD.gn b/BUILD.gn index 1a2830cf6c3c7a0df574a8b9f3bc7010862f62c7..8016013d1608e6602e4a5f89bc8682185cb5e011 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -14,5 +14,12 @@ import("//build/ohos.gni") group("libremotefileshare") { - deps = [ "//foundation/filemanagement/app_file_service/interfaces/kits/js:remotefileshare" ] + deps = [ + "//foundation/filemanagement/app_file_service/interfaces/innerkits/remote_file_share/native:remote_file_share_native", + "//foundation/filemanagement/app_file_service/interfaces/kits/js:remotefileshare", + ] +} + +group("exeremotefiletest") { + deps = [ "//foundation/filemanagement/app_file_service/test/unittest:remote_file_test" ] } diff --git a/bundle.json b/bundle.json index 287695427e9bf0719252dd1ebf51bb902ea4e75d..aabe5b3973842785a224ef071de4fbf002134264 100644 --- a/bundle.json +++ b/bundle.json @@ -25,7 +25,8 @@ "group_type": { "base_group": [], "fwk_group": [ - "//foundation/filemanagement/app_file_service:libremotefileshare" + "//foundation/filemanagement/app_file_service:libremotefileshare", + "//foundation/filemanagement/app_file_service:exeremotefiletest" ], "service_group": [] }, diff --git a/interfaces/innerkits/remote_file_share/native/BUILD.gn b/interfaces/innerkits/remote_file_share/native/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..b0adf7e4e7b69a1fcdb10952229779554390eee5 --- /dev/null +++ b/interfaces/innerkits/remote_file_share/native/BUILD.gn @@ -0,0 +1,49 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +ohos_shared_library("remote_file_share_native") { + include_dirs = [ + "include", + "//utils/system/safwk/native/include", + "//commonlibrary/c_utils/base/include", + "//foundation/arkui/napi/interfaces/kits", + "//third_party/bounds_checking_function/include", + "//foundation/filemanagement/app_file_service/interfaces/innerkits/remote_file_share/native", + ] + + sources = [ "//foundation/filemanagement/app_file_service/services/remote_file_share/src/remote_file_share.cpp" ] + + deps = [ + "//foundation/distributeddatamgr/distributedfile/utils/filemgmt_libn", + "//third_party/bounds_checking_function:libsec_shared", + ] + + external_deps = [ + "access_token:libaccesstoken_sdk", + "c_utils:utils", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + ] + + defines = [ + "REMOTE_SHARE_FILE_LOG_TAG=\"app_file_service\"", + "LOG_DOMAIN=0xD200000", + ] + + relative_install_dir = "module" + + part_name = "app_file_service" + subsystem_name = "filemanagement" +} diff --git a/interfaces/innerkits/remote_file_share/native/remote_file_share.h b/interfaces/innerkits/remote_file_share/native/remote_file_share.h new file mode 100644 index 0000000000000000000000000000000000000000..4aaf50fe2c013c9770323a35aa1e012be9ba0bc3 --- /dev/null +++ b/interfaces/innerkits/remote_file_share/native/remote_file_share.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef REMOTE_FILE_SHARE_H +#define REMOTE_FILE_SHARE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "securec.h" +#include "ipc_skeleton.h" +#include "hap_token_info.h" +#include "accesstoken_kit.h" + +namespace OHOS { +namespace AppFileService { +namespace ModuleRemoteFileShare { + +class RemoteFileShare { +public: + RemoteFileShare() {} + int CreateSharePath(const int src_fd, std::string &hmdfs_share_path, const int uid, + const std::string &cid = "0"); + std::string GetPkgName(); + ~RemoteFileShare() {} +}; + +} // namespace ModuleRemoteFileShare +} // namespace AppFileService +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/interfaces/innerkits/remote_file_share/native/remote_file_share_log.h b/interfaces/innerkits/remote_file_share/native/remote_file_share_log.h new file mode 100644 index 0000000000000000000000000000000000000000..4388cd4246c65135c0450071757dd5675b30a0c1 --- /dev/null +++ b/interfaces/innerkits/remote_file_share/native/remote_file_share_log.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef REMOTE_FILE_SHARE_LOG_H +#define REMOTE_FILE_SHARE_LOG_H + +#include "hilog/log.h" + +namespace OHOS { +static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_DOMAIN, REMOTE_SHARE_FILE_LOG_TAG}; + +#define PRINT_LOG(Level, fmt, ...) \ + OHOS::HiviewDFX::HiLog::Level(OHOS::LOG_LABEL, "[%{public}s:%{public}d] " fmt, \ + __FUNCTION__, __LINE__, ##__VA_ARGS__) + +#define LOGD(fmt, ...) PRINT_LOG(Debug, fmt, ##__VA_ARGS__) +#define LOGI(fmt, ...) PRINT_LOG(Info, fmt, ##__VA_ARGS__) +#define LOGW(fmt, ...) PRINT_LOG(Warn, fmt, ##__VA_ARGS__) +#define LOGE(fmt, ...) PRINT_LOG(Error, fmt, ##__VA_ARGS__) +#define LOGF(fmt, ...) PRINT_LOG(Fatal, fmt, ##__VA_ARGS__) +} // OHOS + +#endif // REMOTE_FILE_SHARE_LOG_H \ No newline at end of file diff --git a/services/remote_file_share/src/remote_file_share.cpp b/services/remote_file_share/src/remote_file_share.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8095cf45c63edf3509cf45e2108e8d9fa5e90155 --- /dev/null +++ b/services/remote_file_share/src/remote_file_share.cpp @@ -0,0 +1,112 @@ +#include "remote_file_share.h" +#include "remote_file_share_log.h" + +namespace OHOS { +namespace AppFileService { +namespace ModuleRemoteFileShare { +using namespace std; +namespace { + constexpr int HMDFS_CID_SIZE = 64; + constexpr unsigned HMDFS_IOC = 0xf2; +} + +#define HMDFS_IOC_SET_SHARE_PATH _IOW(HMDFS_IOC, 1, struct hmdfs_share_control) + +struct hmdfs_share_control { + int src_fd; + char cid[HMDFS_CID_SIZE]; +}; + +int RemoteFileShare::CreateSharePath(const int src_fd, std::string &hmdfs_share_path, const int uid, + const std::string &cid) +{ + struct hmdfs_share_control sc; + int32_t ret = 0; + int32_t dirFd; + const string userid_str = to_string(uid); + const string package_name = this->GetPkgName(); + + const string PACKAGE_PATH = "/data/service/el2/" + userid_str + "/hmdfs/account/services/" + + package_name; + if (access(PACKAGE_PATH.c_str(), F_OK) != 0) { + ret = mkdir(PACKAGE_PATH.c_str(), S_IRWXU); + if (ret < 0) { + LOGE("RemoteFileShare::CreateSharePath, make package_path failed with error code %{public}d", errno); + return errno; + } + } + + const string SHARE_PATH_LOWER = "/data/service/el2/" + userid_str + "/hmdfs/account/services/" + + package_name + "/.share"; + if (access(SHARE_PATH_LOWER.c_str(), F_OK) != 0) { + ret = mkdir(SHARE_PATH_LOWER.c_str(), S_IRWXU); + if (ret < 0) { + LOGE("RemoteFileShare::CreateSharePath, make share path failed with error code %{public}d", errno); + return errno; + } + } + + const string SHARE_PATH = "/mnt/hmdfs/" + userid_str + "/account/merge_view/services/" + + package_name + "/.share"; + char realPath[PATH_MAX] = {'\0'}; + if (!realpath(SHARE_PATH.c_str(), realPath)) { + LOGE("RemoteFileShare::CreateSharePath, realpath failed with error code %{public}d", errno); + return errno; + } + dirFd = open(realPath, O_RDONLY); + if (dirFd < 0) { + return errno; + } + + sc.src_fd = src_fd; + if (memcpy_s(sc.cid, HMDFS_CID_SIZE, cid.c_str(), cid.size()) != 0) { + close(dirFd); + return ENOMEM; + } + + ret = ioctl(dirFd, HMDFS_IOC_SET_SHARE_PATH, &sc); + if (ret < 0) { + close(dirFd); + LOGE("RemoteFileShare::CreateSharePath, ioctl failed with error code %{public}d", errno); + return errno; + } + close(dirFd); + + char buf[PATH_MAX] = {'\0'}; + char file_path[PATH_MAX] = {'\0'}; + + ret = snprintf(buf, sizeof(buf), "/proc/self/fd/%d", sc.src_fd); + if (ret < 0) { + LOGE("RemoteFileShare::CreateSharePath, snprintf failed with error code %{public}d", errno); + return errno; + } + + ret = readlink(buf, file_path, PATH_MAX-1); + if (ret < 0) { + LOGE("RemoteFileShare::CreateSharePath, readlink failed with error code %{public}d", errno); + return errno; + } + + string file_name = file_path; + int first_slash = file_name.rfind("/"); + if (first_slash == file_name.npos) { + LOGE("RemoteFileShare::CreateSharePath, get error path with %{public}s", file_name.c_str()); + return ENOENT; + } + file_name = file_name.substr(first_slash + 1, file_name.size() - first_slash); + hmdfs_share_path = "/mnt/hmdfs/" + userid_str + "/account/merge_view/services/" + + package_name + "/.share/" + file_name; + return 0; +} + +std::string RemoteFileShare::GetPkgName() +{ + uint32_t pid = IPCSkeleton::GetCallingTokenID(); + Security::AccessToken::NativeTokenInfo tokenInfo = Security::AccessToken::NativeTokenInfo(); + Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(pid, tokenInfo); + return tokenInfo.processName; +} + +} // namespace ModuleRemoteFileShare +} // namespace AppFileService +} // namespace OHOS diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..d1ead9ca494ad6d0fbec1e0cbfcec67ff80fae57 --- /dev/null +++ b/test/unittest/BUILD.gn @@ -0,0 +1,49 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +ohos_executable("remote_file_test") { + include_dirs = [ + "include", + "//utils/system/safwk/native/include", + "//commonlibrary/c_utils/base/include", + "//foundation/arkui/napi/interfaces/kits", + "//third_party/bounds_checking_function/include", + "//foundation/filemanagement/app_file_service/interfaces/innerkits/remote_file_share/native", + ] + + sources = [ "//foundation/filemanagement/app_file_service/test/unittest/remote_file_share/remote_file_share_test.cpp" ] + + deps = [ + "//foundation/distributeddatamgr/distributedfile/utils/filemgmt_libn", + "//third_party/bounds_checking_function:libsec_shared", + ] + + external_deps = [ + "access_token:libaccesstoken_sdk", + "c_utils:utils", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + ] + + defines = [ + "REMOTE_SHARE_FILE_LOG_TAG=\"app_file_service\"", + "LOG_DOMAIN=0xD200000", + ] + + relative_install_dir = "module" + + part_name = "app_file_service" + subsystem_name = "filemanagement" +} diff --git a/test/unittest/remote_file_share/remote_file_share_test.cpp b/test/unittest/remote_file_share/remote_file_share_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f0d853374beba8e2c1e0f75d9a8a4702e9cc4614 --- /dev/null +++ b/test/unittest/remote_file_share/remote_file_share_test.cpp @@ -0,0 +1,62 @@ +#include +#include +#include +#include +#include +#include +#include +#include + + +#define HMDFS_IOC 0xf2 +#define HMDFS_IOC_SET_SHARE_PATH _IOW(HMDFS_IOC, 1, \ + struct hmdfs_share_control) + +#define HMDFS_CID_SIZE 64 + +struct hmdfs_share_control { + int src_fd; + char cid[HMDFS_CID_SIZE]; +}; + +using namespace std; + +int main() +{ + int ret; + int dirFd, realFileFd; + struct hmdfs_share_control sc; + string shareDirPath = "/data/service/el2/100/hmdfs/account/services/pasteboard/.share"; + string realFilePath = "/data/test.txt"; + string shareFilePath = shareDirPath + "/test.txt"; + char cid[HMDFS_CID_SIZE + 1] = "0"; + + /* open realFile */ + realFileFd = open(realFilePath.c_str(), O_RDWR); + if (realFileFd < 0) { + cout << "open realfile failed: " << errno << " " << realFilePath << endl; + return -1; + } + + /* ioctl cmd */ + sc.src_fd = realFileFd; + memcpy(sc.cid, cid, HMDFS_CID_SIZE); + + /* open share dir */ + dirFd = open(shareDirPath.c_str(), O_RDONLY); + if (dirFd < 0) { + close(realFileFd); + cout << "open share dir failed: " << errno << " " << shareFilePath << endl; + return -1; + } + + /* ioctl share dir */ + ret = ioctl(dirFd, HMDFS_IOC_SET_SHARE_PATH, &sc); + if (ret < 0) { + cout << "ioctl realfile failed: " << errno << endl; + } + + close(realFileFd); + close(dirFd); + return ret; +} \ No newline at end of file