diff options
author | Egor Tensin <Egor.Tensin@gmail.com> | 2020-10-16 18:13:24 +0300 |
---|---|---|
committer | Egor Tensin <Egor.Tensin@gmail.com> | 2020-10-16 21:20:11 +0300 |
commit | 182bff76382d59f44f0ac3c69beb55dacde75eb5 (patch) | |
tree | a1a90b748831594eeb14def8eef1c13c98ca5aa6 /src/path.cpp | |
parent | Process: add get_exit_code() (diff) | |
download | winapi-common-182bff76382d59f44f0ac3c69beb55dacde75eb5.tar.gz winapi-common-182bff76382d59f44f0ac3c69beb55dacde75eb5.zip |
add path.hpp: CanonicalPath class, etc.
Apparently, relative paths in the Win32 namespace (e.g. \\?\test.txt)
are not a thing.
Diffstat (limited to '')
-rw-r--r-- | src/path.cpp | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/src/path.cpp b/src/path.cpp new file mode 100644 index 0000000..2c2deda --- /dev/null +++ b/src/path.cpp @@ -0,0 +1,47 @@ +// Copyright (c) 2020 Egor Tensin <Egor.Tensin@gmail.com> +// This file is part of the "winapi-common" project. +// For details, see https://github.com/egor-tensin/winapi-common. +// Distributed under the MIT License. + +#include <winapi/error.hpp> +#include <winapi/path.hpp> +#include <winapi/utf8.hpp> + +#include <windows.h> + +#include <string> +#include <vector> + +namespace winapi { +namespace { + +std::wstring do_canonicalize(const std::wstring& path) { + std::vector<wchar_t> buffer; + buffer.resize(MAX_PATH); + + while (true) { + const auto nch = ::GetFullPathNameW(path.c_str(), buffer.size(), buffer.data(), NULL); + + if (nch == 0) { + throw error::windows(GetLastError(), "GetFullPathNameW"); + } + + if (nch < buffer.size()) { + return {buffer.data(), nch}; + } + + if (nch > buffer.size()) { + buffer.resize(2 * buffer.size()); + } + } +} + +} // namespace + +CanonicalPath::CanonicalPath(const std::string& path) : m_path(canonicalize(path)) {} + +std::string CanonicalPath::canonicalize(const std::string& path) { + return narrow(do_canonicalize(widen(path))); +} + +} // namespace winapi |