delete lock data when not active and mount location is empty
This commit is contained in:
parent
0e0eb9e729
commit
dc3bb025bf
@ -115,6 +115,7 @@ googletest
|
|||||||
gpath
|
gpath
|
||||||
gtest_version
|
gtest_version
|
||||||
has_setxattr
|
has_setxattr
|
||||||
|
hkey
|
||||||
httpapi
|
httpapi
|
||||||
httplib
|
httplib
|
||||||
icudata
|
icudata
|
||||||
|
@ -31,43 +31,42 @@ class i_provider;
|
|||||||
|
|
||||||
class lock_data final {
|
class lock_data final {
|
||||||
public:
|
public:
|
||||||
explicit lock_data(const provider_type &pt, std::string unique_id /*= ""*/)
|
explicit lock_data(const provider_type &prov, std::string unique_id /*= ""*/)
|
||||||
: pt_(pt),
|
: prov_(prov),
|
||||||
unique_id_(std::move(unique_id)),
|
unique_id_(std::move(unique_id)),
|
||||||
mutex_id_("repertory_" + app_config::get_provider_name(pt) + "_" +
|
mutex_id_("repertory_" + app_config::get_provider_name(prov) + "_" +
|
||||||
unique_id_),
|
unique_id_),
|
||||||
mutex_handle_(::CreateMutex(nullptr, FALSE, &mutex_id_[0u])) {}
|
mutex_handle_(::CreateMutex(nullptr, FALSE, mutex_id_.c_str())) {}
|
||||||
|
lock_data(const lock_data &) = delete;
|
||||||
lock_data()
|
lock_data(lock_data &&) = delete;
|
||||||
: pt_(provider_type::sia),
|
|
||||||
unique_id_(""),
|
|
||||||
mutex_id_(""),
|
|
||||||
mutex_handle_(INVALID_HANDLE_VALUE) {}
|
|
||||||
|
|
||||||
~lock_data() { release(); }
|
~lock_data() { release(); }
|
||||||
|
|
||||||
|
auto operator=(const lock_data &) -> lock_data & = delete;
|
||||||
|
auto operator=(lock_data &&) -> lock_data & = delete;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const provider_type pt_;
|
provider_type prov_;
|
||||||
const std::string unique_id_;
|
std::string unique_id_;
|
||||||
const std::string mutex_id_;
|
std::string mutex_id_;
|
||||||
HANDLE mutex_handle_;
|
HANDLE mutex_handle_{};
|
||||||
DWORD mutex_state_ = WAIT_FAILED;
|
DWORD mutex_state_{WAIT_FAILED};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] auto get_mount_state(const provider_type &pt,
|
[[nodiscard]] auto get_mount_state(provider_type prov, json &mount_state)
|
||||||
json &mount_state) -> bool;
|
-> bool;
|
||||||
|
|
||||||
[[nodiscard]] auto get_mount_state(json &mount_state) -> bool;
|
[[nodiscard]] static auto get_mount_state(json &mount_state) -> bool;
|
||||||
|
|
||||||
[[nodiscard]] auto get_unique_id() const -> std::string { return unique_id_; }
|
[[nodiscard]] auto get_unique_id() const -> std::string { return unique_id_; }
|
||||||
|
|
||||||
[[nodiscard]] auto grab_lock(std::uint8_t retry_count = 30) -> lock_result;
|
[[nodiscard]] auto grab_lock(std::uint8_t retry_count = 30U) -> lock_result;
|
||||||
|
|
||||||
void release();
|
void release();
|
||||||
|
|
||||||
[[nodiscard]] auto set_mount_state(bool active,
|
[[nodiscard]] auto set_mount_state(bool active,
|
||||||
const std::string &mount_location,
|
std::string_view mount_location,
|
||||||
const std::int64_t &pid) -> bool;
|
std::int64_t pid) -> bool;
|
||||||
};
|
};
|
||||||
|
|
||||||
[[nodiscard]] auto create_meta_attributes(
|
[[nodiscard]] auto create_meta_attributes(
|
||||||
|
@ -159,7 +159,11 @@ auto lock_data::set_mount_state(bool active, const std::string &mount_location,
|
|||||||
{"Location", active ? mount_location : ""},
|
{"Location", active ? mount_location : ""},
|
||||||
{"PID", active ? pid : -1},
|
{"PID", active ? pid : -1},
|
||||||
};
|
};
|
||||||
ret = utils::file::write_json_file(get_lock_data_file(), json_data);
|
if (mount_location.empty() && not active) {
|
||||||
|
ret = utils::file::file{get_lock_data_file()}.delete();
|
||||||
|
} else {
|
||||||
|
ret = utils::file::write_json_file(get_lock_data_file(), json_data);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
|
@ -26,131 +26,151 @@
|
|||||||
#include "events/event_system.hpp"
|
#include "events/event_system.hpp"
|
||||||
#include "events/types/filesystem_item_added.hpp"
|
#include "events/types/filesystem_item_added.hpp"
|
||||||
#include "providers/i_provider.hpp"
|
#include "providers/i_provider.hpp"
|
||||||
#include "utils/error_utils.hpp"
|
|
||||||
#include "utils/string.hpp"
|
#include "utils/string.hpp"
|
||||||
|
|
||||||
namespace repertory {
|
namespace repertory {
|
||||||
auto lock_data::get_mount_state(const provider_type & /*pt*/, json &mount_state)
|
auto lock_data::get_mount_state(provider_type /*pt*/, json &mount_state)
|
||||||
-> bool {
|
-> bool {
|
||||||
const auto ret = get_mount_state(mount_state);
|
if (not get_mount_state(mount_state)) {
|
||||||
if (ret) {
|
return false;
|
||||||
const auto mount_id =
|
|
||||||
app_config::get_provider_display_name(pt_) + unique_id_;
|
|
||||||
mount_state = mount_state[mount_id].empty()
|
|
||||||
? json({{"Active", false}, {"Location", ""}, {"PID", -1}})
|
|
||||||
: mount_state[mount_id];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
auto mount_id = app_config::get_provider_display_name(prov_) + unique_id_;
|
||||||
|
mount_state = mount_state[mount_id].empty() ? json({
|
||||||
|
{"Active", false},
|
||||||
|
{"Location", ""},
|
||||||
|
{"PID", -1},
|
||||||
|
})
|
||||||
|
: mount_state[mount_id];
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto lock_data::get_mount_state(json &mount_state) -> bool {
|
auto lock_data::get_mount_state(json &mount_state) -> bool {
|
||||||
HKEY key;
|
HKEY key{};
|
||||||
auto ret = !::RegCreateKeyEx(
|
auto ret = (::RegCreateKeyEx(
|
||||||
HKEY_CURRENT_USER,
|
HKEY_CURRENT_USER,
|
||||||
("SOFTWARE\\" + std::string{REPERTORY_DATA_NAME} + "\\Mounts").c_str(), 0,
|
("SOFTWARE\\" + std::string{REPERTORY_DATA_NAME} + "\\Mounts")
|
||||||
nullptr, 0, KEY_ALL_ACCESS, nullptr, &key, nullptr);
|
.c_str(),
|
||||||
if (ret) {
|
0, nullptr, 0, KEY_ALL_ACCESS, nullptr, &key,
|
||||||
DWORD i = 0u;
|
nullptr) == ERROR_SUCCESS);
|
||||||
DWORD data_size = 0u;
|
if (not ret) {
|
||||||
std::string name;
|
return ret;
|
||||||
name.resize(32767u);
|
|
||||||
auto name_size = static_cast<DWORD>(name.size());
|
|
||||||
while (ret &&
|
|
||||||
(::RegEnumValue(key, i, &name[0], &name_size, nullptr, nullptr,
|
|
||||||
nullptr, &data_size) == ERROR_SUCCESS)) {
|
|
||||||
std::string data;
|
|
||||||
data.resize(data_size);
|
|
||||||
name_size++;
|
|
||||||
if ((ret = !::RegEnumValue(key, i++, &name[0], &name_size, nullptr,
|
|
||||||
nullptr, reinterpret_cast<LPBYTE>(&data[0]),
|
|
||||||
&data_size))) {
|
|
||||||
mount_state[name.c_str()] = json::parse(data);
|
|
||||||
name_size = static_cast<DWORD>(name.size());
|
|
||||||
data_size = 0u;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
::RegCloseKey(key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string data;
|
||||||
|
DWORD data_size{};
|
||||||
|
DWORD idx{};
|
||||||
|
std::string name;
|
||||||
|
name.resize(32767U);
|
||||||
|
auto name_size{static_cast<DWORD>(name.size())};
|
||||||
|
while (ret &&
|
||||||
|
(::RegEnumValue(key, idx, name.data(), &name_size, nullptr, nullptr,
|
||||||
|
nullptr, &data_size) == ERROR_SUCCESS)) {
|
||||||
|
|
||||||
|
data.resize(data_size);
|
||||||
|
ret = (::RegEnumValue(key, idx, name.data(), &name_size, nullptr, nullptr,
|
||||||
|
reinterpret_cast<LPBYTE>(data.data()),
|
||||||
|
&data_size) == ERROR_SUCCESS);
|
||||||
|
if (ret) {
|
||||||
|
mount_state[name] = json::parse(data);
|
||||||
|
name_size = static_cast<DWORD>(name.size());
|
||||||
|
data_size = 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
++idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
::RegCloseKey(key);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto lock_data::grab_lock(std::uint8_t retry_count) -> lock_result {
|
auto lock_data::grab_lock(std::uint8_t retry_count) -> lock_result {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
|
||||||
|
|
||||||
auto ret = lock_result::success;
|
|
||||||
if (mutex_handle_ == INVALID_HANDLE_VALUE) {
|
if (mutex_handle_ == INVALID_HANDLE_VALUE) {
|
||||||
ret = lock_result::failure;
|
return lock_result::failure;
|
||||||
} else {
|
|
||||||
for (auto i = 0;
|
|
||||||
(i <= retry_count) && ((mutex_state_ = ::WaitForSingleObject(
|
|
||||||
mutex_handle_, 100)) == WAIT_TIMEOUT);
|
|
||||||
i++) {
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (mutex_state_) {
|
|
||||||
case WAIT_OBJECT_0:
|
|
||||||
ret = lock_result::success;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WAIT_TIMEOUT:
|
|
||||||
ret = lock_result::locked;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
ret = lock_result::failure;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
for (std::uint8_t idx = 0U;
|
||||||
|
(idx <= retry_count) && ((mutex_state_ = ::WaitForSingleObject(
|
||||||
|
mutex_handle_, 100)) == WAIT_TIMEOUT);
|
||||||
|
++idx) {
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (mutex_state_) {
|
||||||
|
case WAIT_OBJECT_0:
|
||||||
|
return lock_result::success;
|
||||||
|
|
||||||
|
case WAIT_TIMEOUT:
|
||||||
|
return lock_result::locked;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return lock_result::failure;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lock_data::release() {
|
void lock_data::release() {
|
||||||
if (mutex_handle_ != INVALID_HANDLE_VALUE) {
|
if (mutex_handle_ == INVALID_HANDLE_VALUE) {
|
||||||
if ((mutex_state_ == WAIT_OBJECT_0) || (mutex_state_ == WAIT_ABANDONED)) {
|
return;
|
||||||
::ReleaseMutex(mutex_handle_);
|
|
||||||
}
|
|
||||||
::CloseHandle(mutex_handle_);
|
|
||||||
mutex_handle_ = INVALID_HANDLE_VALUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((mutex_state_ == WAIT_OBJECT_0) || (mutex_state_ == WAIT_ABANDONED)) {
|
||||||
|
::ReleaseMutex(mutex_handle_);
|
||||||
|
}
|
||||||
|
|
||||||
|
::CloseHandle(mutex_handle_);
|
||||||
|
mutex_handle_ = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto lock_data::set_mount_state(bool active, const std::string &mount_location,
|
auto lock_data::set_mount_state(bool active, std::string_view mount_location,
|
||||||
const std::int64_t &pid) -> bool {
|
std::int64_t pid) -> bool {
|
||||||
auto ret = false;
|
if (mutex_handle_ == INVALID_HANDLE_VALUE) {
|
||||||
if (mutex_handle_ != INVALID_HANDLE_VALUE) {
|
return false;
|
||||||
const auto mount_id =
|
|
||||||
app_config::get_provider_display_name(pt_) + unique_id_;
|
|
||||||
json mount_state;
|
|
||||||
[[maybe_unused]] auto success = get_mount_state(mount_state);
|
|
||||||
if ((mount_state.find(mount_id) == mount_state.end()) ||
|
|
||||||
(mount_state[mount_id].find("Active") == mount_state[mount_id].end()) ||
|
|
||||||
(mount_state[mount_id]["Active"].get<bool>() != active) ||
|
|
||||||
(active && ((mount_state[mount_id].find("Location") ==
|
|
||||||
mount_state[mount_id].end()) ||
|
|
||||||
(mount_state[mount_id]["Location"].get<std::string>() !=
|
|
||||||
mount_location)))) {
|
|
||||||
HKEY key;
|
|
||||||
if ((ret = !::RegCreateKeyEx(
|
|
||||||
HKEY_CURRENT_USER,
|
|
||||||
("SOFTWARE\\" + std::string{REPERTORY_DATA_NAME} + "\\Mounts")
|
|
||||||
.c_str(),
|
|
||||||
0, nullptr, 0, KEY_ALL_ACCESS, nullptr, &key, nullptr))) {
|
|
||||||
const auto str = json({{"Active", active},
|
|
||||||
{"Location", active ? mount_location : ""},
|
|
||||||
{"PID", active ? pid : -1}})
|
|
||||||
.dump(0);
|
|
||||||
ret = !::RegSetValueEx(key, &mount_id[0], 0, REG_SZ,
|
|
||||||
reinterpret_cast<const BYTE *>(&str[0]),
|
|
||||||
static_cast<DWORD>(str.size()));
|
|
||||||
::RegCloseKey(key);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ret = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto mount_id{app_config::get_provider_display_name(prov_) + unique_id_};
|
||||||
|
|
||||||
|
json mount_state;
|
||||||
|
[[maybe_unused]] auto success{get_mount_state(mount_state)};
|
||||||
|
if (not((mount_state.find(mount_id) == mount_state.end()) ||
|
||||||
|
(mount_state[mount_id].find("Active") ==
|
||||||
|
mount_state[mount_id].end()) ||
|
||||||
|
(mount_state[mount_id]["Active"].get<bool>() != active) ||
|
||||||
|
(active && ((mount_state[mount_id].find("Location") ==
|
||||||
|
mount_state[mount_id].end()) ||
|
||||||
|
(mount_state[mount_id]["Location"].get<std::string>() !=
|
||||||
|
mount_location))))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
HKEY key{};
|
||||||
|
if (::RegCreateKeyEx(
|
||||||
|
HKEY_CURRENT_USER,
|
||||||
|
("SOFTWARE\\" + std::string{REPERTORY_DATA_NAME} + "\\Mounts")
|
||||||
|
.c_str(),
|
||||||
|
0, nullptr, 0, KEY_ALL_ACCESS, nullptr, &key,
|
||||||
|
nullptr) != ERROR_SUCCESS) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto data{
|
||||||
|
json({
|
||||||
|
{"Active", active},
|
||||||
|
{"Location", active ? mount_location : ""},
|
||||||
|
{"PID", active ? pid : -1},
|
||||||
|
})
|
||||||
|
.dump(),
|
||||||
|
};
|
||||||
|
|
||||||
|
auto ret{false};
|
||||||
|
if (mount_location.empty() && not active) {
|
||||||
|
ret = (::RegDeleteKey(key, mount_id.c_str()) == ERROR_SUCCESS);
|
||||||
|
} else {
|
||||||
|
ret = (::RegSetValueEx(key, mount_id.c_str(), 0, REG_SZ,
|
||||||
|
reinterpret_cast<const BYTE *>(data.c_str()),
|
||||||
|
static_cast<DWORD>(data.size())) == ERROR_SUCCESS);
|
||||||
|
}
|
||||||
|
::RegCloseKey(key);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user