Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/windirstat/llfio.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiall Douglas (s [underscore] sourceforge {at} nedprod [dot] com) <spamtrap@nedprod.com>2021-01-27 23:37:53 +0300
committerNiall Douglas (s [underscore] sourceforge {at} nedprod [dot] com) <spamtrap@nedprod.com>2021-01-27 23:37:53 +0300
commit48ee8bae656cb5d53f38feb462caa53e1128b76d (patch)
tree724b307ed58ccbf961308fab421f3f35f7041a95
parentdd31f911f631b268e10a94fb8a43cc04870200d6 (diff)
Add the beginnings of a to_win32_path(), though it's not finished yet.
-rw-r--r--include/llfio/v2.0/handle.hpp6
-rw-r--r--include/llfio/v2.0/path_view.hpp49
2 files changed, 54 insertions, 1 deletions
diff --git a/include/llfio/v2.0/handle.hpp b/include/llfio/v2.0/handle.hpp
index 727157bf..2511847b 100644
--- a/include/llfio/v2.0/handle.hpp
+++ b/include/llfio/v2.0/handle.hpp
@@ -296,6 +296,12 @@ public:
It is up to you to detect if `current_path()` is not working, and to change how you
call LLFIO appropriately.
+ On Windows, you will almost certainly get back a path of the form `\!!\Device\HarddiskVolume10\Users\ned\...`.
+ See `path_view` for what all the path prefix sequences mean, but to summarise the `\!!\`
+ prefix is LLFIO-only and will not be accepted by other Windows APIs. Pass LLFIO derived
+ paths through the function `to_win32_path()` to Win32-ise them. This function is also
+ available on Linux where it does nothing, so you can use it in portable code.
+
\warning This call is expensive, it always asks the kernel for the current path, and no
checking is done to ensure what the kernel returns is accurate or even sensible.
Be aware that despite these precautions, paths are unstable and **can change randomly at
diff --git a/include/llfio/v2.0/path_view.hpp b/include/llfio/v2.0/path_view.hpp
index f1a5497c..41589da3 100644
--- a/include/llfio/v2.0/path_view.hpp
+++ b/include/llfio/v2.0/path_view.hpp
@@ -1840,7 +1840,7 @@ public:
if(_npos == sep_idx)
{
// Sorry, this semantic is so broken that it's unwise to emulate!
-#if 0 // LLFIO_USING_EXPERIMENTAL_FILESYSTEM && defined(_MSC_VER)
+#if 0 // LLFIO_USING_EXPERIMENTAL_FILESYSTEM && defined(_MSC_VER)
return this->_invoke([&](const auto &v) {
// MSVC's Experimental Filesystem has some really, really weird semantics :(
return *this;
@@ -2437,6 +2437,53 @@ inline filesystem::path operator/(T a, path_view_component b)
}
+namespace detail
+{
+ inline filesystem::path to_win32_path(filesystem::path &&p, bool need_dos_path_form)
+ {
+#ifdef _WIN32
+ if(need_dos_path_form)
+ {
+ throw std::runtime_error("Not implemented yet");
+ }
+ auto &str = const_cast<filesystem::path::string_type &>(p.native());
+ if(str.size() >= 4 && str[0] == '\\' && str[1] == '!' && str[2] == '!' && str[3] == '\\')
+ {
+ /* Paths of form \!!\Device\... => \\.\ */
+ if(0 == str.compare(0, 11, L"\\!!\\Device\\"))
+ {
+ str[1] = '\\';
+ str[2] = '.';
+ memcpy(&str[4], &str[11], (str.size() - 7) * sizeof(wchar_t));
+ str.resize(str.size() - 7);
+ }
+ else
+ {
+ throw std::runtime_error("cannot convert path into Win32 path");
+ }
+ }
+#endif
+ return std::move(p);
+ }
+} // namespace detail
+
+/*! \brief Transforms the input path into a form suitable for Win32 APIs.
+Passes through unmodified on POSIX.
+
+\throws If the path cannot be turned into a valid Win32 path, an exception
+is thrown.
+*/
+inline filesystem::path to_win32_path(path_view p, bool need_dos_path_form = false)
+{
+ return detail::to_win32_path(p.path(), need_dos_path_form);
+}
+//! \overload
+inline filesystem::path to_win32_path(filesystem::path &&p, bool need_dos_path_form = false)
+{
+ return detail::to_win32_path(std::move(p), need_dos_path_form);
+}
+
+
#ifndef NDEBUG
static_assert(std::is_trivially_copyable<path_view>::value, "path_view is not a trivially copyable!");
#endif