winfsp unit tests and fixes

This commit is contained in:
Scott E. Graves 2024-10-30 14:56:50 -05:00
parent 7d74d192f9
commit 07d0eb0616
12 changed files with 227 additions and 104 deletions

View File

@ -23,6 +23,7 @@ cppflags
cpphttplib
cpptrace
cppvsdbg
create_notraverse
crypto_aead_xchacha20poly1305_ietf_npubbytes
cstdint
cxxflags

View File

@ -361,7 +361,7 @@ auto remote_winfsp_drive::ReadDirectory(PVOID /*file_node*/, PVOID file_desc,
// if (not utils::path::is_ads_file_path(item_path)) {
union {
UINT8 B[FIELD_OFFSET(FSP_FSCTL_DIR_INFO, FileNameBuf) +
((MAX_PATH + 1) * sizeof(WCHAR))];
((repertory::max_path_length + 1U) * sizeof(WCHAR))];
FSP_FSCTL_DIR_INFO D;
} directory_info_buffer;
@ -369,7 +369,8 @@ auto remote_winfsp_drive::ReadDirectory(PVOID /*file_node*/, PVOID file_desc,
::ZeroMemory(directory_info, sizeof(*directory_info));
directory_info->Size = static_cast<UINT16>(
FIELD_OFFSET(FSP_FSCTL_DIR_INFO, FileNameBuf) +
(std::min(static_cast<size_t>(MAX_PATH), display_name.size()) *
(std::min(static_cast<size_t>(repertory::max_path_length),
display_name.size()) *
sizeof(WCHAR)));
if (not item["meta"].empty() ||
@ -377,8 +378,8 @@ auto remote_winfsp_drive::ReadDirectory(PVOID /*file_node*/, PVOID file_desc,
populate_file_info(item, directory_info->FileInfo);
}
if (ret == STATUS_SUCCESS) {
::wcscpy_s(&directory_info->FileNameBuf[0], MAX_PATH,
&display_name[0]);
::wcscpy_s(&directory_info->FileNameBuf[0],
repertory::max_path_length, &display_name[0]);
FspFileSystemFillDirectoryBuffer(directory_buffer, directory_info,
&ret);

View File

@ -568,7 +568,7 @@ auto winfsp_drive::Init(PVOID host) -> NTSTATUS {
file_system_host->SetCasePreservedNames(TRUE);
file_system_host->SetNamedStreams(FALSE);
file_system_host->SetUnicodeOnDisk(TRUE);
// file_system_host->SetMaxComponentLength(4096U);
file_system_host->SetMaxComponentLength(255U);
file_system_host->SetPersistentAcls(FALSE);
file_system_host->SetPostCleanupWhenModifiedOnly(TRUE);
file_system_host->SetPassQueryDirectoryPattern(FALSE);
@ -926,7 +926,7 @@ auto winfsp_drive::ReadDirectory(PVOID /*file_node*/, PVOID file_desc,
utils::path::strip_to_file_name(dir_item.api_path));
union {
UINT8 B[FIELD_OFFSET(FSP_FSCTL_DIR_INFO, FileNameBuf) +
((MAX_PATH + 1) * sizeof(WCHAR))];
((repertory::max_path_length + 1U) * sizeof(WCHAR))];
FSP_FSCTL_DIR_INFO D;
} directory_info_buffer;
@ -934,14 +934,14 @@ auto winfsp_drive::ReadDirectory(PVOID /*file_node*/, PVOID file_desc,
::ZeroMemory(directory_info, sizeof(*directory_info));
directory_info->Size = static_cast<UINT16>(
FIELD_OFFSET(FSP_FSCTL_DIR_INFO, FileNameBuf) +
(std::min(static_cast<size_t>(MAX_PATH),
(std::min(static_cast<size_t>(repertory::max_path_length),
display_name.size()) *
sizeof(WCHAR)));
populate_file_info(dir_item.size, dir_item.meta,
directory_info->FileInfo);
::wcscpy_s(&directory_info->FileNameBuf[0U], MAX_PATH,
display_name.data());
::wcscpy_s(&directory_info->FileNameBuf[0U],
repertory::max_path_length, display_name.data());
FspFileSystemFillDirectoryBuffer(
directory_buffer, directory_info, &status_result);

View File

@ -28,6 +28,14 @@
//
#include "fixtures/winfsp_fixture.hpp"
// TODO revisit create_related
// TODO revisit create_allocation
// TODO revisit create_sd
// TODO revisit create_notraverse
// TODO revisit create_backup
// TODO revisit create_restore
// TODO revisit create_share
namespace repertory {
TYPED_TEST_CASE(winfsp_test, winfsp_provider_types);

View File

@ -0,0 +1,75 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#if defined(_WIN32)
//
// Implemented test cases based on WinFsp tests:
// https://github.com/winfsp/winfsp/blob/v2.0/tst/winfsp-tests
//
#include "fixtures/winfsp_fixture.hpp"
namespace repertory {
TYPED_TEST_CASE(winfsp_test, winfsp_provider_types);
TYPED_TEST(winfsp_test, cr8_nl_can_create_file_of_max_component_length) {
DWORD max_length{};
EXPECT_TRUE(::GetVolumeInformationA(this->mount_location.c_str(), nullptr, 0,
nullptr, &max_length, nullptr, nullptr,
0));
EXPECT_EQ(255U, max_length);
auto file_path = utils::path::combine(this->mount_location,
{
std::string(max_length - 1U, 'a'),
});
auto handle =
::CreateFileA(file_path.c_str(), GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0);
EXPECT_NE(INVALID_HANDLE_VALUE, handle);
EXPECT_TRUE(::CloseHandle(handle));
}
TYPED_TEST(winfsp_test,
cr8_nl_can_not_create_file_greater_than_max_component_length) {
DWORD max_length{};
EXPECT_TRUE(::GetVolumeInformationA(this->mount_location.c_str(), nullptr, 0,
nullptr, &max_length, nullptr, nullptr,
0));
EXPECT_EQ(255U, max_length);
auto file_path = utils::path::combine(this->mount_location,
{
std::string(max_length, 'a'),
});
auto handle =
::CreateFileA(file_path.c_str(), GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0);
EXPECT_EQ(INVALID_HANDLE_VALUE, handle);
EXPECT_EQ(ERROR_INVALID_NAME, ::GetLastError());
}
} // namespace repertory
#endif // defined(_WIN32)

View File

@ -0,0 +1,40 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#if defined(_WIN32)
//
// Implemented test cases based on WinFsp tests:
// https://github.com/winfsp/winfsp/blob/v2.0/tst/winfsp-tests
//
#include "fixtures/winfsp_fixture.hpp"
namespace repertory {
TYPED_TEST_CASE(winfsp_test, winfsp_provider_types);
TYPED_TEST(winfsp_test, can_set_current_directory_to_mount_location) {
EXPECT_TRUE(::SetCurrentDirectoryA(this->mount_location.c_str()));
EXPECT_TRUE(::SetCurrentDirectoryA(this->current_directory.string().c_str()));
}
} // namespace repertory
#endif // defined(_WIN32)

View File

@ -419,12 +419,7 @@ using unique_mutex_lock = std::unique_lock<std::mutex>;
using unique_recur_mutex_lock = std::unique_lock<std::recursive_mutex>;
#if defined(_WIN32)
#if defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
inline constexpr const auto max_path_length = std::size_t{32767U};
#else // !defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
inline constexpr const auto max_path_length = std::size_t{MAX_PATH};
#endif // defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
using native_handle = HANDLE;
#else // !defined(_WIN32)
inline constexpr const auto max_path_length = std::size_t{PATH_MAX};

View File

@ -53,50 +53,50 @@ inline constexpr const std::wstring_view not_directory_seperator_w{backslash_w};
#endif // defined(_WIN32)
template <typename char_t>
[[nodiscard]] inline constexpr auto
get_backslash() -> std::basic_string_view<char_t>;
[[nodiscard]] inline constexpr auto get_backslash()
-> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_backslash<char>() -> std::basic_string_view<char> {
[[nodiscard]] inline constexpr auto get_backslash<char>()
-> std::basic_string_view<char> {
return backslash;
}
template <>
[[nodiscard]] inline constexpr auto
get_backslash<wchar_t>() -> std::basic_string_view<wchar_t> {
[[nodiscard]] inline constexpr auto get_backslash<wchar_t>()
-> std::basic_string_view<wchar_t> {
return backslash_w;
}
template <typename char_t>
[[nodiscard]] inline constexpr auto
get_directory_seperator() -> std::basic_string_view<char_t>;
[[nodiscard]] inline constexpr auto get_directory_seperator()
-> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_directory_seperator<char>() -> std::basic_string_view<char> {
[[nodiscard]] inline constexpr auto get_directory_seperator<char>()
-> std::basic_string_view<char> {
return directory_seperator;
}
template <>
[[nodiscard]] inline constexpr auto
get_directory_seperator<wchar_t>() -> std::basic_string_view<wchar_t> {
[[nodiscard]] inline constexpr auto get_directory_seperator<wchar_t>()
-> std::basic_string_view<wchar_t> {
return directory_seperator_w;
}
template <typename char_t>
[[nodiscard]] inline constexpr auto
get_not_directory_seperator() -> std::basic_string_view<char_t>;
[[nodiscard]] inline constexpr auto get_not_directory_seperator()
-> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_not_directory_seperator<char>() -> std::basic_string_view<char> {
[[nodiscard]] inline constexpr auto get_not_directory_seperator<char>()
-> std::basic_string_view<char> {
return not_directory_seperator;
}
template <>
[[nodiscard]] inline constexpr auto
get_not_directory_seperator<wchar_t>() -> std::basic_string_view<wchar_t> {
[[nodiscard]] inline constexpr auto get_not_directory_seperator<wchar_t>()
-> std::basic_string_view<wchar_t> {
return not_directory_seperator_w;
}
@ -104,95 +104,95 @@ template <typename char_t>
[[nodiscard]] inline constexpr auto get_dot() -> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_dot<char>() -> std::basic_string_view<char> {
[[nodiscard]] inline constexpr auto get_dot<char>()
-> std::basic_string_view<char> {
return dot;
}
template <>
[[nodiscard]] inline constexpr auto
get_dot<wchar_t>() -> std::basic_string_view<wchar_t> {
[[nodiscard]] inline constexpr auto get_dot<wchar_t>()
-> std::basic_string_view<wchar_t> {
return dot_w;
}
template <typename char_t>
[[nodiscard]] inline constexpr auto
get_dot_backslash() -> std::basic_string_view<char_t>;
[[nodiscard]] inline constexpr auto get_dot_backslash()
-> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_dot_backslash<char>() -> std::basic_string_view<char> {
[[nodiscard]] inline constexpr auto get_dot_backslash<char>()
-> std::basic_string_view<char> {
return dot_backslash;
}
template <>
[[nodiscard]] inline constexpr auto
get_dot_backslash<wchar_t>() -> std::basic_string_view<wchar_t> {
[[nodiscard]] inline constexpr auto get_dot_backslash<wchar_t>()
-> std::basic_string_view<wchar_t> {
return dot_backslash_w;
}
template <typename char_t>
[[nodiscard]] inline constexpr auto
get_dot_slash() -> std::basic_string_view<char_t>;
[[nodiscard]] inline constexpr auto get_dot_slash()
-> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_dot_slash<char>() -> std::basic_string_view<char> {
[[nodiscard]] inline constexpr auto get_dot_slash<char>()
-> std::basic_string_view<char> {
return dot_slash;
}
template <>
[[nodiscard]] inline constexpr auto
get_dot_slash<wchar_t>() -> std::basic_string_view<wchar_t> {
[[nodiscard]] inline constexpr auto get_dot_slash<wchar_t>()
-> std::basic_string_view<wchar_t> {
return dot_slash_w;
}
template <typename char_t>
[[nodiscard]] inline constexpr auto
get_long_notation() -> std::basic_string_view<char_t>;
[[nodiscard]] inline constexpr auto get_long_notation()
-> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_long_notation<char>() -> std::basic_string_view<char> {
[[nodiscard]] inline constexpr auto get_long_notation<char>()
-> std::basic_string_view<char> {
return long_notation;
}
template <>
[[nodiscard]] inline constexpr auto
get_long_notation<wchar_t>() -> std::basic_string_view<wchar_t> {
[[nodiscard]] inline constexpr auto get_long_notation<wchar_t>()
-> std::basic_string_view<wchar_t> {
return long_notation_w;
}
template <typename char_t>
[[nodiscard]] inline constexpr auto
get_slash() -> std::basic_string_view<char_t>;
[[nodiscard]] inline constexpr auto get_slash()
-> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_slash<char>() -> std::basic_string_view<char> {
[[nodiscard]] inline constexpr auto get_slash<char>()
-> std::basic_string_view<char> {
return slash;
}
template <>
[[nodiscard]] inline constexpr auto
get_slash<wchar_t>() -> std::basic_string_view<wchar_t> {
[[nodiscard]] inline constexpr auto get_slash<wchar_t>()
-> std::basic_string_view<wchar_t> {
return slash_w;
}
#if defined(_WIN32)
template <typename char_t>
[[nodiscard]] inline constexpr auto
get_unc_notation() -> std::basic_string_view<char_t>;
[[nodiscard]] inline constexpr auto get_unc_notation()
-> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_unc_notation<char>() -> std::basic_string_view<char> {
[[nodiscard]] inline constexpr auto get_unc_notation<char>()
-> std::basic_string_view<char> {
return unc_notation;
}
template <>
[[nodiscard]] inline constexpr auto
get_unc_notation<wchar_t>() -> std::basic_string_view<wchar_t> {
[[nodiscard]] inline constexpr auto get_unc_notation<wchar_t>()
-> std::basic_string_view<wchar_t> {
return unc_notation_w;
}
#endif // defined(_WIN32)
@ -204,13 +204,13 @@ template <typename string_t>
[[nodiscard]] auto absolute(std::wstring_view path) -> std::wstring;
[[nodiscard]] inline auto
combine(std::string_view path,
const std::vector<std::string_view> &paths) -> std::string;
[[nodiscard]] inline auto combine(std::string_view path,
const std::vector<std::string_view> &paths)
-> std::string;
[[nodiscard]] inline auto
combine(std::wstring_view path,
const std::vector<std::wstring_view> &paths) -> std::wstring;
[[nodiscard]] inline auto combine(std::wstring_view path,
const std::vector<std::wstring_view> &paths)
-> std::wstring;
[[nodiscard]] auto contains_trash_directory(std::string_view path) -> bool;
@ -242,28 +242,28 @@ format_path(string_t &path,
std::basic_string_view<typename string_t::value_type> not_sep)
-> string_t &;
[[nodiscard]] inline auto
get_parent_api_path(std::string_view path) -> std::string;
[[nodiscard]] inline auto get_parent_api_path(std::string_view path)
-> std::string;
[[nodiscard]] inline auto
get_parent_api_path(std::wstring_view path) -> std::wstring;
[[nodiscard]] inline auto get_parent_api_path(std::wstring_view path)
-> std::wstring;
[[nodiscard]] auto get_parent_path(std::string_view path) -> std::string;
[[nodiscard]] auto get_parent_path(std::wstring_view path) -> std::wstring;
[[nodiscard]] inline auto
get_parts(std::string_view path) -> std::vector<std::string>;
[[nodiscard]] inline auto get_parts(std::string_view path)
-> std::vector<std::string>;
[[nodiscard]] inline auto
get_parts_w(std::wstring_view path) -> std::vector<std::wstring>;
[[nodiscard]] inline auto get_parts_w(std::wstring_view path)
-> std::vector<std::wstring>;
[[nodiscard]] auto get_relative_path(std::string_view path,
std::string_view root_path) -> std::string;
[[nodiscard]] auto
get_relative_path(std::wstring_view path,
std::wstring_view root_path) -> std::wstring;
[[nodiscard]] auto get_relative_path(std::wstring_view path,
std::wstring_view root_path)
-> std::wstring;
[[nodiscard]] auto make_file_uri(std::string_view path) -> std::string;
@ -301,15 +301,16 @@ inline auto combine(std::string_view path,
return combine_t<std::string>(path, paths);
}
inline auto
combine(std::wstring_view path,
const std::vector<std::wstring_view> &paths) -> std::wstring {
inline auto combine(std::wstring_view path,
const std::vector<std::wstring_view> &paths)
-> std::wstring {
return combine_t<std::wstring>(path, paths);
}
template <typename string_t>
[[nodiscard]] inline auto create_api_path_t(
std::basic_string_view<typename string_t::value_type> path) -> string_t {
[[nodiscard]] inline auto
create_api_path_t(std::basic_string_view<typename string_t::value_type> path)
-> string_t {
auto backslash_t = get_backslash<typename string_t::value_type>();
auto dot_backslash_t = get_dot_backslash<typename string_t::value_type>();
auto dot_slash_t = get_dot_slash<typename string_t::value_type>();
@ -357,8 +358,9 @@ inline auto create_api_path(std::wstring_view path) -> std::wstring {
}
template <typename string_t>
[[nodiscard]] inline auto finalize_t(
std::basic_string_view<typename string_t::value_type> path) -> string_t {
[[nodiscard]] inline auto
finalize_t(std::basic_string_view<typename string_t::value_type> path)
-> string_t {
string_t dir_sep_t{get_directory_seperator<typename string_t::value_type>()};
string_t fmt_path{path};
if (fmt_path.empty()) {
@ -463,7 +465,7 @@ template <>
[[nodiscard]] inline auto get_current_path<std::string>() -> std::string {
#if defined(_WIN32)
std::string path;
path.resize(repertory::max_path_length + 1);
path.resize(repertory::max_path_length + 1U);
::GetCurrentDirectoryA(static_cast<DWORD>(path.size()), path.data());
path = path.c_str();
return finalize(path);

View File

@ -37,7 +37,7 @@ auto change_to_process_directory() -> bool {
try {
#if defined(_WIN32)
std::string file_name;
file_name.resize(MAX_PATH + 1U);
file_name.resize(repertory::max_path_length + 1U);
::GetModuleFileNameA(nullptr, file_name.data(),
static_cast<DWORD>(file_name.size() - 1U));

View File

@ -33,7 +33,7 @@ namespace {
file_size = 0U;
#if defined(_WIN32)
struct _stat64 st {};
struct _stat64 st{};
auto res = _stat64(std::string{path}.c_str(), &st);
if (res != 0) {
return false;
@ -55,7 +55,7 @@ namespace {
return ((::PathFileExistsA(abs_path.c_str()) != 0) &&
(::PathIsDirectoryA(abs_path.c_str()) == 0));
#else // !defined(_WIN32)
struct stat64 st {};
struct stat64 st{};
return (stat64(abs_path.c_str(), &st) == 0 && not S_ISDIR(st.st_mode));
#endif // defined(_WIN32)
}
@ -70,12 +70,12 @@ namespace repertory::utils::file {
// std::string path;
//
// #if defined(_WIN32)
// path.resize(repertory::max_path_length + 1);
// path.resize(repertory::max_path_length + 1U);
// ::GetFinalPathNameByHandleA(handle, path.data(),
// static_cast<DWORD>(path.size()),
// FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
// #else // !defined(_WIN32)
// path.resize(repertory::max_path_length + 1);
// path.resize(repertory::max_path_length + 1U);
//
// #if defined(__APPLE__)
// fcntl(handle, F_GETPATH, source_path.data());
@ -155,8 +155,8 @@ auto file::open_file(std::string_view path, bool read_only) -> fs_file_t {
return new_file;
}
auto file::open_or_create_file(std::string_view path,
bool read_only) -> fs_file_t {
auto file::open_or_create_file(std::string_view path, bool read_only)
-> fs_file_t {
auto abs_path = utils::path::absolute(path);
if (not is_file(abs_path)) {
#if defined(_WIN32)

View File

@ -94,7 +94,7 @@ auto absolute(std::string_view path) -> std::string {
}
std::string temp;
temp.resize(repertory::max_path_length + 1);
temp.resize(repertory::max_path_length + 1U);
::GetFullPathNameA(abs_path.c_str(), static_cast<DWORD>(temp.size()),
temp.data(), nullptr);
#else // !defined(_WIN32)
@ -206,8 +206,8 @@ auto get_parent_path(std::wstring_view path) -> std::wstring {
get_parent_path(utils::string::to_utf8(path)));
}
auto get_relative_path(std::string_view path,
std::string_view root_path) -> std::string {
auto get_relative_path(std::string_view path, std::string_view root_path)
-> std::string {
auto abs_path = absolute(path);
auto abs_root_path =
absolute(root_path) + std::string{get_directory_seperator<char>()};
@ -223,8 +223,8 @@ auto get_relative_path(std::string_view path,
return abs_path;
}
auto get_relative_path(std::wstring_view path,
std::wstring_view root_path) -> std::wstring {
auto get_relative_path(std::wstring_view path, std::wstring_view root_path)
-> std::wstring {
return utils::string::from_utf8(get_relative_path(
utils::string::to_utf8(path), utils::string::to_utf8(root_path)));
}

View File

@ -116,7 +116,8 @@ auto run_process_elevated(std::vector<const char *> args) -> int {
std::string full_path;
full_path.resize(repertory::max_path_length + 1);
if (::GetModuleFileNameA(nullptr, full_path.data(), MAX_PATH)) {
if (::GetModuleFileNameA(nullptr, full_path.data(),
repertory::max_path_length)) {
SHELLEXECUTEINFOA sei{};
sei.fMask = SEE_MASK_NOCLOSEPROCESS;
sei.cbSize = sizeof(sei);