diff --git a/src/client/ring_signal.cpp b/src/client/ring_signal.cpp index 0ff28dbd859750c23652c5691e9b0d2eea7ffcca..77f5b65ac7d58046340d57f28fac0cb895ace666 100644 --- a/src/client/ring_signal.cpp +++ b/src/client/ring_signal.cpp @@ -71,8 +71,11 @@ getSignalHandlers() exported_callback<DRing::ConfigurationSignal::Error>(), #ifdef __ANDROID__ exported_callback<DRing::ConfigurationSignal::GetHardwareAudioFormat>(), +#endif +#if defined(__ANDROID__) || defined(RING_UWP) exported_callback<DRing::ConfigurationSignal::GetAppDataPath>(), #endif + /* Debug */ exported_callback<DRing::DebugSignal::MessageSend>(), diff --git a/src/dring/configurationmanager_interface.h b/src/dring/configurationmanager_interface.h index 9b81118a01c2cdc6ae1a69ce414f082e9480ed1d..ad396ca40fe550aa9ff4bf5b0d5af3dd43ce988d 100644 --- a/src/dring/configurationmanager_interface.h +++ b/src/dring/configurationmanager_interface.h @@ -252,15 +252,17 @@ struct ConfigurationSignal { constexpr static const char* name = "MediaParametersChanged"; using cb_type = void(const std::string& /*accountId*/); }; -#ifdef __ANDROID__ /** - * These are special getters for Android so the daemon can retreive - * some informations only accessible through Java APIs + * These are special getters for Android and UWP, so the daemon can retreive + * information only accessible through their respective platform APIs */ +#ifdef __ANDROID__ struct GetHardwareAudioFormat { constexpr static const char* name = "GetHardwareAudioFormat"; using cb_type = void(std::vector<int32_t>* /* params_ret */); }; +#endif +#if defined(__ANDROID__) || defined(RING_UWP) struct GetAppDataPath { constexpr static const char* name = "GetAppDataPath"; using cb_type = void(const std::string& name, std::vector<std::string>* /* path_ret */); diff --git a/src/fileutils.cpp b/src/fileutils.cpp index 037d6c37c331708a25ced5b03c4db609d50c3a0f..66422f63e9414a0a78f04973d42156700357ce5c 100644 --- a/src/fileutils.cpp +++ b/src/fileutils.cpp @@ -28,6 +28,11 @@ #include "fileutils.h" #include "compiler_intrinsics.h" +#ifdef RING_UWP +#include <io.h> // for access and close +#include "ring_signal.h" +#endif + #ifdef __APPLE__ #include <TargetConditionals.h> #endif @@ -75,7 +80,7 @@ #include <cstring> #include <cerrno> #include <cstddef> -#include <ciso646> // fix windows compiler bug +#include <ciso646> namespace ring { namespace fileutils { @@ -170,7 +175,7 @@ create_pidfile() std::string expand_path(const std::string &path) { -#if defined __ANDROID__ || defined WIN32 || TARGET_OS_IPHONE +#if defined __ANDROID__ || defined RING_UWP || defined WIN32 || TARGET_OS_IPHONE RING_ERR("Path expansion not implemented, returning original"); return path; #else @@ -234,7 +239,7 @@ bool isSymLink(const std::string& path) struct stat s; if (lstat(path.c_str(), &s) == 0) return S_ISLNK(s.st_mode); -#else +#elif !defined(RING_UWP) DWORD attr = GetFileAttributes(ring::to_wstring(path).c_str()); if (attr & FILE_ATTRIBUTE_REPARSE_POINT) return true; @@ -251,8 +256,19 @@ writeTime(const std::string& path) if (ret) throw std::runtime_error("Can't check write time for: " + path); return std::chrono::system_clock::from_time_t(s.st_mtime); +#else +#if RING_UWP + _CREATEFILE2_EXTENDED_PARAMETERS ext_params = { 0 }; + ext_params.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS); + ext_params.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; + ext_params.dwFileFlags = FILE_FLAG_NO_BUFFERING; + ext_params.dwSecurityQosFlags = SECURITY_ANONYMOUS; + ext_params.lpSecurityAttributes = nullptr; + ext_params.hTemplateFile = nullptr; + HANDLE h = CreateFile2(ring::to_wstring(path).c_str(), GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, &ext_params); #else HANDLE h = CreateFile(ring::to_wstring(path).c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); +#endif if (h == INVALID_HANDLE_VALUE) throw std::runtime_error("Can't open: " + path); FILETIME lastWriteTime; @@ -373,28 +389,40 @@ FileHandle::~FileHandle() } } -#ifdef __ANDROID__ +#if defined(__ANDROID__) || defined(RING_UWP) static std::string files_path; static std::string cache_path; static std::string config_path; #else static char *program_dir = NULL; -#ifndef RING_UWP void set_program_dir(char *program_path) { program_dir = dirname(program_path); } #endif -#endif std::string get_cache_dir() { +#ifdef RING_UWP + std::vector<std::string> paths; + emitSignal<DRing::ConfigurationSignal::GetAppDataPath>("", &paths); + if (not paths.empty()) + cache_path = paths[0] + DIR_SEPARATOR_STR + std::string(".cache"); + + if (fileutils::recursive_mkdir(cache_path.data(), 0700) != true) { + // If directory creation failed + if (errno != EEXIST) + RING_DBG("Cannot create directory: %s!", cache_path.c_str()); + } + return cache_path; +#else const std::string cache_home(XDG_CACHE_HOME); if (not cache_home.empty()) { return cache_home; } else { +#endif #ifdef __ANDROID__ std::vector<std::string> paths; emitSignal<DRing::ConfigurationSignal::GetAppDataPath>("cache", &paths); @@ -409,7 +437,9 @@ get_cache_dir() return get_home_dir() + DIR_SEPARATOR_STR + ".cache" + DIR_SEPARATOR_STR + PACKAGE; #endif +#ifndef RING_UWP } +#endif } std::string @@ -421,6 +451,12 @@ get_home_dir() if (not paths.empty()) files_path = paths[0]; return files_path; +#elif defined RING_UWP + std::vector<std::string> paths; + emitSignal<DRing::ConfigurationSignal::GetAppDataPath>("", &paths); + if (not paths.empty()) + files_path = paths[0]; + return files_path; #elif defined _WIN32 WCHAR path[MAX_PATH]; if (SUCCEEDED(SHGetFolderPathW(nullptr, CSIDL_PROFILE, nullptr, 0, path))) { @@ -463,6 +499,18 @@ get_data_dir() return get_home_dir() + DIR_SEPARATOR_STR + "Library" + DIR_SEPARATOR_STR + "Application Support" + DIR_SEPARATOR_STR + PACKAGE; +#elif defined (RING_UWP) + std::vector<std::string> paths; + emitSignal<DRing::ConfigurationSignal::GetAppDataPath>("", &paths); + if (not paths.empty()) + files_path = paths[0] + DIR_SEPARATOR_STR + std::string(".data"); + + if (fileutils::recursive_mkdir(files_path.data(), 0700) != true) { + // If directory creation failed + if (errno != EEXIST) + RING_DBG("Cannot create directory: %s!", files_path.c_str()); + } + return files_path; #else const std::string data_home(XDG_DATA_HOME); if (not data_home.empty()) @@ -483,15 +531,26 @@ get_config_dir() if (not paths.empty()) config_path = paths[0]; return config_path; -#else -#ifdef __APPLE__ + +#elif defined( __APPLE__ ) std::string configdir = fileutils::get_home_dir() + DIR_SEPARATOR_STR + "Library" + DIR_SEPARATOR_STR + "Application Support" + DIR_SEPARATOR_STR + PACKAGE; +#elif defined(RING_UWP) + std::vector<std::string> paths; + emitSignal<DRing::ConfigurationSignal::GetAppDataPath>("", &paths); + if (not paths.empty()) + config_path = paths[0] + DIR_SEPARATOR_STR + std::string(".config"); + + if (fileutils::recursive_mkdir(config_path.data(), 0700) != true) { + // If directory creation failed + if (errno != EEXIST) + RING_DBG("Cannot create directory: %s!", config_path.c_str()); + } + return config_path; #else std::string configdir = fileutils::get_home_dir() + DIR_SEPARATOR_STR + ".config" + DIR_SEPARATOR_STR + PACKAGE; -#endif const std::string xdg_env(XDG_CONFIG_HOME); if (not xdg_env.empty())