From 2e9bc120574cff14927e9bdbf2a480090e51ba92 Mon Sep 17 00:00:00 2001 From: zhangkaixiang Date: Wed, 24 Aug 2022 15:50:41 +0800 Subject: [PATCH] add innerkit interface for create_share_path Signed-off-by: zhangkaixiang --- BUILD.gn | 5 +- .../remote_file_share/native/BUILD.gn | 40 ++++ .../native/remote_file_share.h | 35 +++ .../native/remote_file_share_log.h | 34 +++ .../src/remote_file_share.cpp | 203 ++++++++++++++++++ 5 files changed, 316 insertions(+), 1 deletion(-) create mode 100644 interfaces/innerkits/remote_file_share/native/BUILD.gn create mode 100644 interfaces/innerkits/remote_file_share/native/remote_file_share.h create mode 100644 interfaces/innerkits/remote_file_share/native/remote_file_share_log.h create mode 100644 services/remote_file_share/src/remote_file_share.cpp diff --git a/BUILD.gn b/BUILD.gn index 1a2830cf6..2c041cd26 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -14,5 +14,8 @@ 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", + ] } 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 000000000..706bf36b0 --- /dev/null +++ b/interfaces/innerkits/remote_file_share/native/BUILD.gn @@ -0,0 +1,40 @@ +# 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/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" ] + + external_deps = [ + "c_utils:utils", + "hiviewdfx_hilog_native:libhilog", + ] + + defines = [ + "REMOTE_SHARE_FILE_LOG_TAG=\"RemoteFileShare\"", + "LOG_DOMAIN=0xD004312", + ] + + 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 000000000..589e29f4d --- /dev/null +++ b/interfaces/innerkits/remote_file_share/native/remote_file_share.h @@ -0,0 +1,35 @@ +/* + * 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 + +namespace OHOS { +namespace AppFileService { +namespace ModuleRemoteFileShare { +class RemoteFileShare { +public: + RemoteFileShare() {} + int CreateSharePath(const int &fd, std::string &sharePath, + const int &userId, const std::string &deviceId = ""); + ~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 000000000..4388cd424 --- /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 000000000..dfee443c1 --- /dev/null +++ b/services/remote_file_share/src/remote_file_share.cpp @@ -0,0 +1,203 @@ +/* + * 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. + */ + +#include "remote_file_share.h" +#include "remote_file_share_log.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "securec.h" + +namespace OHOS { +namespace AppFileService { +namespace ModuleRemoteFileShare { +namespace { + const int HMDFS_CID_SIZE = 64; + const unsigned HMDFS_IOC = 0xf2; + const std::string SHAER_PATH_HEAD = "/mnt/hmdfs/"; + const std::string SHAER_PATH_MID = "/account/merge_view/services/"; + const std::string LOWER_SHARE_PATH_HEAD = "/data/service/el2/"; + const std::string LOWER_SHARE_PATH_MID = "/hmdfs/account/services/"; +} + +#define HMDFS_IOC_SET_SHARE_PATH _IOW(HMDFS_IOC, 1, struct HmdfsShareControl) + +struct HmdfsShareControl { + int fd; + char deviceId[HMDFS_CID_SIZE]; +}; + +static std::string GetProcessName() +{ + char pthreadName[PATH_MAX]; + int ret = pthread_getname_np(pthread_self(), pthreadName, sizeof(pthreadName)); + if (ret != 0) { + LOGE("RemoteFileShare::GetProcessName, pthread_getname_np failed with %{public}d", errno); + return ""; + } + std::string pthreadNameStr = pthreadName; + LOGI("RemoteFileShare::GetProcessName, thread name is %{public}s", pthreadNameStr.c_str()); + return pthreadNameStr; +} + +static std::string GetFileName(const int &fd) +{ + char buf[PATH_MAX] = {'\0'}; + char filePath[PATH_MAX] = {'\0'}; + + int ret = snprintf_s(buf, sizeof(buf), sizeof(buf), "/proc/self/fd/%d", fd); + if (ret < 0) { + LOGE("RemoteFileShare::GetFileName, snprintf failed with %{public}d", errno); + return ""; + } + + ret = readlink(buf, filePath, PATH_MAX - 1); + if (ret < 0) { + LOGE("RemoteFileShare::GetFileName, readlink failed with %{public}d", errno); + return ""; + } + + std::string fileName = filePath; + int firstSlash = fileName.rfind("/"); + if (firstSlash == fileName.npos) { + LOGE("RemoteFileShare::GetFileName, get error path with %{public}s", fileName.c_str()); + return ""; + } + fileName = fileName.substr(firstSlash + 1, fileName.size() - firstSlash); + return fileName; +} + +static int CreateShareDir(const std::string &path) +{ + if (access(path.c_str(), F_OK) != 0) { + int ret = mkdir(path.c_str(), S_IRWXU); + if (ret != 0) { + LOGE("RemoteFileShare::CreateShareDir, make dir failed with %{public}d", errno); + return errno; + } + } + return 0; +} + +static std::string GetSharePath(const int &userId, const std::string &packageName) +{ + return SHAER_PATH_HEAD + std::to_string(userId) + SHAER_PATH_MID + packageName; +} + +static std::string GetLowerSharePath(const int &userId, const std::string &packageName) +{ + return LOWER_SHARE_PATH_HEAD + std::to_string(userId) + LOWER_SHARE_PATH_MID + packageName; +} + +static bool DeleteShareDir(const std::string PACKAGE_PATH, const std::string SHARE_PATH_LOWER) +{ + bool result = true; + if (access(SHARE_PATH_LOWER.c_str(), F_OK) == 0) { + int ret = rmdir(SHARE_PATH_LOWER.c_str()); + if (ret != 0) { + LOGE("RemoteFileShare::DeleteShareDir, delete dir failed with %{public}d", errno); + result = false; + } + LOGI("RemoteFileShare::DeleteShareDir, delete %{public}s path successfully", SHARE_PATH_LOWER.c_str()); + } + if (access(PACKAGE_PATH.c_str(), F_OK) == 0) { + int ret = rmdir(PACKAGE_PATH.c_str()); + if (ret != 0) { + LOGE("RemoteFileShare::DeleteShareDir, delete dir failed with %{public}d", errno); + result = false; + } + LOGI("RemoteFileShare::DeleteShareDir, delete %{public}s path successfully", PACKAGE_PATH.c_str()); + } + return result; +} + +static int CreateShareFile(struct HmdfsShareControl &shareControl, const char* file, + const std::string &deviceId) +{ + int32_t dirFd = open(file, O_RDONLY); + if (dirFd < 0) { + LOGE("RemoteFileShare::CreateShareFile, open share path failed with %{public}d", errno); + return errno; + } + + if (memcpy_s(shareControl.deviceId, HMDFS_CID_SIZE, deviceId.c_str(), deviceId.size()) != 0) { + LOGE("RemoteFileShare::CreateShareFile, memcpy_s failed with %{public}d", errno); + close(dirFd); + return errno; + } + + if (ioctl(dirFd, HMDFS_IOC_SET_SHARE_PATH, &shareControl) < 0) { + LOGE("RemoteFileShare::CreateShareFile, ioctl failed with %{public}d", errno); + close(dirFd); + return errno; + } + close(dirFd); + return 0; +} + +int RemoteFileShare::CreateSharePath(const int &fd, std::string &sharePath, + const int &userId, const std::string &deviceId) +{ + struct HmdfsShareControl shareControl; + shareControl.fd = fd; + + const std::string processName = GetProcessName(); + if (processName == "") { + LOGE("RemoteFileShare::CreateSharePath, GetProcessName failed with %{public}d", errno); + return errno; + } + + const std::string PACKAGE_PATH = GetLowerSharePath(userId, processName); + const std::string SHARE_PATH_LOWER = PACKAGE_PATH + "/.share"; + if (CreateShareDir(PACKAGE_PATH) != 0) + return errno; + if (CreateShareDir(SHARE_PATH_LOWER) != 0) { + DeleteShareDir(PACKAGE_PATH, SHARE_PATH_LOWER); + return errno; + } + + const std::string SHARE_PATH = GetSharePath(userId, processName) + "/.share"; + char realPath[PATH_MAX] = {'\0'}; + if (!realpath(SHARE_PATH.c_str(), realPath)) { + LOGE("RemoteFileShare::CreateSharePath, realpath failed with %{public}d", errno); + DeleteShareDir(PACKAGE_PATH, SHARE_PATH_LOWER); + return errno; + } + + if (CreateShareFile(shareControl, realPath, deviceId) != 0) { + LOGE("RemoteFileShare::CreateSharePath, create share file failed with %{public}d", errno); + DeleteShareDir(PACKAGE_PATH, SHARE_PATH_LOWER); + return errno; + } + + std::string file_name = GetFileName(shareControl.fd); + if (file_name == "") { + LOGE("RemoteFileShare::CreateSharePath, get error file name"); + DeleteShareDir(PACKAGE_PATH, SHARE_PATH_LOWER); + return EBADF; + } + sharePath = SHARE_PATH + "/" + file_name; + LOGI("RemoteFileShare::CreateSharePath, create %{public}s successfully", sharePath.c_str()); + return 0; +} +} // namespace ModuleRemoteFileShare +} // namespace AppFileService +} // namespace OHOS -- Gitee