aboutsummaryrefslogtreecommitdiff
path: root/libs/usvfs/src/shared
diff options
context:
space:
mode:
Diffstat (limited to 'libs/usvfs/src/shared')
-rw-r--r--libs/usvfs/src/shared/CMakeLists.txt23
-rw-r--r--libs/usvfs/src/shared/addrtools.h64
-rw-r--r--libs/usvfs/src/shared/directory_tree.cpp47
-rw-r--r--libs/usvfs/src/shared/directory_tree.h650
-rw-r--r--libs/usvfs/src/shared/exceptionex.cpp82
-rw-r--r--libs/usvfs/src/shared/exceptionex.h99
-rw-r--r--libs/usvfs/src/shared/formatters.h158
-rw-r--r--libs/usvfs/src/shared/loghelpers.cpp96
-rw-r--r--libs/usvfs/src/shared/loghelpers.h123
-rw-r--r--libs/usvfs/src/shared/ntdll_declarations.cpp75
-rw-r--r--libs/usvfs/src/shared/ntdll_declarations.h612
-rw-r--r--libs/usvfs/src/shared/pch.cpp1
-rw-r--r--libs/usvfs/src/shared/pch.h87
-rw-r--r--libs/usvfs/src/shared/shared_memory.h53
-rw-r--r--libs/usvfs/src/shared/shmlogger.cpp205
-rw-r--r--libs/usvfs/src/shared/shmlogger.h105
-rw-r--r--libs/usvfs/src/shared/stringcast.cpp40
-rw-r--r--libs/usvfs/src/shared/stringcast.h170
-rw-r--r--libs/usvfs/src/shared/stringutils.cpp146
-rw-r--r--libs/usvfs/src/shared/stringutils.h57
-rw-r--r--libs/usvfs/src/shared/tree_container.h630
-rw-r--r--libs/usvfs/src/shared/unicodestring.cpp77
-rw-r--r--libs/usvfs/src/shared/unicodestring.h110
-rw-r--r--libs/usvfs/src/shared/wildcard.cpp194
-rw-r--r--libs/usvfs/src/shared/wildcard.h67
-rw-r--r--libs/usvfs/src/shared/winapi.cpp490
-rw-r--r--libs/usvfs/src/shared/winapi.h610
-rw-r--r--libs/usvfs/src/shared/windows_sane.h28
28 files changed, 0 insertions, 5099 deletions
diff --git a/libs/usvfs/src/shared/CMakeLists.txt b/libs/usvfs/src/shared/CMakeLists.txt
deleted file mode 100644
index b1a7c05..0000000
--- a/libs/usvfs/src/shared/CMakeLists.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-
-find_package(Boost CONFIG REQUIRED COMPONENTS algorithm interprocess filesystem)
-find_package(spdlog CONFIG REQUIRED)
-
-file(GLOB sources "*.cpp" "*.h")
-source_group("" FILES ${sources})
-
-add_library(shared STATIC ${sources})
-target_link_libraries(shared
- PUBLIC
- Boost::algorithm Boost::interprocess comsuppw
- Boost::filesystem spdlog::spdlog_header_only)
-target_include_directories(shared
- PUBLIC ${PROJECT_SOURCE_DIR}/include/usvfs ${CMAKE_CURRENT_SOURCE_DIR})
-target_precompile_headers(shared PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/pch.h)
-target_compile_options(shared PUBLIC /FI"pch.h")
-target_compile_definitions(shared PUBLIC
- SPDLOG_USE_STD_FORMAT SPDLOG_NO_NAME SPDLOG_NO_REGISTRY_MUTEX
- BOOST_INTERPROCESS_SHARED_DIR_FUNC BOOST_CONFIG_SUPPRESS_OUTDATED_MESSAGE
- NOMINMAX _WINDOWS _UNICODE UNICODE
- _DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR
-)
diff --git a/libs/usvfs/src/shared/addrtools.h b/libs/usvfs/src/shared/addrtools.h
deleted file mode 100644
index b888ebf..0000000
--- a/libs/usvfs/src/shared/addrtools.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-Userspace Virtual Filesystem
-
-Copyright (C) 2015 Sebastian Herbord. All rights reserved.
-
-This file is part of usvfs.
-
-usvfs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-usvfs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with usvfs. If not, see <http://www.gnu.org/licenses/>.
-*/
-#pragma once
-
-#include "windows_sane.h"
-
-namespace usvfs::shared
-{
-
-#ifdef _M_AMD64
-typedef DWORD64 REGWORD;
-#elif _M_IX86
-typedef DWORD REGWORD;
-#endif
-
-inline LPVOID AddrAdd(LPVOID address, size_t offset)
-{
- return reinterpret_cast<LPVOID>(reinterpret_cast<LPBYTE>(address) + offset);
-}
-
-inline std::ptrdiff_t AddrDiff(LPVOID lhs, LPVOID rhs)
-{
- return reinterpret_cast<LPBYTE>(lhs) - reinterpret_cast<LPBYTE>(rhs);
-}
-
-// implicitly cast pointer to void*, from there cast to target type.
-// This is supposed to be safer than directly reinterpret-casting
-template <typename T>
-inline T void_ptr_cast(void* ptr)
-{
- return reinterpret_cast<T>(ptr);
-}
-
-template <>
-inline int64_t void_ptr_cast(void* ptr)
-{
- return reinterpret_cast<int64_t>(ptr);
-}
-
-template <>
-inline uint64_t void_ptr_cast(void* ptr)
-{
- return reinterpret_cast<uint64_t>(ptr);
-}
-
-} // namespace usvfs::shared
diff --git a/libs/usvfs/src/shared/directory_tree.cpp b/libs/usvfs/src/shared/directory_tree.cpp
deleted file mode 100644
index 33d7ae1..0000000
--- a/libs/usvfs/src/shared/directory_tree.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-Userspace Virtual Filesystem
-
-Copyright (C) 2015 Sebastian Herbord. All rights reserved.
-
-This file is part of usvfs.
-
-usvfs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-usvfs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with usvfs. If not, see <http://www.gnu.org/licenses/>.
-*/
-#include "directory_tree.h"
-#include "tree_container.h"
-
-namespace usvfs::shared
-{
-
-fs::path::iterator nextIter(const fs::path::iterator& iter,
- const fs::path::iterator& end)
-{
- fs::path::iterator next = iter;
- advanceIter(next, end);
- return next;
-}
-
-void advanceIter(fs::path::iterator& iter, const fs::path::iterator& end)
-{
- if (iter == end) {
- return;
- }
-
- ++iter;
- while (iter != end && (iter->wstring() == L"/" || iter->wstring() == L"\\" ||
- iter->wstring() == L"."))
- ++iter;
-}
-
-} // namespace usvfs::shared
diff --git a/libs/usvfs/src/shared/directory_tree.h b/libs/usvfs/src/shared/directory_tree.h
deleted file mode 100644
index 1712071..0000000
--- a/libs/usvfs/src/shared/directory_tree.h
+++ /dev/null
@@ -1,650 +0,0 @@
-/*
-Userspace Virtual Filesystem
-
-Copyright (C) 2015 Sebastian Herbord. All rights reserved.
-
-This file is part of usvfs.
-
-usvfs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-usvfs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with usvfs. If not, see <http://www.gnu.org/licenses/>.
-*/
-#pragma once
-
-#include "exceptionex.h"
-#include "logging.h"
-#include "shared_memory.h"
-#include "stringutils.h"
-#include "wildcard.h"
-
-// simplify unit tests by allowing access to private members
-#ifndef PRIVATE
-#define PRIVATE private
-#endif // PRIVATE
-
-namespace usvfs::shared
-{
-
-template <typename T, typename U>
-struct SHMDataCreator
-{
- static T create(const U& source, const VoidAllocatorT& allocator)
- {
- return T(source, allocator);
- }
-};
-
-template <typename T, typename U>
-T createData(const U& source, const VoidAllocatorT& allocator)
-{
- return SHMDataCreator<T, U>::create(source, allocator);
-}
-
-template <typename T>
-T createDataEmpty(const VoidAllocatorT& allocator);
-
-template <typename T>
-void dataAssign(T& destination, const T& source);
-
-// crappy little workaround for fs::path iterating over path separators
-fs::path::iterator nextIter(const fs::path::iterator& iter,
- const fs::path::iterator& end);
-
-void advanceIter(fs::path::iterator& iter, const fs::path::iterator& end);
-
-// decomposes a path into its components
-//
-class DecomposablePath
-{
-public:
- explicit DecomposablePath(std::string s) : m_s(std::move(s)), m_begin(0), m_end(0)
- {
- m_end = nextSeparator(m_begin);
- }
-
- // move to the next component, returns false when there are no more components
- //
- bool next()
- {
- for (;;) {
- if (m_end >= m_s.size()) {
- // done
- m_begin = m_end;
- return false;
- }
-
- // move begin to one past the last separator found
- m_begin = m_end + 1;
-
- // find the next separator
- m_end = nextSeparator(m_begin);
-
- // check for components that should be ignored:
- // - empty, happens when the path ends with a separator
- // - slashes, happens with consecutive separators
- // - dot, unnecessary
- const auto c = current();
- if (!c.empty() && c != "\\" && c != "/" && c != ".") {
- return true;
- }
- }
- }
-
- // checks if next() would return false
- //
- bool peekNext() const
- {
- auto copy = *this;
- return copy.next();
- }
-
- // the current component, empty when next() returned false
- //
- std::string_view current() const { return {m_s.data() + m_begin, m_end - m_begin}; }
-
-private:
- const std::string m_s;
- std::size_t m_begin, m_end;
-
- // finds the next path separator
- //
- std::size_t nextSeparator(std::size_t from) const
- {
- while (from < m_s.size()) {
- if (m_s[from] == '/' || m_s[from] == '\\') {
- break;
- }
-
- ++from;
- }
-
- return from;
- }
-};
-
-namespace bi = boost::interprocess;
-namespace bmi = boost::multi_index;
-
-typedef uint8_t TreeFlags;
-
-static const TreeFlags FLAG_DIRECTORY = 0x01;
-static const TreeFlags FLAG_DUMMY = 0x02;
-static const TreeFlags FLAG_FIRSTUSERFLAG = 0x10;
-
-struct MissingThrowT
-{};
-static const MissingThrowT MissingThrow = MissingThrowT();
-
-template <typename NodeDataT>
-class TreeContainer;
-
-template <typename T1, typename T2, typename Alloc>
-struct mutable_pair
-{
- typedef T1 first_type;
- typedef T2 second_type;
-
- mutable_pair(Alloc alloc) : first(T1(alloc)), second(T2(alloc)) {}
-
- mutable_pair(const T1& f, const T2& s) : first(f), second(s) {}
-
- mutable_pair(const std::pair<T1, T2>& p) : first(p.first), second(p.second) {}
-
- T1 first;
- mutable T2 second;
-};
-
-template <typename Key, typename T, typename Compare, typename Allocator,
- typename Element = mutable_pair<Key, T, Allocator>>
-using mimap = bmi::multi_index_container<
- Element,
- bmi::indexed_by<
- bmi::ordered_unique<bmi::member<Element, Key, &Element::first>, Compare>>,
- typename Allocator::template rebind<Element>::other>;
-
-/**
- * a representation of a directory tree in memory.
- * This class is designed to be stored in shared memory.
- */
-template <typename NodeDataT>
-class DirectoryTree
-{
- template <typename T>
- friend class TreeContainer;
-
-public:
- struct CILess
- {
- template <typename U, typename V>
- bool operator()(const U& lhs, const V& rhs) const
- {
- const size_t lhsLength = getLength(lhs);
- const size_t rhsLength = getLength(rhs);
-
- const auto r =
- _strnicmp(getCharPtr(lhs), getCharPtr(rhs), std::min(lhsLength, rhsLength));
-
- if (r == 0) {
- return lhsLength < rhsLength;
- }
-
- return (r < 0);
- }
-
- private:
- const char* getCharPtr(const StringT& s) const { return s.c_str(); }
-
- const char* getCharPtr(const std::string& s) const { return s.c_str(); }
-
- const char* getCharPtr(const char* s) const { return s; }
-
- const char* getCharPtr(std::string_view s) const { return s.data(); }
-
- size_t getLength(const StringT& s) const { return s.size(); }
-
- size_t getLength(const std::string& s) const { return s.size(); }
-
- size_t getLength(const char* s) const { return strlen(s); }
-
- size_t getLength(std::string_view s) const { return s.size(); }
- };
-
- typedef DirectoryTree<NodeDataT> NodeT;
- typedef bi::deleter<NodeT, SegmentManagerT> DeleterT;
- typedef NodeDataT DataT;
-
- typedef bi::shared_ptr<NodeT, VoidAllocatorT, DeleterT> NodePtrT;
- typedef bi::weak_ptr<NodeT, VoidAllocatorT, DeleterT> WeakPtrT;
-
- typedef bi::allocator<std::pair<const StringT, NodePtrT>, SegmentManagerT>
- NodeEntryAllocatorT;
-
- typedef mimap<StringT, NodePtrT, CILess, NodeEntryAllocatorT> NodeMapT;
- typedef typename NodeMapT::iterator file_iterator;
- typedef typename NodeMapT::const_iterator const_file_iterator;
-
- typedef std::function<void(const NodePtrT&)> VisitorFunction;
-
- DirectoryTree() = delete;
- DirectoryTree(const NodeT& reference) = delete;
- DirectoryTree(NodeT&& reference) = delete;
- NodeT& operator=(NodeT reference) = delete;
-
- /**
- * @brief construct a new node to be inserted in an existing tree
- **/
- DirectoryTree(std::string_view name, TreeFlags flags, const NodePtrT& parent,
- const NodeDataT& data, const VoidAllocatorT& allocator)
- : m_Parent(parent), m_Name(name.begin(), name.end(), allocator), m_Data(data),
- m_Nodes(allocator), m_Flags(flags)
- {}
-
- ~DirectoryTree() { m_Nodes.clear(); }
-
- /**
- * @return parent node
- */
- NodePtrT parent() const { return m_Parent.lock(); }
-
- /**
- * @return the full path to the node
- */
- fs::path path() const
- {
- if (m_Parent.lock().get() == nullptr) {
- if (m_Name.size() == 0) {
- return fs::path();
- } else {
- return fs::path(m_Name.c_str()) / "\\";
- }
- } else {
- return m_Parent.lock()->path() / m_Name.c_str();
- }
- }
-
- /**
- * @return data connected to this node
- **/
- const NodeDataT& data() const { return m_Data; }
-
- /**
- * @return name of this node
- */
- std::string name() const { return m_Name.c_str(); }
-
- /**
- * @brief setFlag change a flag for this node
- * @param enabled new state for the specified flag
- */
- void setFlag(TreeFlags flag, bool enabled = true)
- {
- m_Flags = enabled ? m_Flags | flag : m_Flags & ~flag;
- }
-
- /**
- * @return true if the specified flag is set, false otherwise
- */
- bool hasFlag(TreeFlags flag) const { return (m_Flags & flag) != 0; }
-
- /**
- * @return true if this node is a directory, false if it's a regular file
- */
- bool isDirectory() const { return hasFlag(FLAG_DIRECTORY); }
-
- /**
- * @return the number of subnodes (directly) below this one
- */
- size_t numNodes() const { return m_Nodes.size(); }
-
- /**
- * @return number of nodes in this (sub-)tree including this one
- */
- size_t numNodesRecursive() const
- {
- size_t result = numNodes() + 1;
-
- for (const auto& node : m_Nodes) {
- result += node.second->numNodesRecursive();
- }
-
- return result;
- }
-
- /**
- * @brief find a node by its path
- * @param path the path to look up
- * @return a pointer to the node or a null ptr
- */
- NodePtrT findNode(const fs::path& path)
- {
- fs::path::iterator iter = path.begin();
- if (iter == path.end()) {
- return NodePtrT();
- }
- return findNode(path, iter);
- }
-
- /**
- * @brief find a node by its path
- * @param path the path to look up
- * @return a pointer to the node or a null ptr
- */
- const NodePtrT findNode(const fs::path& path) const
- {
- fs::path::iterator iter = path.begin();
- if (iter == path.end()) {
- return NodePtrT();
- }
- return findNode(path, iter);
- }
-
- /**
- * @brief visit the nodes along the specified path (in order) calling the visitor for
- * each
- * @param path the path to visit
- * @param visitor a function called for each node
- */
- void visitPath(const fs::path& path, const VisitorFunction& visitor) const
- {
- fs::path::iterator iter = path.begin();
- if (iter == path.end()) {
- return;
- }
- visitPath(path, iter, visitor);
- }
-
- /**
- * @brief retrieve a node by the specified name
- * @param name name of the node
- * @return the node found or an empty pointer if no such node was found
- */
- NodePtrT node(std::string_view name, MissingThrowT) const
- {
- auto iter = m_Nodes.find(name);
-
- if (iter != m_Nodes.end()) {
- return iter->second;
- } else {
- USVFS_THROW_EXCEPTION(node_missing_error());
- }
- }
-
- /**
- * @brief retrieve a node by the specified name
- * @param name name of the node
- * @return the node found or an empty pointer if no such node was found
- */
- NodePtrT node(std::string_view name)
- {
- auto iter = m_Nodes.find(name);
-
- if (iter != m_Nodes.end()) {
- return iter->second;
- } else {
- return NodePtrT();
- }
- }
-
- /**
- * @brief retrieve a node by the specified name
- * @param name name of the node
- * @return the node found or an empty pointer if no such node was found
- */
- const NodePtrT node(std::string_view name, MissingThrowT)
- {
- auto iter = m_Nodes.find(name);
-
- if (iter != m_Nodes.end()) {
- return iter->second;
- } else {
- USVFS_THROW_EXCEPTION(node_missing_error());
- }
- }
-
- /**
- * @brief retrieve a node by the specified name
- * @param name name of the node
- * @return the node found or an empty pointer if no such node was found
- */
- const NodePtrT node(std::string_view name) const
- {
- auto iter = m_Nodes.find(name);
-
- if (iter != m_Nodes.end()) {
- return iter->second;
- } else {
- return NodePtrT();
- }
- }
-
- /**
- * @brief test if a node by the specified name exists
- * @param name name of the node
- * @return true if the node exists, false otherwise
- */
- bool exists(std::string_view name) const
- {
- return m_Nodes.find(name) != m_Nodes.end();
- }
-
- /**
- * @brief find all matches for a pattern
- * @param pattern the pattern to look for
- * @return a vector of the found nodes
- */
- std::vector<NodePtrT> find(const std::string& pattern) const
- {
- // determine if there is a prefix in the pattern that indicates a specific
- // directory.
- size_t fixedPart = pattern.find_first_of("*?");
-
- if (fixedPart == 0)
- fixedPart = std::string::npos;
- if (fixedPart != std::string::npos)
- fixedPart = pattern.find_last_of(R"(\/)", fixedPart);
-
- std::vector<NodePtrT> result;
-
- if (fixedPart != std::string::npos) {
- // if there is a prefix, search for the node representing that path and
- // search only on that
- NodePtrT node = findNode(fs::path(pattern.substr(0, fixedPart)));
- if (node.get() != nullptr) {
- node->findLocal(result, pattern.substr(fixedPart + 1));
- }
- } else {
- findLocal(result, pattern);
- }
-
- return result;
- }
-
- /**
- * @return an iterator to the first leaf
- **/
- file_iterator filesBegin() { return m_Nodes.begin(); }
-
- /**
- * @return a const iterator to the first leaf
- **/
- const_file_iterator filesBegin() const { return m_Nodes.begin(); }
-
- /**
- * @return an iterator one past the last leaf
- **/
- file_iterator filesEnd() { return m_Nodes.end(); }
-
- /**
- * @return a const iterator one past the last leaf
- **/
- const_file_iterator filesEnd() const { return m_Nodes.end(); }
-
- /**
- * @brief erase the leaf at the specified iterator
- * @return an iterator to the following file
- **/
- file_iterator erase(file_iterator iter) { return m_Nodes.erase(iter); }
-
- /**
- * @brief clear all nodes
- */
- void clear() { m_Nodes.clear(); }
-
- void removeFromTree()
- {
- if (auto par = parent()) {
- spdlog::get("usvfs")->info("remove from tree {}", m_Name.c_str());
- auto self = par->m_Nodes.find(m_Name.c_str());
- if (self != par->m_Nodes.end()) {
- par->erase(self);
- } else {
- // trying to remove a node that does not exist, most likely because it was
- // already removed in a lower level call. this is known to happen when MoveFile
- // has the MOVEFILE_COPY_ALLOWED flag and moving a mapped file.
- spdlog::get("usvfs")->warn("Failed to remove inexisting node from tree: {}",
- m_Name.c_str());
- }
- }
- }
-
- PRIVATE : void set(StringT key, const NodePtrT& value)
- {
- auto res = m_Nodes.emplace(std::move(key), value);
- if (!res.second) {
- res.first->second = value;
- }
- }
-
- WeakPtrT findRoot() const
- {
- if (m_Parent.lock().get() == nullptr) {
- return m_Self;
- } else {
- return m_Parent.lock()->findRoot();
- }
- }
-
- NodePtrT findNode(const fs::path& name, fs::path::iterator& iter)
- {
- if (iter == name.end()) {
- return NodePtrT();
- }
-
- std::string l = iter->string();
- auto subNode = m_Nodes.find(iter->string());
- advanceIter(iter, name.end());
-
- if (iter == name.end()) {
- // last name component, should be a local node
- if (subNode != m_Nodes.end()) {
- return subNode->second;
- } else {
- return NodePtrT();
- }
- } else {
- if (subNode != m_Nodes.end()) {
- return subNode->second->findNode(name, iter);
- } else {
- return NodePtrT();
- }
- }
- }
-
- const NodePtrT findNode(const fs::path& name, fs::path::iterator& iter) const
- {
- if (iter == name.end()) {
- return NodePtrT();
- }
-
- auto subNode = m_Nodes.find(iter->string());
- advanceIter(iter, name.end());
-
- if (iter == name.end()) {
- // last name component, should be a local node
- if (subNode != m_Nodes.end()) {
- return subNode->second;
- } else {
- return NodePtrT();
- }
- } else {
- if (subNode != m_Nodes.end()) {
- return subNode->second->findNode(name, iter);
- } else {
- return NodePtrT();
- }
- }
- }
-
- void visitPath(const fs::path& path, fs::path::iterator& iter,
- const VisitorFunction& visitor) const
- {
- if (iter == path.end()) {
- return;
- }
-
- auto subNode = m_Nodes.find(iter->string());
-
- if (subNode != m_Nodes.end()) {
- visitor(subNode->second);
- advanceIter(iter, path.end());
- if (iter != path.end()) {
- subNode->second->visitPath(path, iter, visitor);
- }
- }
- }
-
- void findLocal(std::vector<NodePtrT>& output, const std::string& pattern) const
- {
- for (auto iter = m_Nodes.begin(); iter != m_Nodes.end(); ++iter) {
- LPCSTR remainder = nullptr;
-
- if (pattern.size() > 1 && (pattern[0] == '*') &&
- ((pattern[1] == '/') || (pattern[1] == '\\')) &&
- iter->second->isDirectory()) {
- // the star may represent a directory (one directory level, not
- // multiple!), search in subdirectory
- iter->second->findLocal(output, pattern.substr(1));
- } else if ((remainder = wildcard::PartialMatch(iter->second->name().c_str(),
- pattern.c_str())) != nullptr) {
- if ((*remainder == '\0') || (strcmp(remainder, "*") == 0)) {
- NodePtrT node = iter->second;
- output.push_back(node);
- }
-
- if (iter->second->isDirectory()) {
- iter->second->findLocal(output, remainder);
- }
- }
- }
- }
-
- PRIVATE : TreeFlags m_Flags;
-
- WeakPtrT m_Parent;
- WeakPtrT m_Self;
-
- StringT m_Name;
- NodeDataT m_Data;
-
- NodeMapT m_Nodes;
-};
-
-template <typename NodeDataT>
-void dumpTree(std::ostream& stream, const DirectoryTree<NodeDataT>& tree, int level = 0)
-{
- stream << std::string(level, ' ') << tree.name() << " -> " << tree.data() << "\n";
- for (auto iter = tree.filesBegin(); iter != tree.filesEnd(); ++iter) {
- dumpTree<NodeDataT>(stream, *iter->second, level + 1);
- }
-}
-
-} // namespace usvfs::shared
diff --git a/libs/usvfs/src/shared/exceptionex.cpp b/libs/usvfs/src/shared/exceptionex.cpp
deleted file mode 100644
index 4a814b5..0000000
--- a/libs/usvfs/src/shared/exceptionex.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
-Userspace Virtual Filesystem
-
-Copyright (C) 2015 Sebastian Herbord. All rights reserved.
-
-This file is part of usvfs.
-
-usvfs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-usvfs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with usvfs. If not, see <http://www.gnu.org/licenses/>.
-*/
-#include "exceptionex.h"
-#include "winapi.h"
-#include <spdlog/spdlog.h>
-
-namespace usvfs::shared
-{
-
-std::string windows_error::constructMessage(const std::string& input, int inErrorCode)
-{
- std::ostringstream finalMessage;
- finalMessage << input;
-
- LPSTR buffer = nullptr;
-
- DWORD errorCode = inErrorCode != -1 ? inErrorCode : GetLastError();
-
- // TODO: the message is not english?
- if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- nullptr, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPSTR)&buffer, 0, nullptr) == 0) {
- finalMessage << " (errorcode " << errorCode << ")";
- } else {
- LPSTR lastChar = buffer + strlen(buffer) - 2;
- *lastChar = '\0';
- finalMessage << " (" << buffer << " [" << errorCode << "])";
- LocalFree(buffer); // allocated by FormatMessage
- }
-
- SetLastError(
- errorCode); // restore error code because FormatMessage might have modified it
- return finalMessage.str();
-}
-
-} // namespace usvfs::shared
-
-void logExtInfo(const std::exception& e, LogLevel logLevel)
-{
- std::string content;
-
- if (const std::string* msg = boost::get_error_info<ex_msg>(e)) {
- content = *msg;
- }
-
- if (const DWORD* errorCode = boost::get_error_info<ex_win_errcode>(e)) {
- content = std::string("error: ") + winapi::ex::ansi::errorString(*errorCode);
- }
-
- switch (logLevel) {
- case LogLevel::Debug:
- spdlog::get("usvfs")->debug(content);
- break;
- case LogLevel::Info:
- spdlog::get("usvfs")->info(content);
- break;
- case LogLevel::Warning:
- spdlog::get("usvfs")->warn(content);
- break;
- case LogLevel::Error:
- spdlog::get("usvfs")->error(content);
- break;
- }
-}
diff --git a/libs/usvfs/src/shared/exceptionex.h b/libs/usvfs/src/shared/exceptionex.h
deleted file mode 100644
index 4c298a5..0000000
--- a/libs/usvfs/src/shared/exceptionex.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
-Userspace Virtual Filesystem
-
-Copyright (C) 2015 Sebastian Herbord. All rights reserved.
-
-This file is part of usvfs.
-
-usvfs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-usvfs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with usvfs. If not, see <http://www.gnu.org/licenses/>.
-*/
-#pragma once
-
-#include "logging.h"
-#include <boost/exception/all.hpp>
-#include <stdexcept>
-
-typedef boost::error_info<struct tag_message, DWORD> ex_win_errcode;
-typedef boost::error_info<struct tag_message, std::string> ex_msg;
-
-struct std_boost_exception : virtual boost::exception, virtual std::exception
-{
- const char* what() const noexcept override
- {
- return boost::diagnostic_information_what(*this);
- }
-};
-
-struct incompatibility_error : std_boost_exception
-{};
-struct usage_error : std_boost_exception
-{};
-struct data_error : std_boost_exception
-{};
-struct file_not_found_error : std_boost_exception
-{};
-struct timeout_error : std_boost_exception
-{};
-struct unknown_error : std_boost_exception
-{};
-struct node_missing_error : std_boost_exception
-{};
-
-#define USVFS_THROW_EXCEPTION(x) BOOST_THROW_EXCEPTION(x)
-
-void logExtInfo(const std::exception& e, LogLevel logLevel = LogLevel::Warning);
-
-namespace usvfs::shared
-{
-
-class windows_error : public std::runtime_error
-{
-public:
- windows_error(const std::string& message, int errorcode = GetLastError())
- : runtime_error(constructMessage(message, errorcode)), m_ErrorCode(errorcode)
- {}
-
- int getErrorCode() const { return m_ErrorCode; }
-
-private:
- int m_ErrorCode;
-
- std::string constructMessage(const std::string& input, int errorcode);
-};
-
-class guard
-{
-public:
- explicit guard(std::function<void()> f) : m_f(std::move(f)) {}
-
- ~guard()
- {
- if (m_f) {
- m_f();
- }
- }
-
- guard(const guard&);
- guard& operator=(const guard&);
-
-private:
- std::function<void()> m_f;
-};
-
-} // namespace usvfs::shared
-
-#define CONCATENATE_DIRECT(s1, s2) s1##s2
-#define CONCATENATE(s1, s2) CONCATENATE_DIRECT(s1, s2)
-#define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __LINE__)
-#define ON_BLOCK_EXIT(f) usvfs::shared::guard ANONYMOUS_VARIABLE(guard)(f)
diff --git a/libs/usvfs/src/shared/formatters.h b/libs/usvfs/src/shared/formatters.h
deleted file mode 100644
index 3d0e47e..0000000
--- a/libs/usvfs/src/shared/formatters.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
-Userspace Virtual Filesystem
-
-Copyright (C) 2024. All rights reserved.
-
-This file is part of usvfs.
-
-usvfs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-usvfs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with usvfs. If not, see <http://www.gnu.org/licenses/>.
-*/
-#pragma once
-
-#include <format>
-#include <type_traits>
-
-#include "ntdll_declarations.h"
-
-// formatters for standard types
-
-namespace usvfs::log
-{
-std::string to_string(LPCWSTR value);
-std::string to_string(PCUNICODE_STRING value);
-} // namespace usvfs::log
-
-template <class Enum, class CharT>
- requires std::is_enum_v<Enum>
-struct std::formatter<Enum, CharT> : std::formatter<std::underlying_type_t<Enum>, CharT>
-{
- template <class FmtContext>
- FmtContext::iterator format(Enum v, FmtContext& ctx) const
- {
- return std::formatter<std::underlying_type_t<Enum>, CharT>::format(
- static_cast<std::underlying_type_t<Enum>>(v), ctx);
- }
-};
-
-template <>
-struct std::formatter<LPCWSTR, char> : std::formatter<std::string, char>
-{
- template <class FmtContext>
- FmtContext::iterator format(LPCWSTR v, FmtContext& ctx) const
- {
- return std::formatter<std::string, char>::format(usvfs::log::to_string(v), ctx);
- }
-};
-
-template <>
-struct std::formatter<std::wstring, char> : std::formatter<LPCWSTR, char>
-{
- template <class FmtContext>
- FmtContext::iterator format(const std::wstring& v, FmtContext& ctx) const
- {
- return std::formatter<LPCWSTR, char>::format(v.c_str(), ctx);
- }
-};
-
-template <>
-struct std::formatter<PCUNICODE_STRING, char> : std::formatter<std::string, char>
-{
- template <class FmtContext>
- FmtContext::iterator format(PCUNICODE_STRING v, FmtContext& ctx) const
- {
- return std::formatter<std::string, char>::format(usvfs::log::to_string(v), ctx);
- }
-};
-
-template <>
-struct std::formatter<UNICODE_STRING, char> : std::formatter<std::string, char>
-{
- template <class FmtContext>
- FmtContext::iterator format(UNICODE_STRING v, FmtContext& ctx) const
- {
- return std::formatter<std::string, char>::format(usvfs::log::to_string(&v), ctx);
- }
-};
-
-template <class Pointer>
- requires(std::is_pointer_v<Pointer> && !std::is_same_v<Pointer, const char*> &&
- !std::is_same_v<Pointer, char*> && !std::is_same_v<Pointer, const void*> &&
- !std::is_same_v<Pointer, void*>)
-struct std::formatter<Pointer, char> : std::formatter<const void*, char>
-{
- template <class FmtContext>
- FmtContext::iterator format(Pointer v, FmtContext& ctx) const
- {
- return std::formatter<const void*, char>::format(v, ctx);
- }
-};
-
-namespace usvfs::log
-{
-
-/**
- * a small helper class to wrap any object. The whole point is to give us a way
- * to ensure our own operator<< is used in addParam calls
- */
-template <typename T>
-class Wrap
-{
-public:
- explicit Wrap(const T& data) : m_Data(data) {}
- Wrap(Wrap<T>&& reference) : m_Data(std::move(reference.m_Data)) {}
-
- Wrap(const Wrap<T>& reference) = delete;
- Wrap<T>& operator=(const Wrap<T>& reference) = delete;
-
-private:
- friend struct ::std::formatter<Wrap<T>, char>;
- const T& m_Data;
-};
-
-template <typename T>
-Wrap<T> wrap(const T& data)
-{
- return Wrap<T>(data);
-}
-
-} // namespace usvfs::log
-
-template <>
-struct std::formatter<usvfs::log::Wrap<DWORD>, char> : std::formatter<DWORD, char>
-{
- template <class FmtContext>
- FmtContext::iterator format(const usvfs::log::Wrap<DWORD>& v, FmtContext& ctx) const
- {
- return std::format_to(ctx.out(), "{:x}", v.m_Data);
- }
-};
-
-template <>
-struct std::formatter<usvfs::log::Wrap<NTSTATUS>, char> : std::formatter<NTSTATUS, char>
-{
- template <class FmtContext>
- FmtContext::iterator format(const usvfs::log::Wrap<NTSTATUS>& v,
- FmtContext& ctx) const
- {
- switch (v.m_Data) {
- case 0x00000000:
- return std::format_to(ctx.out(), "ok");
- case 0xC0000022:
- return std::format_to(ctx.out(), "access denied");
- case 0xC0000035:
- return std::format_to(ctx.out(), "exists already");
- }
- return std::format_to(ctx.out(), "err {:x}", v.m_Data);
- }
-};
diff --git a/libs/usvfs/src/shared/loghelpers.cpp b/libs/usvfs/src/shared/loghelpers.cpp
deleted file mode 100644
index bfcabf1..0000000
--- a/libs/usvfs/src/shared/loghelpers.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
-Userspace Virtual Filesystem
-
-Copyright (C) 2015 Sebastian Herbord. All rights reserved.
-
-This file is part of usvfs.
-
-usvfs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-usvfs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with usvfs. If not, see <http://www.gnu.org/licenses/>.
-*/
-#include <format>
-
-#include "formatters.h"
-#include "loghelpers.h"
-#include "stringcast.h"
-#include "stringutils.h"
-
-namespace ush = usvfs::shared;
-
-namespace usvfs::log
-{
-
-// this is declared in formatters but is defined here to avoid a whole .cpp
-// file for two small functions
-//
-// comments from old code, taken as is:
-//
-// TODO this does not correctly support surrogate pairs since the size used here
-// is the number of 16-bit characters in the buffer whereas toNarrow expects the
-// actual number of characters. It will always underestimate though, so worst
-// case scenario we truncate the string
-//
-std::string to_string(LPCWSTR value)
-{
- if (value == nullptr) {
- return "<null>";
- }
- try {
- return ush::string_cast<std::string>(value, ush::CodePage::UTF8);
- } catch (const std::exception& e) {
- return std::format("<err: {}>", e.what());
- }
-}
-std::string to_string(PCUNICODE_STRING value)
-{
- try {
- return ush::string_cast<std::string>(value->Buffer, ush::CodePage::UTF8,
- value->Length / sizeof(WCHAR));
- } catch (const std::exception& e) {
- return std::format("<err: {}>", e.what());
- }
-}
-
-spdlog::level::level_enum ConvertLogLevel(LogLevel level)
-{
- switch (level) {
- case LogLevel::Debug:
- return spdlog::level::debug;
- case LogLevel::Info:
- return spdlog::level::info;
- case LogLevel::Warning:
- return spdlog::level::warn;
- case LogLevel::Error:
- return spdlog::level::err;
- default:
- return spdlog::level::debug;
- }
-}
-
-LogLevel ConvertLogLevel(spdlog::level::level_enum level)
-{
- switch (level) {
- case spdlog::level::debug:
- return LogLevel::Debug;
- case spdlog::level::info:
- return LogLevel::Info;
- case spdlog::level::warn:
- return LogLevel::Warning;
- case spdlog::level::err:
- return LogLevel::Error;
- default:
- return LogLevel::Debug;
- }
-}
-
-} // namespace usvfs::log
diff --git a/libs/usvfs/src/shared/loghelpers.h b/libs/usvfs/src/shared/loghelpers.h
deleted file mode 100644
index 071ad9d..0000000
--- a/libs/usvfs/src/shared/loghelpers.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
-Userspace Virtual Filesystem
-
-Copyright (C) 2015 Sebastian Herbord. All rights reserved.
-
-This file is part of usvfs.
-
-usvfs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-usvfs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with usvfs. If not, see <http://www.gnu.org/licenses/>.
-*/
-#pragma once
-
-#include "dllimport.h"
-#include "formatters.h"
-#include "ntdll_declarations.h"
-#include "shmlogger.h"
-#include "stringutils.h"
-
-namespace usvfs::log
-{
-
-enum class DisplayStyle : uint8_t
-{
- Hex = 0x01
-};
-
-class CallLoggerDummy
-{
-public:
- template <typename T>
- CallLoggerDummy& addParam(const char*, const T&, uint8_t style = 0)
- {
- return *this;
- }
-};
-
-class CallLogger
-{
-public:
- explicit CallLogger(const char* function)
- {
- const char* namespaceend = strrchr(function, ':');
-
- if (namespaceend != nullptr) {
- function = namespaceend + 1;
- }
-
- m_Message = function;
- }
-
- ~CallLogger()
- {
- try {
- static std::shared_ptr<spdlog::logger> log = spdlog::get("hooks");
- log->debug("{}", m_Message);
- } catch (...) {
- // suppress all exceptions in destructor
- }
- }
-
- template <typename T>
- CallLogger& addParam(const char* name, const T& value, uint8_t style = 0);
-
-private:
- std::string m_Message;
-};
-
-template <typename T>
-CallLogger& CallLogger::addParam(const char* name, const T& value, uint8_t style)
-{
- static bool enabled = spdlog::get("hooks")->should_log(spdlog::level::debug);
- typedef std::underlying_type<DisplayStyle>::type DSType;
-
- if (enabled) {
- if constexpr (std::is_pointer_v<T>) {
- if (value == nullptr) {
- std::format_to(std::back_inserter(m_Message), "[{}=<null>]", name);
- } else {
- std::format_to(std::back_inserter(m_Message), "[{}={}]", name, value);
- }
- } else if constexpr (std::is_integral_v<T>) {
- if (style & static_cast<DSType>(DisplayStyle::Hex)) {
- std::format_to(std::back_inserter(m_Message), "[{}={:x}]", name, value);
- } else {
- std::format_to(std::back_inserter(m_Message), "[{}={}]", name, value);
- }
- } else {
- std::format_to(std::back_inserter(m_Message), "[{}={}]", name, value);
- }
- }
-
- return *this;
-}
-
-spdlog::level::level_enum ConvertLogLevel(LogLevel level);
-LogLevel ConvertLogLevel(spdlog::level::level_enum level);
-
-} // namespace usvfs::log
-
-// prefer the short variant of the function name, without signature.
-// Fall back to the portable boost macro
-#ifdef __FUNCTION__
-#define __MYFUNC__ __FUNCTION__
-#else
-#define __MYFUNC__ BOOST_CURRENT_FUNCTION
-#endif
-
-#define LOG_CALL() usvfs::log::CallLogger(__MYFUNC__)
-
-#define PARAM(val) addParam(#val, val)
-#define PARAMHEX(val) \
- addParam(#val, val, static_cast<uint8_t>(usvfs::log::DisplayStyle::Hex))
-#define PARAMWRAP(val) addParam(#val, usvfs::log::wrap(val))
diff --git a/libs/usvfs/src/shared/ntdll_declarations.cpp b/libs/usvfs/src/shared/ntdll_declarations.cpp
deleted file mode 100644
index b4bf0f5..0000000
--- a/libs/usvfs/src/shared/ntdll_declarations.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
-Userspace Virtual Filesystem
-
-Copyright (C) 2015 Sebastian Herbord. All rights reserved.
-
-This file is part of usvfs.
-
-usvfs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-usvfs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with usvfs. If not, see <http://www.gnu.org/licenses/>.
-*/
-#include "ntdll_declarations.h"
-#include <cassert>
-
-#define LOAD_EXT(mod, name) \
- name = reinterpret_cast<name##_type>(::GetProcAddress(mod, #name)); \
- assert(name != nullptr)
-
-NtQueryDirectoryFile_type NtQueryDirectoryFile;
-NtQueryDirectoryFileEx_type NtQueryDirectoryFileEx;
-NtQueryFullAttributesFile_type NtQueryFullAttributesFile;
-NtQueryAttributesFile_type NtQueryAttributesFile;
-NtQueryObject_type NtQueryObject;
-NtQueryInformationFile_type NtQueryInformationFile;
-NtQueryInformationByName_type NtQueryInformationByName;
-NtOpenFile_type NtOpenFile;
-NtCreateFile_type NtCreateFile;
-NtClose_type NtClose;
-RtlDoesFileExists_U_type RtlDoesFileExists_U;
-RtlDosPathNameToRelativeNtPathName_U_WithStatus_type
- RtlDosPathNameToRelativeNtPathName_U_WithStatus;
-RtlReleaseRelativeName_type RtlReleaseRelativeName;
-RtlGetVersion_type RtlGetVersion;
-NtTerminateProcess_type NtTerminateProcess;
-
-static bool ntdll_initialized;
-
-void ntdll_declarations_init()
-{
- if (!ntdll_initialized) {
- HMODULE ntDLLMod = GetModuleHandleW(L"ntdll.dll");
-
- LOAD_EXT(ntDLLMod, NtQueryDirectoryFile);
- LOAD_EXT(ntDLLMod, NtQueryDirectoryFileEx);
- LOAD_EXT(ntDLLMod, NtQueryFullAttributesFile);
- LOAD_EXT(ntDLLMod, NtQueryAttributesFile);
- LOAD_EXT(ntDLLMod, NtQueryObject);
- LOAD_EXT(ntDLLMod, NtQueryInformationFile);
- LOAD_EXT(ntDLLMod, NtQueryInformationByName);
- LOAD_EXT(ntDLLMod, NtCreateFile);
- LOAD_EXT(ntDLLMod, NtOpenFile);
- LOAD_EXT(ntDLLMod, NtClose);
- LOAD_EXT(ntDLLMod, RtlDoesFileExists_U);
- LOAD_EXT(ntDLLMod, RtlDosPathNameToRelativeNtPathName_U_WithStatus);
- LOAD_EXT(ntDLLMod, RtlReleaseRelativeName);
- LOAD_EXT(ntDLLMod, RtlGetVersion);
- LOAD_EXT(ntDLLMod, NtTerminateProcess);
-
- ntdll_initialized = true;
- }
-}
-
-static struct __Initializer
-{
- __Initializer() { ntdll_declarations_init(); }
-} __initializer;
diff --git a/libs/usvfs/src/shared/ntdll_declarations.h b/libs/usvfs/src/shared/ntdll_declarations.h
deleted file mode 100644
index 813ad8c..0000000
--- a/libs/usvfs/src/shared/ntdll_declarations.h
+++ /dev/null
@@ -1,612 +0,0 @@
-/*
-Userspace Virtual Filesystem
-
-Copyright (C) 2015 Sebastian Herbord. All rights reserved.
-
-This file is part of usvfs.
-
-usvfs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-usvfs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with usvfs. If not, see <http://www.gnu.org/licenses/>.
-*/
-#pragma once
-
-#include "windows_sane.h"
-
-#pragma warning(push)
-#pragma warning(disable : 4201)
-
-typedef LONG NTSTATUS;
-
-typedef struct _IO_STATUS_BLOCK
-{
- union
- {
- NTSTATUS Status;
- PVOID Pointer;
- } DUMMYUNIONNAME;
-
- ULONG_PTR Information;
-} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
-
-typedef struct _FILE_DIRECTORY_INFORMATION
-{
- ULONG NextEntryOffset;
- ULONG FileIndex;
- LARGE_INTEGER CreationTime;
- LARGE_INTEGER LastAccessTime;
- LARGE_INTEGER LastWriteTime;
- LARGE_INTEGER ChangeTime;
- LARGE_INTEGER EndOfFile;
- LARGE_INTEGER AllocationSize;
- ULONG FileAttributes;
- ULONG FileNameLength;
- WCHAR FileName[1];
-} FILE_DIRECTORY_INFORMATION, *PFILE_DIRECTORY_INFORMATION;
-
-typedef struct _FILE_FULL_DIR_INFORMATION
-{
- ULONG NextEntryOffset;
- ULONG FileIndex;
- LARGE_INTEGER CreationTime;
- LARGE_INTEGER LastAccessTime;
- LARGE_INTEGER LastWriteTime;
- LARGE_INTEGER ChangeTime;
- LARGE_INTEGER EndOfFile;
- LARGE_INTEGER AllocationSize;
- ULONG FileAttributes;
- ULONG FileNameLength;
- ULONG EaSize;
- WCHAR FileName[1];
-} FILE_FULL_DIR_INFORMATION, *PFILE_FULL_DIR_INFORMATION;
-
-typedef struct _FILE_ID_FULL_DIR_INFORMATION
-{
- ULONG NextEntryOffset;
- ULONG FileIndex;
- LARGE_INTEGER CreationTime;
- LARGE_INTEGER LastAccessTime;
- LARGE_INTEGER LastWriteTime;
- LARGE_INTEGER ChangeTime;
- LARGE_INTEGER EndOfFile;
- LARGE_INTEGER AllocationSize;
- ULONG FileAttributes;
- ULONG FileNameLength;
- ULONG EaSize;
- LARGE_INTEGER FileId;
- WCHAR FileName[1];
-} FILE_ID_FULL_DIR_INFORMATION, *PFILE_ID_FULL_DIR_INFORMATION;
-
-typedef struct _FILE_BOTH_DIR_INFORMATION
-{
- ULONG NextEntryOffset;
- ULONG FileIndex;
- LARGE_INTEGER CreationTime;
- LARGE_INTEGER LastAccessTime;
- LARGE_INTEGER LastWriteTime;
- LARGE_INTEGER ChangeTime;
- LARGE_INTEGER EndOfFile;
- LARGE_INTEGER AllocationSize;
- ULONG FileAttributes;
- ULONG FileNameLength;
- ULONG EaSize;
- CCHAR ShortNameLength;
- WCHAR ShortName[12];
- WCHAR FileName[1];
-} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;
-
-typedef struct _FILE_ID_BOTH_DIR_INFORMATION
-{
- ULONG NextEntryOffset;
- ULONG FileIndex;
- LARGE_INTEGER CreationTime;
- LARGE_INTEGER LastAccessTime;
- LARGE_INTEGER LastWriteTime;
- LARGE_INTEGER ChangeTime;
- LARGE_INTEGER EndOfFile;
- LARGE_INTEGER AllocationSize;
- ULONG FileAttributes;
- ULONG FileNameLength;
- ULONG EaSize;
- CCHAR ShortNameLength;
- WCHAR ShortName[12];
- LARGE_INTEGER FileId;
- WCHAR FileName[1];
-} FILE_ID_BOTH_DIR_INFORMATION, *PFILE_ID_BOTH_DIR_INFORMATION;
-
-typedef struct _FILE_BASIC_INFORMATION
-{
- LARGE_INTEGER CreationTime;
- LARGE_INTEGER LastAccessTime;
- LARGE_INTEGER LastWriteTime;
- LARGE_INTEGER ChangeTime;
- ULONG FileAttributes;
-} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;
-
-typedef struct _FILE_RENAME_INFORMATION
-{
-#if (_WIN32_WINNT >= _WIN32_WINNT_WIN10_RS1)
- union
- {
- BOOLEAN ReplaceIfExists; // FileRenameInformation
- ULONG Flags; // FileRenameInformationEx
- } DUMMYUNIONNAME;
-#else
- BOOLEAN ReplaceIfExists;
-#endif
- HANDLE RootDirectory;
- ULONG FileNameLength;
- WCHAR FileName[1];
-} FILE_RENAME_INFORMATION, *PFILE_RENAME_INFORMATION;
-
-typedef struct _FILE_STANDARD_INFORMATION
-{
- LARGE_INTEGER AllocationSize;
- LARGE_INTEGER EndOfFile;
- ULONG NumberOfLinks;
- BOOLEAN DeletePending;
- BOOLEAN Directory;
-} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;
-
-typedef struct _FILE_NAMES_INFORMATION
-{
- ULONG NextEntryOffset;
- ULONG FileIndex;
- ULONG FileNameLength;
- WCHAR FileName[1];
-} FILE_NAMES_INFORMATION, *PFILE_NAMES_INFORMATION;
-
-typedef struct _FILE_INTERNAL_INFORMATION
-{
- LARGE_INTEGER IndexNumber;
-} FILE_INTERNAL_INFORMATION, *PFILE_INTERNAL_INFORMATION;
-
-typedef struct _FILE_EA_INFORMATION
-{
- ULONG EaSize;
-} FILE_EA_INFORMATION, *PFILE_EA_INFORMATION;
-
-typedef struct _FILE_ACCESS_INFORMATION
-{
- ACCESS_MASK AccessFlags;
-} FILE_ACCESS_INFORMATION, *PFILE_ACCESS_INFORMATION;
-
-typedef struct _FILE_POSITION_INFORMATION
-{
- LARGE_INTEGER CurrentByteOffset;
-} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;
-
-typedef struct _FILE_MODE_INFORMATION
-{
- ULONG Mode;
-} FILE_MODE_INFORMATION, *PFILE_MODE_INFORMATION;
-
-typedef struct _FILE_ALIGNMENT_INFORMATION
-{
- ULONG AlignmentRequirement;
-} FILE_ALIGNMENT_INFORMATION, *PFILE_ALIGNMENT_INFORMATION;
-
-typedef struct _FILE_NAME_INFORMATION
-{
- ULONG FileNameLength;
- WCHAR FileName[1];
-} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;
-
-typedef struct _FILE_ID_EXTD_DIR_INFORMATION
-{
- ULONG NextEntryOffset;
- ULONG FileIndex;
- LARGE_INTEGER CreationTime;
- LARGE_INTEGER LastAccessTime;
- LARGE_INTEGER LastWriteTime;
- LARGE_INTEGER ChangeTime;
- LARGE_INTEGER EndOfFile;
- LARGE_INTEGER AllocationSize;
- ULONG FileAttributes;
- ULONG FileNameLength;
- ULONG EaSize;
- ULONG ReparsePointTag;
- FILE_ID_128 FileId;
- WCHAR FileName[1];
-} FILE_ID_EXTD_DIR_INFORMATION, *PFILE_ID_EXTD_DIR_INFORMATION;
-
-typedef struct _FILE_ID_EXTD_BOTH_DIR_INFORMATION
-{
- ULONG NextEntryOffset;
- ULONG FileIndex;
- LARGE_INTEGER CreationTime;
- LARGE_INTEGER LastAccessTime;
- LARGE_INTEGER LastWriteTime;
- LARGE_INTEGER ChangeTime;
- LARGE_INTEGER EndOfFile;
- LARGE_INTEGER AllocationSize;
- ULONG FileAttributes;
- ULONG FileNameLength;
- ULONG EaSize;
- ULONG ReparsePointTag;
- FILE_ID_128 FileId;
- CCHAR ShortNameLength;
- WCHAR ShortName[12];
- WCHAR FileName[1];
-} FILE_ID_EXTD_BOTH_DIR_INFORMATION, *PFILE_ID_EXTD_BOTH_DIR_INFORMATION;
-
-typedef struct _FILE_ID_64_EXTD_DIR_INFORMATION
-{
- ULONG NextEntryOffset;
- ULONG FileIndex;
- LARGE_INTEGER CreationTime;
- LARGE_INTEGER LastAccessTime;
- LARGE_INTEGER LastWriteTime;
- LARGE_INTEGER ChangeTime;
- LARGE_INTEGER EndOfFile;
- LARGE_INTEGER AllocationSize;
- ULONG FileAttributes;
- ULONG FileNameLength;
- ULONG EaSize;
- ULONG ReparsePointTag;
- LARGE_INTEGER FileId;
- WCHAR FileName[1];
-} FILE_ID_64_EXTD_DIR_INFORMATION, *PFILE_ID_64_EXTD_DIR_INFORMATION;
-
-typedef struct _FILE_ID_64_EXTD_BOTH_DIR_INFORMATION
-{
- ULONG NextEntryOffset;
- ULONG FileIndex;
- LARGE_INTEGER CreationTime;
- LARGE_INTEGER LastAccessTime;
- LARGE_INTEGER LastWriteTime;
- LARGE_INTEGER ChangeTime;
- LARGE_INTEGER EndOfFile;
- LARGE_INTEGER AllocationSize;
- ULONG FileAttributes;
- ULONG FileNameLength;
- ULONG EaSize;
- ULONG ReparsePointTag;
- LARGE_INTEGER FileId;
- CCHAR ShortNameLength;
- WCHAR ShortName[12];
- WCHAR FileName[1];
-} FILE_ID_64_EXTD_BOTH_DIR_INFORMATION, *PFILE_ID_64_EXTD_BOTH_DIR_INFORMATION;
-
-typedef struct _FILE_ID_ALL_EXTD_DIR_INFORMATION
-{
- ULONG NextEntryOffset;
- ULONG FileIndex;
- LARGE_INTEGER CreationTime;
- LARGE_INTEGER LastAccessTime;
- LARGE_INTEGER LastWriteTime;
- LARGE_INTEGER ChangeTime;
- LARGE_INTEGER EndOfFile;
- LARGE_INTEGER AllocationSize;
- ULONG FileAttributes;
- ULONG FileNameLength;
- ULONG EaSize;
- ULONG ReparsePointTag;
- LARGE_INTEGER FileId;
- FILE_ID_128 FileId128;
- WCHAR FileName[1];
-} FILE_ID_ALL_EXTD_DIR_INFORMATION, *PFILE_ID_ALL_EXTD_DIR_INFORMATION;
-
-typedef struct _FILE_ID_ALL_EXTD_BOTH_DIR_INFORMATION
-{
- ULONG NextEntryOffset;
- ULONG FileIndex;
- LARGE_INTEGER CreationTime;
- LARGE_INTEGER LastAccessTime;
- LARGE_INTEGER LastWriteTime;
- LARGE_INTEGER ChangeTime;
- LARGE_INTEGER EndOfFile;
- LARGE_INTEGER AllocationSize;
- ULONG FileAttributes;
- ULONG FileNameLength;
- ULONG EaSize;
- ULONG ReparsePointTag;
- LARGE_INTEGER FileId;
- FILE_ID_128 FileId128;
- CCHAR ShortNameLength;
- WCHAR ShortName[12];
- WCHAR FileName[1];
-} FILE_ID_ALL_EXTD_BOTH_DIR_INFORMATION, *PFILE_ID_ALL_EXTD_BOTH_DIR_INFORMATION;
-
-typedef struct _FILE_ALL_INFORMATION
-{
- FILE_BASIC_INFORMATION BasicInformation;
- FILE_STANDARD_INFORMATION StandardInformation;
- FILE_INTERNAL_INFORMATION InternalInformation;
- FILE_EA_INFORMATION EaInformation;
- FILE_ACCESS_INFORMATION AccessInformation;
- FILE_POSITION_INFORMATION PositionInformation;
- FILE_MODE_INFORMATION ModeInformation;
- FILE_ALIGNMENT_INFORMATION AlignmentInformation;
- FILE_NAME_INFORMATION NameInformation;
-} FILE_ALL_INFORMATION, *PFILE_ALL_INFORMATION;
-
-typedef struct _FILE_OBJECTID_INFORMATION
-{
- LONGLONG FileReference;
- UCHAR ObjectId[16];
- union
- {
- struct
- {
- UCHAR BirthVolumeId[16];
- UCHAR BirthObjectId[16];
- UCHAR DomainId[16];
- };
- UCHAR ExtendedInfo[48];
- };
-} FILE_OBJECTID_INFORMATION, *PFILE_OBJECTID_INFORMATION;
-
-typedef struct _FILE_REPARSE_POINT_INFORMATION
-{
- LONGLONG FileReference;
- ULONG Tag;
-} FILE_REPARSE_POINT_INFORMATION, *PFILE_REPARSE_POINT_INFORMATION;
-
-// copied from ntstatus.h
-#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
-#define STATUS_BUFFER_OVERFLOW ((NTSTATUS)0x80000005L)
-#define STATUS_NO_MORE_FILES ((NTSTATUS)0x80000006L)
-#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
-#define STATUS_NO_SUCH_FILE ((NTSTATUS)0xC000000FL)
-
-#define SL_RESTART_SCAN 0x01
-#define SL_RETURN_SINGLE_ENTRY 0x02
-#define SL_INDEX_SPECIFIED 0x04
-#define SL_RETURN_ON_DISK_ENTRIES_ONLY 0x08
-
-#define SL_QUERY_DIRECTORY_MASK 0x0b
-
-typedef enum _FILE_INFORMATION_CLASS
-{
- FileDirectoryInformation = 1,
- FileFullDirectoryInformation = 2,
- FileBothDirectoryInformation = 3,
- FileStandardInformation = 5,
- FileNameInformation = 9,
- FileRenameInformation = 10,
- FileNamesInformation = 12,
- FileAllInformation = 18,
- FileObjectIdInformation = 29,
- FileReparsePointInformation = 33,
- FileIdBothDirectoryInformation = 37,
- FileIdFullDirectoryInformation = 38,
- FileNormalizedNameInformation = 48,
- FileIdExtdDirectoryInformation = 60,
- FileIdExtdBothDirectoryInformation = 63,
- FileId64ExtdDirectoryInformation = 78,
- FileId64ExtdBothDirectoryInformation = 79,
- FileIdAllExtdDirectoryInformation = 80,
- FileIdAllExtdBothDirectoryInformation = 81
-} FILE_INFORMATION_CLASS,
- *PFILE_INFORMATION_CLASS;
-
-typedef enum _MODE
-{
- KernelMode,
- UserMode,
- MaximumMode
-} MODE;
-
-typedef struct _IO_STATUS_BLOCK IO_STATUS_BLOCK;
-
-typedef struct _IO_STATUS_BLOCK* PIO_STATUS_BLOCK;
-// typedef VOID (NTAPI *PIO_APC_ROUTINE )(__in PVOID ApcContext, __in
-// PIO_STATUS_BLOCK IoStatusBlock, __in ULONG Reserved);
-typedef VOID(NTAPI* PIO_APC_ROUTINE)(PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock,
- ULONG Reserved);
-typedef enum _FILE_INFORMATION_CLASS FILE_INFORMATION_CLASS;
-
-typedef struct _UNICODE_STRING
-{
- USHORT Length;
- USHORT MaximumLength;
- PWSTR Buffer;
-} UNICODE_STRING, *PUNICODE_STRING;
-typedef const UNICODE_STRING* PCUNICODE_STRING;
-
-typedef struct _OBJECT_ATTRIBUTES
-{
- ULONG Length;
- HANDLE RootDirectory;
- PUNICODE_STRING ObjectName;
- ULONG Attributes;
- PVOID SecurityDescriptor;
- PVOID SecurityQualityOfService;
-} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
-
-typedef enum _POOL_TYPE
-{
- NonPagedPool,
- NonPagedPoolExecute = NonPagedPool,
- PagedPool,
- NonPagedPoolMustSucceed = NonPagedPool + 2,
- DontUseThisType,
- NonPagedPoolCacheAligned = NonPagedPool + 4,
- PagedPoolCacheAligned,
- NonPagedPoolCacheAlignedMustS = NonPagedPool + 6,
- MaxPoolType,
- NonPagedPoolBase = 0,
- NonPagedPoolBaseMustSucceed = NonPagedPoolBase + 2,
- NonPagedPoolBaseCacheAligned = NonPagedPoolBase + 4,
- NonPagedPoolBaseCacheAlignedMustS = NonPagedPoolBase + 6,
- NonPagedPoolSession = 32,
- PagedPoolSession = NonPagedPoolSession + 1,
- NonPagedPoolMustSucceedSession = PagedPoolSession + 1,
- DontUseThisTypeSession = NonPagedPoolMustSucceedSession + 1,
- NonPagedPoolCacheAlignedSession = DontUseThisTypeSession + 1,
- PagedPoolCacheAlignedSession = NonPagedPoolCacheAlignedSession + 1,
- NonPagedPoolCacheAlignedMustSSession = PagedPoolCacheAlignedSession + 1,
- NonPagedPoolNx = 512,
- NonPagedPoolNxCacheAligned = NonPagedPoolNx + 4,
- NonPagedPoolSessionNx = NonPagedPoolNx + 32
-} POOL_TYPE;
-
-typedef struct _OBJECT_TYPE_INITIALIZER
-{
- WORD Length;
- UCHAR ObjectTypeFlags;
- ULONG CaseInsensitive : 1;
- ULONG UnnamedObjectsOnly : 1;
- ULONG UseDefaultObject : 1;
- ULONG SecurityRequired : 1;
- ULONG MaintainHandleCount : 1;
- ULONG MaintainTypeList : 1;
- ULONG ObjectTypeCode;
- ULONG InvalidAttributes;
- GENERIC_MAPPING GenericMapping;
- ULONG ValidAccessMask;
- POOL_TYPE PoolType;
- ULONG DefaultPagedPoolCharge;
- ULONG DefaultNonPagedPoolCharge;
- PVOID DumpProcedure;
- LONG* OpenProcedure;
- PVOID CloseProcedure;
- PVOID DeleteProcedure;
- LONG* ParseProcedure;
- LONG* SecurityProcedure;
- LONG* QueryNameProcedure;
- UCHAR* OkayToCloseProcedure;
-} OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;
-
-typedef CCHAR KPROCESSOR_MODE;
-
-typedef struct _OBJECT_HANDLE_INFORMATION
-{
- ULONG HandleAttributes;
- ACCESS_MASK GrantedAccess;
-} OBJECT_HANDLE_INFORMATION, *POBJECT_HANDLE_INFORMATION;
-
-typedef struct _OBJECT_NAME_INFORMATION
-{
- UNICODE_STRING Name;
-} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
-
-typedef enum _OBJECT_INFORMATION_CLASS
-{
- ObjectBasicInformation = 0,
- ObjectNameInformation = 1,
- ObjectTypeInformation = 2
-} OBJECT_INFORMATION_CLASS;
-
-typedef struct _RTL_RELATIVE_NAME
-{
- UNICODE_STRING RelativeName;
- HANDLE ContainingDirectory;
- void* CurDirRef;
-} RTL_RELATIVE_NAME, *PRTL_RELATIVE_NAME;
-
-typedef struct _FILE_NETWORK_OPEN_INFORMATION
-{
- LARGE_INTEGER CreationTime;
- LARGE_INTEGER LastAccessTime;
- LARGE_INTEGER LastWriteTime;
- LARGE_INTEGER ChangeTime;
- LARGE_INTEGER AllocationSize;
- LARGE_INTEGER EndOfFile;
- ULONG FileAttributes;
-} FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION;
-
-#define FILE_DIRECTORY_FILE 0x00000001
-#define FILE_WRITE_THROUGH 0x00000002
-#define FILE_SEQUENTIAL_ONLY 0x00000004
-#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008
-#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010
-#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
-#define FILE_NON_DIRECTORY_FILE 0x00000040
-#define FILE_CREATE_TREE_CONNECTION 0x00000080
-#define FILE_COMPLETE_IF_OPLOCKED 0x00000100
-#define FILE_NO_EA_KNOWLEDGE 0x00000200
-#define FILE_OPEN_REMOTE_INSTANCE 0x00000400
-#define FILE_RANDOM_ACCESS 0x00000800
-#define FILE_DELETE_ON_CLOSE 0x00001000
-#define FILE_OPEN_BY_FILE_ID 0x00002000
-#define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000
-#define FILE_NO_COMPRESSION 0x00008000
-#define FILE_OPEN_REQUIRING_OPLOCK 0x00010000
-#define FILE_DISALLOW_EXCLUSIVE 0x00020000
-#define FILE_SESSION_AWARE 0x00040000
-#define FILE_RESERVE_OPFILTER 0x00100000
-#define FILE_OPEN_REPARSE_POINT 0x00200000
-#define FILE_OPEN_NO_RECALL 0x00400000
-#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000
-#define FILE_CONTAINS_EXTENDED_CREATE_INFORMATION 0x10000000
-
-// Nt
-
-using NtQueryDirectoryFile_type = NTSTATUS(WINAPI*)(HANDLE, HANDLE, PIO_APC_ROUTINE,
- PVOID, PIO_STATUS_BLOCK, PVOID,
- ULONG, FILE_INFORMATION_CLASS,
- BOOLEAN, PUNICODE_STRING, BOOLEAN);
-using NtQueryDirectoryFileEx_type = NTSTATUS(WINAPI*)(HANDLE, HANDLE, PIO_APC_ROUTINE,
- PVOID, PIO_STATUS_BLOCK, PVOID,
- ULONG, FILE_INFORMATION_CLASS,
- ULONG, PUNICODE_STRING);
-
-using NtQueryFullAttributesFile_type =
- NTSTATUS(WINAPI*)(POBJECT_ATTRIBUTES, PFILE_NETWORK_OPEN_INFORMATION);
-using NtQueryAttributesFile_type = NTSTATUS(WINAPI*)(POBJECT_ATTRIBUTES,
- PFILE_BASIC_INFORMATION);
-
-using NtQueryObject_type = NTSTATUS(WINAPI*)(
- HANDLE Handle, OBJECT_INFORMATION_CLASS ObjectInformationClass,
- PVOID ObjectInformation, ULONG ObjectInformationLength, PULONG ReturnLength);
-using NtQueryInformationFile_type = NTSTATUS(WINAPI*)(
- HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation,
- ULONG Length, FILE_INFORMATION_CLASS FileInformationClass);
-
-using NtQueryInformationByName_type = NTSTATUS(WINAPI*)(
- HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation,
- ULONG Length, FILE_INFORMATION_CLASS FileInformationClass);
-
-using NtOpenFile_type = NTSTATUS(WINAPI*)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
- PIO_STATUS_BLOCK, ULONG, ULONG);
-using NtCreateFile_type = NTSTATUS(WINAPI*)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
- PIO_STATUS_BLOCK, PLARGE_INTEGER, ULONG,
- ULONG, ULONG, ULONG, PVOID, ULONG);
-
-using NtClose_type = NTSTATUS(WINAPI*)(HANDLE);
-
-using NtTerminateProcess_type = NTSTATUS(WINAPI*)(HANDLE ProcessHandle,
- NTSTATUS ExitStatus);
-
-// Rtl
-
-using RtlDoesFileExists_U_type = NTSYSAPI BOOLEAN(NTAPI*)(PCWSTR);
-using RtlDosPathNameToRelativeNtPathName_U_WithStatus_type =
- NTSTATUS(NTAPI*)(PCWSTR DosFileName, PUNICODE_STRING NtFileName, PWSTR* FilePath,
- PRTL_RELATIVE_NAME RelativeName);
-using RtlReleaseRelativeName_type = void(NTAPI*)(PRTL_RELATIVE_NAME RelativeName);
-using RtlGetVersion_type = NTSTATUS(NTAPI*)(PRTL_OSVERSIONINFOW);
-
-extern NtQueryDirectoryFile_type NtQueryDirectoryFile;
-extern NtQueryDirectoryFileEx_type NtQueryDirectoryFileEx;
-extern NtQueryFullAttributesFile_type NtQueryFullAttributesFile;
-extern NtQueryAttributesFile_type NtQueryAttributesFile;
-extern NtQueryObject_type NtQueryObject;
-extern NtQueryInformationFile_type NtQueryInformationFile;
-extern NtQueryInformationByName_type NtQueryInformationByName;
-extern NtOpenFile_type NtOpenFile;
-extern NtCreateFile_type NtCreateFile;
-extern NtClose_type NtClose;
-extern NtTerminateProcess_type NtTerminateProcess;
-extern RtlDoesFileExists_U_type RtlDoesFileExists_U;
-extern RtlDosPathNameToRelativeNtPathName_U_WithStatus_type
- RtlDosPathNameToRelativeNtPathName_U_WithStatus;
-extern RtlReleaseRelativeName_type RtlReleaseRelativeName;
-extern RtlGetVersion_type RtlGetVersion;
-
-// ensures ntdll functions have been initialized (only needed during static objects
-// initialization)
-void ntdll_declarations_init();
-
-#pragma warning(pop)
diff --git a/libs/usvfs/src/shared/pch.cpp b/libs/usvfs/src/shared/pch.cpp
deleted file mode 100644
index 1d9f38c..0000000
--- a/libs/usvfs/src/shared/pch.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "pch.h"
diff --git a/libs/usvfs/src/shared/pch.h b/libs/usvfs/src/shared/pch.h
deleted file mode 100644
index e787f68..0000000
--- a/libs/usvfs/src/shared/pch.h
+++ /dev/null
@@ -1,87 +0,0 @@
-#pragma once
-
-#include <algorithm>
-#include <atomic>
-#include <bitset>
-#include <cassert>
-#include <codecvt>
-#include <cstddef>
-#include <cstdint>
-#include <cstring>
-#include <ctime>
-#include <exception>
-#include <format>
-#include <functional>
-#include <future>
-#include <iomanip>
-#include <ios>
-#include <limits>
-#include <map>
-#include <memory>
-#include <mutex>
-#include <regex>
-#include <shared_mutex>
-#include <sstream>
-#include <stdexcept>
-#include <string>
-#include <thread>
-#include <type_traits>
-#include <utility>
-#include <vector>
-
-#ifndef NOMINMAX
-#define NOMINMAX
-#endif
-
-// clang-format off
-#define WIN32_LEAN_AND_MEAN
-#include <Windows.h>
-#include <ShlObj.h>
-#include <comutil.h>
-#include <Psapi.h>
-#include <shellapi.h>
-#include <shlwapi.h>
-#include <fileapi.h>
-#include <DbgHelp.h>
-// clang-format on
-
-#define BOOST_INTERPROCESS_SEGMENT_MANAGER_ABI 1
-#include <boost/algorithm/string.hpp>
-#include <boost/algorithm/string/case_conv.hpp>
-#include <boost/any.hpp>
-#include <boost/container/flat_set.hpp>
-#include <boost/container/map.hpp>
-#include <boost/container/scoped_allocator.hpp>
-#include <boost/container/slist.hpp>
-#include <boost/container/string.hpp>
-#include <boost/container/vector.hpp>
-#include <boost/current_function.hpp>
-#include <boost/dll/runtime_symbol_info.hpp>
-#include <boost/filesystem.hpp>
-#include <boost/filesystem/detail/utf8_codecvt_facet.hpp>
-#include <boost/filesystem/operations.hpp>
-#include <boost/filesystem/path.hpp>
-#include <boost/format.hpp>
-#include <boost/interprocess/ipc/message_queue.hpp>
-#include <boost/interprocess/managed_windows_shared_memory.hpp>
-#include <boost/interprocess/offset_ptr.hpp>
-#include <boost/interprocess/smart_ptr/deleter.hpp>
-#include <boost/interprocess/smart_ptr/shared_ptr.hpp>
-#include <boost/interprocess/smart_ptr/weak_ptr.hpp>
-#include <boost/interprocess/sync/named_mutex.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/locale.hpp>
-#include <boost/multi_index/member.hpp>
-#include <boost/multi_index/ordered_index.hpp>
-#include <boost/multi_index_container.hpp>
-#include <boost/predef.h>
-#include <boost/static_assert.hpp>
-#include <boost/thread.hpp>
-#include <boost/thread/shared_lock_guard.hpp>
-#include <boost/thread/shared_mutex.hpp>
-#include <boost/tokenizer.hpp>
-#include <boost/type_traits.hpp>
-
-#include <spdlog/spdlog.h>
-
-namespace fs = boost::filesystem;
diff --git a/libs/usvfs/src/shared/shared_memory.h b/libs/usvfs/src/shared/shared_memory.h
deleted file mode 100644
index 28da34b..0000000
--- a/libs/usvfs/src/shared/shared_memory.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
-Userspace Virtual Filesystem
-
-Copyright (C) 2015 Sebastian Herbord. All rights reserved.
-
-This file is part of usvfs.
-
-usvfs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-usvfs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with usvfs. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#pragma once
-
-namespace bi = boost::interprocess;
-namespace bc = boost::container;
-
-namespace usvfs::shared
-{
-
-template <typename T>
-using OffsetPtrT = bi::offset_ptr<T, std::int32_t, std::uint64_t>;
-
-using VoidPointerT = OffsetPtrT<void>;
-
-// important: the windows shared memory mechanism, unlike other implementations,
-// automatically removes the SHM object when there are no more "subscribers".
-// MO currently depends on that feature!
-
-// managed_windows_shared_memory apparently doesn't support sharing between
-// 64bit and 32bit processes
-using managed_windows_shared_memory = bi::basic_managed_windows_shared_memory<
- char, bi::rbtree_best_fit<bi::mutex_family, VoidPointerT, 8>, bi::iset_index>;
-
-using SharedMemoryT = managed_windows_shared_memory;
-using SegmentManagerT = SharedMemoryT::segment_manager;
-
-using VoidAllocatorT = boost::container::scoped_allocator_adaptor<
- boost::interprocess::allocator<void, SegmentManagerT>>;
-using CharAllocatorT = VoidAllocatorT::rebind<char>::other;
-
-using StringT = bc::basic_string<char, std::char_traits<char>, CharAllocatorT>;
-
-} // namespace usvfs::shared
diff --git a/libs/usvfs/src/shared/shmlogger.cpp b/libs/usvfs/src/shared/shmlogger.cpp
deleted file mode 100644
index 66512de..0000000
--- a/libs/usvfs/src/shared/shmlogger.cpp
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
-Userspace Virtual Filesystem
-
-Copyright (C) 2015 Sebastian Herbord. All rights reserved.
-
-This file is part of usvfs.
-
-usvfs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-usvfs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with usvfs. If not, see <http://www.gnu.org/licenses/>.
-*/
-#pragma warning(disable : 4714)
-#pragma warning(disable : 4503)
-#pragma warning(push, 3)
-#include "shmlogger.h"
-#pragma warning(pop)
-
-#pragma warning(disable : 4996)
-
-using namespace boost::interprocess;
-using namespace boost::posix_time;
-
-SHMLogger* SHMLogger::s_Instance = nullptr;
-
-SHMLogger::owner_t SHMLogger::owner;
-SHMLogger::client_t SHMLogger::client;
-
-SHMLogger::SHMLogger(owner_t, const std::string& queueName)
- : m_QueueName(queueName),
- m_LogQueue(create_only, queueName.c_str(), MESSAGE_COUNT, MESSAGE_SIZE),
- m_DroppedMessages(0)
-{
- if (s_Instance != nullptr) {
- throw std::runtime_error("duplicate shm logger instantiation");
- } else {
- s_Instance = this;
- }
-}
-
-SHMLogger::SHMLogger(client_t, const std::string& queueName)
- : m_QueueName(queueName), m_LogQueue(open_only, queueName.c_str()),
- m_DroppedMessages(0)
-{
- if (s_Instance != nullptr) {
- throw std::runtime_error("duplicate shm logger instantiation");
- } else {
- s_Instance = this;
- }
-}
-
-SHMLogger::~SHMLogger()
-{
- s_Instance = nullptr;
- message_queue_interop::remove(m_QueueName.c_str());
-}
-
-SHMLogger& SHMLogger::create(const char* instanceName)
-{
- if (s_Instance != nullptr) {
- throw std::runtime_error("duplicate shm logger instantiation");
- } else {
- std::string queueName = std::string("__shm_sink_") + instanceName;
- message_queue::remove(queueName.c_str());
- new SHMLogger(owner, queueName);
- atexit([]() {
- delete s_Instance;
- });
- }
- return *s_Instance;
-}
-
-SHMLogger& SHMLogger::open(const char* instanceName)
-{
- if (s_Instance != nullptr) {
- throw std::runtime_error("duplicate shm logger instantiation");
- } else {
- new SHMLogger(client, std::string("__shm_sink_") + instanceName);
- }
- return *s_Instance;
-}
-
-void SHMLogger::free()
-{
- if (s_Instance != nullptr) {
- SHMLogger* temp = s_Instance;
- s_Instance = nullptr;
- delete temp;
- }
-}
-
-bool SHMLogger::tryGet(char* buffer, size_t bufferSize)
-{
- message_queue_interop::size_type receivedSize;
- unsigned int prio;
- bool res = m_LogQueue.try_receive(buffer, static_cast<unsigned int>(bufferSize),
- receivedSize, prio);
- if (res) {
- buffer[std::min(bufferSize - 1, static_cast<size_t>(receivedSize))] = '\0';
- }
- return res;
-}
-
-void SHMLogger::get(char* buffer, size_t bufferSize)
-{
- message_queue_interop::size_type receivedSize;
- unsigned int prio;
- m_LogQueue.receive(buffer, static_cast<unsigned int>(bufferSize), receivedSize, prio);
- buffer[std::min(bufferSize - 1, static_cast<size_t>(receivedSize))] = '\0';
-}
-
-usvfs::sinks::shm_sink::shm_sink(const char* queueName)
- : m_LogQueue(open_only, (std::string("__shm_sink_") + queueName).c_str()),
- m_DroppedMessages(0)
-{}
-
-void usvfs::sinks::shm_sink::flush_() {}
-
-void usvfs::sinks::shm_sink::sink_it_(const spdlog::details::log_msg& msg)
-{
- int droppedMessages = m_DroppedMessages.load(std::memory_order_relaxed);
- if (droppedMessages > 0) {
- auto dropMessage = std::format("{} debug messages dropped", droppedMessages);
- if (m_LogQueue.try_send(dropMessage.c_str(),
- static_cast<unsigned int>(dropMessage.size()), 0)) {
- m_DroppedMessages.store(0, std::memory_order_relaxed);
- }
- }
-
- std::string message{msg.payload};
-
- // blacklist %USERNAME% because PII
- static const std::string username = std::string(getenv("USERNAME"));
- boost::algorithm::ireplace_all(message, std::string("\\") + username, "\\USERNAME");
- boost::algorithm::ireplace_all(message, std::string("/") + username, "/USERNAME");
-
- if (message.length() > SHMLogger::MESSAGE_SIZE) {
- std::vector<std::string> splitVec;
- boost::split(splitVec, message, boost::is_any_of("\r\n"), boost::token_compress_on);
- for (const std::string& line : splitVec) {
- output(msg.level, line);
- }
- } else {
- output(msg.level, message);
- }
-}
-
-void usvfs::sinks::shm_sink::output(spdlog::level::level_enum lev,
- const std::string& message)
-{
- bool sent = true;
-
- // spdlog auto-append line breaks which we don't need. Probably would be
- // better to not write the breaks to begin with?
- size_t count = std::min(message.find_last_not_of("\r\n") + 1,
- static_cast<size_t>(m_LogQueue.get_max_msg_size()));
-
- // depending on the log level, drop less important messages if the receiver
- // can't keep up
- switch (lev) {
- case spdlog::level::trace:
- case spdlog::level::debug:
- case spdlog::level::info: {
- // m_LogQueue.send(message.c_str(), count, 0);
- sent = m_LogQueue.try_send(message.c_str(), static_cast<unsigned int>(count), 0);
- } break;
- case spdlog::level::err:
- case spdlog::level::critical: {
- m_LogQueue.send(message.c_str(), static_cast<unsigned int>(count), 0);
- } break;
- default: {
- boost::posix_time::ptime time =
- microsec_clock::universal_time() + boost::posix_time::milliseconds(200);
- sent = m_LogQueue.timed_send(message.c_str(), static_cast<unsigned int>(count), 0,
- time);
- } break;
- }
-
- if (!sent) {
- m_DroppedMessages.fetch_add(1, std::memory_order_relaxed);
- }
-}
-
-void __cdecl boost::interprocess::ipcdetail::get_shared_dir(std::string& shared_dir)
-{
- PWSTR path;
- if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_ProgramData, 0, NULL, &path))) {
- _bstr_t bPath(path);
- shared_dir = (char*)bPath;
- shared_dir += "\\USVFS";
- } else {
- shared_dir = "C:\\ProgramData\\USVFS";
- }
- boost::filesystem::path boostPath(shared_dir);
- if (!boost::filesystem::exists(boostPath))
- boost::filesystem::create_directories(boostPath);
-}
diff --git a/libs/usvfs/src/shared/shmlogger.h b/libs/usvfs/src/shared/shmlogger.h
deleted file mode 100644
index 158f941..0000000
--- a/libs/usvfs/src/shared/shmlogger.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
-Userspace Virtual Filesystem
-
-Copyright (C) 2015 Sebastian Herbord. All rights reserved.
-
-This file is part of usvfs.
-
-usvfs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-usvfs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with usvfs. If not, see <http://www.gnu.org/licenses/>.
-*/
-#pragma once
-
-#include <spdlog/details/null_mutex.h>
-#include <spdlog/sinks/base_sink.h>
-
-#include "logging.h"
-#include "shared_memory.h"
-#include "windows_sane.h"
-
-typedef boost::interprocess::message_queue_t<usvfs::shared::VoidPointerT>
- message_queue_interop;
-
-namespace usvfs::sinks
-{
-class shm_sink : public spdlog::sinks::base_sink<spdlog::details::null_mutex>
-{
-public:
- shm_sink(const char* queueName);
-
-protected:
- void sink_it_(const spdlog::details::log_msg& msg) override;
- void output(spdlog::level::level_enum lev, const std::string& message);
- void flush_() override;
-
-private:
- message_queue_interop m_LogQueue;
- std::atomic<int> m_DroppedMessages;
-};
-
-} // namespace usvfs::sinks
-
-class SHMLogger
-{
-public:
- static const size_t MESSAGE_COUNT = 1024;
- static const size_t MESSAGE_SIZE = 512;
-
- static SHMLogger& create(const char* instanceName);
- static SHMLogger& open(const char* instanceName);
- static void free();
-
- static bool isInstantiated() { return s_Instance != nullptr; }
-
- static inline SHMLogger& instance()
- {
- if (s_Instance == nullptr) {
- throw std::runtime_error("shm logger not instantiated");
- }
-
- return *s_Instance;
- }
-
- void log(LogLevel logLevel, const std::string& message);
- bool tryGet(char* buffer, size_t bufferSize);
- void get(char* buffer, size_t bufferSize);
-
-private:
- struct owner_t
- {};
- static owner_t owner;
-
- struct client_t
- {};
- static client_t client;
-
-private:
- SHMLogger(owner_t, const std::string& instanceName);
- SHMLogger(client_t, const std::string& instanceName);
-
- SHMLogger(const SHMLogger&) = delete;
- SHMLogger& operator=(const SHMLogger&) = delete;
-
- ~SHMLogger();
-
-private:
- static SHMLogger* s_Instance;
-
- message_queue_interop m_LogQueue;
-
- std::string m_SHMName;
- std::string m_LockName;
- std::string m_QueueName;
-
- std::atomic<int> m_DroppedMessages;
-};
diff --git a/libs/usvfs/src/shared/stringcast.cpp b/libs/usvfs/src/shared/stringcast.cpp
deleted file mode 100644
index 47822d5..0000000
--- a/libs/usvfs/src/shared/stringcast.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
-Userspace Virtual Filesystem
-
-Copyright (C) 2015 Sebastian Herbord. All rights reserved.
-
-This file is part of usvfs.
-
-usvfs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-usvfs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with usvfs. If not, see <http://www.gnu.org/licenses/>.
-*/
-#include "stringcast.h"
-
-namespace usvfs::shared
-{
-
-UINT windowsCP(CodePage codePage)
-{
- switch (codePage) {
- case CodePage::LOCAL:
- return CP_ACP;
- case CodePage::UTF8:
- return CP_UTF8;
- case CodePage::LATIN1:
- return 850;
- }
- // this should not be possible in practice
- throw std::runtime_error("unsupported codePage");
-}
-
-} // namespace usvfs::shared
diff --git a/libs/usvfs/src/shared/stringcast.h b/libs/usvfs/src/shared/stringcast.h
deleted file mode 100644
index 0ce56d1..0000000
--- a/libs/usvfs/src/shared/stringcast.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
-Userspace Virtual Filesystem
-
-Copyright (C) 2015 Sebastian Herbord. All rights reserved.
-
-This file is part of usvfs.
-
-usvfs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-usvfs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with usvfs. If not, see <http://www.gnu.org/licenses/>.
-*/
-#pragma once
-
-#include "exceptionex.h"
-
-namespace usvfs::shared
-{
-
-enum class CodePage
-{
- LOCAL,
- LATIN1,
- UTF8
-};
-
-template <typename ToT, typename FromT>
-class string_cast_impl
-{
-public:
- static ToT cast(const FromT& source, CodePage codePage, size_t sourceLength);
-};
-
-template <typename ToT, typename FromT>
-ToT string_cast(FromT source, CodePage codePage = CodePage::LOCAL,
- size_t sourceLength = std::numeric_limits<size_t>::max())
-{
- return string_cast_impl<ToT, FromT>::cast(source, codePage, sourceLength);
-}
-
-template <typename ToT, typename CharT>
-class string_cast_impl<ToT, std::basic_string<CharT>>
-{
-public:
- static ToT cast(const std::basic_string<CharT>& source, CodePage codePage,
- size_t sourceLength)
- {
- return string_cast_impl<ToT, const CharT*>::cast(source.c_str(), codePage,
- sourceLength);
- }
-};
-
-template <typename ToT, typename CharT>
-class string_cast_impl<ToT, CharT*>
-{
- BOOST_STATIC_ASSERT(!boost::is_base_and_derived<ToT, CharT>::value);
-
-public:
- static ToT cast(CharT* source, CodePage codePage, size_t sourceLength)
- {
- return string_cast_impl<ToT, const CharT*>::cast(source, codePage, sourceLength);
- }
-};
-
-template <typename ToT, typename CharT, int N>
-class string_cast_impl<ToT, CharT[N]>
-{
-public:
- static ToT cast(CharT (&source)[N], CodePage codePage, size_t sourceLength)
- {
- return string_cast_impl<ToT, const CharT*>::cast(source, codePage, sourceLength);
- }
-};
-
-UINT windowsCP(CodePage codePage);
-
-template <>
-class string_cast_impl<std::string, const wchar_t*>
-{
-public:
- static std::string cast(const wchar_t* const& source, CodePage codePage,
- size_t sourceLength)
- {
- std::string result;
-
- if (sourceLength == std::numeric_limits<size_t>::max()) {
- sourceLength = wcslen(source);
- }
-
- if (sourceLength > 0) {
- // use utf8 or local 8-bit encoding depending on user choice
- UINT cp = windowsCP(codePage);
- // preflight to find out the required buffer size
- int outLength = WideCharToMultiByte(cp, 0, source, static_cast<int>(sourceLength),
- nullptr, 0, nullptr, nullptr);
- if (outLength == 0) {
- throw windows_error("string conversion failed");
- }
- result.resize(outLength);
- outLength = WideCharToMultiByte(cp, 0, source, static_cast<int>(sourceLength),
- &result[0], outLength, nullptr, nullptr);
- if (outLength == 0) {
- throw windows_error("string conversion failed");
- }
- // fix output string length (i.e. in case of unconvertible characters
- while (result[outLength - 1] == L'\0') {
- result.resize(--outLength);
- }
- }
-
- return result;
- }
-};
-
-template <>
-class string_cast_impl<std::wstring, const char*>
-{
-public:
- static std::wstring cast(const char* const& source, CodePage codePage,
- size_t sourceLength)
- {
- std::wstring result;
-
- if (sourceLength == std::numeric_limits<size_t>::max()) {
- sourceLength = strlen(source);
- }
-
- if (sourceLength > 0) {
- // use utf8 or local 8-bit encoding depending on user choice
- UINT cp = windowsCP(codePage);
- // preflight to find out the required source size
- int outLength = MultiByteToWideChar(cp, 0, source, static_cast<int>(sourceLength),
- &result[0], 0);
- if (outLength == 0) {
- throw windows_error("string conversion failed");
- }
- result.resize(outLength);
- outLength = MultiByteToWideChar(cp, 0, source, static_cast<int>(sourceLength),
- &result[0], outLength);
- if (outLength == 0) {
- throw windows_error("string conversion failed");
- }
- while (result[outLength - 1] == L'\0') {
- result.resize(--outLength);
- }
- }
-
- return result;
- }
-};
-
-template <>
-class string_cast_impl<std::wstring, const wchar_t*>
-{
-public:
- static std::wstring cast(const wchar_t* const& source, CodePage, size_t)
- {
- return std::wstring(source);
- }
-};
-
-} // namespace usvfs::shared
diff --git a/libs/usvfs/src/shared/stringutils.cpp b/libs/usvfs/src/shared/stringutils.cpp
deleted file mode 100644
index 2ddbf64..0000000
--- a/libs/usvfs/src/shared/stringutils.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
-Userspace Virtual Filesystem
-
-Copyright (C) 2015 Sebastian Herbord. All rights reserved.
-
-This file is part of usvfs.
-
-usvfs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-usvfs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with usvfs. If not, see <http://www.gnu.org/licenses/>.
-*/
-#include "stringutils.h"
-#include "windows_sane.h"
-
-namespace usvfs::shared
-{
-
-void strncpy_sz(char* dest, const char* src, size_t destSize)
-{
- if (destSize > 0) {
- strncpy(dest, src, destSize - 1);
- dest[destSize - 1] = '\0';
- }
-}
-
-void wcsncpy_sz(wchar_t* dest, const wchar_t* src, size_t destSize)
-{
- if ((destSize > 0) && (dest != nullptr)) {
- wcsncpy(dest, src, destSize - 1);
- dest[destSize - 1] = L'\0';
- }
-}
-
-bool startswith(const wchar_t* string, const wchar_t* subString)
-{
- while ((*string != '\0') && (*subString != '\0')) {
- if (towlower(*string) != towlower(*subString)) {
- return false;
- }
- ++string;
- ++subString;
- }
-
- return *subString == '\0';
-}
-
-static fs::path normalize(const fs::path& path)
-{
- fs::path result;
-
- boost::locale::generator gen;
- auto loc = gen("en_US.UTF-8");
- for (fs::path::iterator iter = path.begin(); iter != path.end(); ++iter) {
- if (*iter == "..") {
- result = result.parent_path();
- } else if (*iter != ".") {
- result /= boost::to_lower_copy(iter->string(), loc);
- } // single dot is ignored
- }
- return result;
-}
-
-fs::path make_relative(const fs::path& fromIn, const fs::path& toIn)
-{
- // converting path to lower case to make iterator comparison work correctly
- // on case-insenstive filesystems
- fs::path from(fs::absolute(fromIn));
- fs::path to(fs::absolute(toIn));
-
- // find common base
- fs::path::const_iterator fromIter(from.begin());
- fs::path::const_iterator toIter(to.begin());
-
- // TODO the following equivalent test is probably quite expensive as new
- // paths are created for each iteration but the case sensitivity depends on
- // the fs
- while ((fromIter != from.end()) && (toIter != to.end()) &&
- (boost::iequals(fromIter->string(), toIter->string()))) {
- ++fromIter;
- ++toIter;
- }
-
- // Navigate backwards in directory to reach previously found base
- fs::path result;
- for (; fromIter != from.end(); ++fromIter) {
- if (*fromIter != ".") {
- result /= "..";
- }
- }
-
- // Now navigate down the directory branch
- for (; toIter != to.end(); ++toIter) {
- result /= *toIter;
- }
- return result;
-}
-
-std::string to_hex(void* bufferIn, size_t bufferSize)
-{
- unsigned char* buffer = static_cast<unsigned char*>(bufferIn);
- std::ostringstream temp;
- temp << std::hex;
- for (size_t i = 0; i < bufferSize; ++i) {
- temp << std::setfill('0') << std::setw(2) << (unsigned int)buffer[i];
- if ((i % 16) == 15) {
- temp << "\n";
- } else {
- temp << " ";
- }
- }
- return temp.str();
-}
-
-std::wstring to_upper(const std::wstring& input)
-{
- std::wstring result;
- result.resize(input.size());
- ::LCMapStringW(LOCALE_INVARIANT, LCMAP_UPPERCASE, input.c_str(),
- static_cast<int>(input.size()), &result[0],
- static_cast<int>(result.size()));
- return result;
-}
-
-std::string byte_string(std::size_t n)
-{
- auto s = std::to_string(n);
- auto p = s.size();
-
- while (p > 3) {
- p -= 3;
- s.insert(p, 1, ',');
- }
-
- return s + " B";
-}
-
-} // namespace usvfs::shared
diff --git a/libs/usvfs/src/shared/stringutils.h b/libs/usvfs/src/shared/stringutils.h
deleted file mode 100644
index 64d0af7..0000000
--- a/libs/usvfs/src/shared/stringutils.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-Userspace Virtual Filesystem
-
-Copyright (C) 2015 Sebastian Herbord. All rights reserved.
-
-This file is part of usvfs.
-
-usvfs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-usvfs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with usvfs. If not, see <http://www.gnu.org/licenses/>.
-*/
-#pragma once
-
-namespace usvfs::shared
-{
-
-void strncpy_sz(char* dest, const char* src, size_t destSize);
-void wcsncpy_sz(wchar_t* dest, const wchar_t* src, size_t destSize);
-
-bool startswith(const wchar_t* string, const wchar_t* subString);
-
-// Return path when appended to a_From will resolve to same as a_To
-fs::path make_relative(const fs::path& from, const fs::path& to);
-
-std::string to_hex(void* bufferIn, size_t bufferSize);
-
-// convert unicode string to upper-case (locale invariant)
-std::wstring to_upper(const std::wstring& input);
-
-// formats a number with thousand separators and B at the end
-//
-std::string byte_string(std::size_t n);
-
-class FormatGuard
-{
- std::ostream& m_Stream;
- std::ios::fmtflags m_Flags;
-
-public:
- FormatGuard(std::ostream& stream) : m_Stream(stream), m_Flags(stream.flags()) {}
-
- ~FormatGuard() { m_Stream.flags(m_Flags); }
-
- FormatGuard(const FormatGuard&) = delete;
- FormatGuard& operator=(FormatGuard&) = delete;
-};
-
-} // namespace usvfs::shared
diff --git a/libs/usvfs/src/shared/tree_container.h b/libs/usvfs/src/shared/tree_container.h
deleted file mode 100644
index a2f61fa..0000000
--- a/libs/usvfs/src/shared/tree_container.h
+++ /dev/null
@@ -1,630 +0,0 @@
-#pragma once
-
-#include "directory_tree.h"
-#include "shared_memory.h"
-
-namespace usvfs::shared
-{
-
-// smart pointer to DirectoryTrees (only intended for top-level nodes). This
-// will transparently switch to new shared memory regions in case they get
-// reallocated
-//
-//
-// reassign() is called from a variety of places when the current chunk of
-// shared memory is full or is marked as being outdated; its job is to either
-// find another chunk that may have been created by another process or to create
-// a brand new one
-//
-//
-// if there is only a single process hooked, it will slowly fill up the shared
-// memory when adding files, eventually throw a bi::bad_alloc and end up in
-// reassign(); a new block will be allocated, the data copied over, and the old
-// block will be deallocated
-//
-//
-// when multiple processes are involved, things are more complicated
-//
-// two processes A and B will start by using the same shared memory, but they
-// have their own pointer to it that's local to the process (the `m_TreeMeta`
-// member variable)
-//
-// so when process A fills up the shared memory and reallocates it, process B
-// is still pointing to the old shared memory; only when process B does some
-// operation that accesses the file tree will the pointer be checked and
-// adjusted to point to the new shared memory
-//
-// in this example, when process A ran out of memory, it set `outdated` to
-// `true` in the shared memory block, allocated a new one and copied the data
-// over, but it did not deallocate the block because process B is still
-// pointing to it
-//
-// when process B tries to access the block, it checks `outdated` (see get());
-// if it's true, it means that it's pointing to an outdated shared memory block
-// and must find the new one that process A created
-//
-// the new block is not necessarily the very next name, it is possible for
-// process A to burn through a series of blocks quickly when adding a bunch of
-// new files, and these blocks will all have been deallocated by the time
-// process B tries to find the newest one
-//
-// so when a process sees its block as outdated, it will try to open a bunch of
-// names until one exists that is not outdated; if it can't find the block
-// (shouldn't happen), it will just create a new one
-//
-template <typename TreeT>
-class TreeContainer
-{
-public:
- /**
- * @brief Constructor
- * @param SHMName name of the shared memory holding the tree. This should contain the
- * running number
- * @param size initial size in bytes of the container. since the tree is resized by
- * doubling this should be a power of two. 64k is supposed to be the page size on
- * windows so smaller allocations make little sense
- * @note size can't be too small. If initial allocations fail automatic growing won't
- * work
- */
- TreeContainer(const std::string& SHMName, size_t size = 64 * 1024)
- : m_TreeMeta(nullptr), m_SHMName(SHMName)
- {
- std::locale global_loc = std::locale();
- std::locale loc(global_loc, new fs::detail::utf8_codecvt_facet);
- fs::path::imbue(loc);
-
- // append _1 to the name if it doesn't end with _N already
- std::regex pattern(R"exp((.*_)(\d+))exp");
- std::smatch match;
- std::string shmName(m_SHMName.c_str());
- regex_match(shmName, match, pattern);
-
- if (match.size() != 3) {
- m_SHMName += "_1";
- }
-
- // creates a new memory block if this is the first process to run or attach
- // to an already existing one
- createOrOpen(m_SHMName, size);
-
- spdlog::get("usvfs")->info("attached to {0} with {1} nodes, size {2}", m_SHMName,
- m_TreeMeta->tree->numNodesRecursive(),
- byte_string(m_SHM->get_size()));
- }
-
- TreeContainer(const TreeContainer&) = delete;
- TreeContainer& operator=(const TreeContainer&) = delete;
-
- ~TreeContainer()
- {
- if (unassign(m_SHM, m_TreeMeta)) {
- bi::shared_memory_object::remove(m_SHMName.c_str());
- }
- }
-
- /**
- * @return retrieve an allocator that can be used to create objects in this tree
- */
- VoidAllocatorT allocator() { return VoidAllocatorT(m_SHM->get_segment_manager()); }
-
- template <typename... Arguments>
- typename TreeT::DataT create(Arguments&&... args)
- {
- return TreeT::DataT(std::forward<Arguments>(args)..., allocator());
- }
-
- TreeT* operator->() { return get(); }
-
- /**
- * @return raw pointer to the managed tree
- */
- TreeT* get()
- {
- if (m_TreeMeta->outdated) {
- reassign();
- }
-
- return m_TreeMeta->tree.get();
- }
-
- /**
- * @return raw const pointer to the managed tree
- */
- const TreeT* get() const
- {
- if (m_TreeMeta->outdated) {
- // safe const_cast, TreeContainer are never created const
- const_cast<TreeContainer<TreeT>*>(this)->reassign();
- }
-
- return m_TreeMeta->tree.get();
- }
-
- const TreeT* operator->() const { return get(); }
-
- /**
- * @return current name of the managed shared memory
- */
- std::string shmName() const { return m_SHMName; }
-
- void clear() { m_TreeMeta->tree->clear(); }
-
- /**
- * @brief add a new file to the tree
- *
- * @param name name of the file, expected to be relative to this directory
- * @param data the file data to attach
- * @param flags flags for this files
- * @param overwrite if true, the new leaf will overwrite an existing one that compares
- *as "equal"
- * @return pointer to the new node or a null ptr
- **/
- template <typename T>
- typename TreeT::NodePtrT addFile(const fs::path& name, const T& data,
- TreeFlags flags = 0, bool overwrite = true)
- {
- for (;;) {
- DecomposablePath dp(name.string());
-
- try {
- return addNode(m_TreeMeta->tree.get(), dp, data, overwrite, flags, allocator());
- } catch (const bi::bad_alloc&) {
- }
-
- reassign();
- }
- }
-
- /**
- * @brief add a new directory to the tree
- *
- * @param name name of the file, expected to be relative to this directory
- * @param data the file data to attach
- * @param flags flags for this files
- * @param overwrite if true, the new leaf will overwrite an existing one that compares
- *as "equal"
- * @return pointer to the new node or a null ptr
- **/
- template <typename T>
- typename TreeT::NodePtrT addDirectory(const fs::path& name, const T& data,
- TreeFlags flags = 0, bool overwrite = true)
- {
- for (;;) {
- DecomposablePath dp(name.string());
-
- try {
- return addNode(m_TreeMeta->tree.get(), dp, data, overwrite,
- flags | FLAG_DIRECTORY, allocator());
- } catch (const bi::bad_alloc&) {
- }
-
- reassign();
- }
- }
-
- void getBuffer(void*& buffer, size_t& bufferSize) const
- {
- buffer = m_SHM->get_address();
- bufferSize = m_SHM->get_size();
- }
-
-private:
- struct TreeMeta
- {
- TreeMeta(const typename TreeT::DataT& data, SegmentManagerT* segmentManager)
- : tree(segmentManager->construct<TreeT>(bi::anonymous_instance)(
- "", true, TreeT::NodePtrT(), data, VoidAllocatorT(segmentManager))),
- referenceCount(0), // reference count only set on top level node
- outdated(false)
- {}
-
- OffsetPtrT<TreeT> tree;
- long referenceCount;
- bool outdated;
- bi::interprocess_mutex mutex;
- };
-
- std::string m_SHMName;
- std::shared_ptr<SharedMemoryT> m_SHM;
- TreeMeta* m_TreeMeta;
-
- typename TreeT::DataT createEmpty()
- {
- return createDataEmpty<typename TreeT::DataT>(allocator());
- }
-
- template <typename T>
- TreeT* createSubNode(const VoidAllocatorT& allocator, std::string_view name,
- unsigned long flags, const T& data)
- {
- auto* manager = allocator.get_segment_manager();
-
- return manager->construct<TreeT>(bi::anonymous_instance)(
- name, flags, TreeT::NodePtrT(),
- createData<typename TreeT::DataT, T>(data, allocator), manager);
- }
-
- typename TreeT::NodePtrT createSubPtr(TreeT* subNode)
- {
- SharedMemoryT::segment_manager* manager = m_SHM->get_segment_manager();
- return TreeT::NodePtrT(subNode, allocator(), TreeT::DeleterT(manager));
- }
-
- template <typename T>
- typename TreeT::NodePtrT addNode(TreeT* base, DecomposablePath& path, const T& data,
- bool overwrite, unsigned int flags,
- const VoidAllocatorT& allocator)
- {
- if (!path.peekNext()) {
- typename TreeT::NodePtrT newNode = base->node(path.current());
-
- if (!newNode) {
- // last name component, should be the filename
- TreeT* node = createSubNode(allocator, path.current(), flags, data);
- newNode = createSubPtr(node);
- newNode->m_Self = TreeT::WeakPtrT(newNode);
- newNode->m_Parent = base->m_Self;
- base->set(StringT(path.current(), allocator), newNode);
- return newNode;
- } else if (overwrite) {
- newNode->m_Data = createData<typename TreeT::DataT, T>(data, allocator);
- newNode->m_Flags = static_cast<usvfs::shared::TreeFlags>(flags);
- return newNode;
- } else {
- // the node is already in the tree, overwrite is false, nothing to do
- return {};
- }
- } else {
- // not last component, continue search in child node
- auto subNode = base->m_Nodes.find(path.current());
-
- if (subNode == base->m_Nodes.end()) {
- typename TreeT::NodePtrT newNode = createSubPtr(createSubNode(
- allocator, path.current(), FLAG_DIRECTORY | FLAG_DUMMY, createEmpty()));
-
- subNode =
- base->m_Nodes.emplace(StringT(path.current(), allocator), newNode).first;
- subNode->second->m_Self = TreeT::WeakPtrT(subNode->second);
- subNode->second->m_Parent = base->m_Self;
- }
-
- path.next();
-
- return addNode(subNode->second.get().get(), path, data, overwrite, flags,
- allocator);
- }
- }
-
- /**
- * @brief copy content of one tree to a different tree (in a different shared memory
- * segment
- * @param destination
- * @param reference
- * @note at the time this is called, destination needs to refer to the shm of
- * "destination" so that objects can be allocated in the new tree
- */
- void copyTree(TreeT* destination, const TreeT* reference)
- {
- VoidAllocatorT allocator = VoidAllocatorT(m_SHM->get_segment_manager());
- destination->m_Flags = reference->m_Flags;
- dataAssign(destination->m_Data, reference->m_Data);
- destination->m_Name.assign(reference->m_Name.c_str());
-
- for (const auto& kv : reference->m_Nodes) {
- TreeT* newNode = createSubNode(allocator, "", true, createEmpty());
- typename TreeT::NodePtrT newNodePtr = createSubPtr(newNode);
-
- // need to set self BEFORE recursively copying the subtree, otherwise
- // how would we assign parent pointers?
- newNode->m_Self = newNodePtr;
-
- TreeT* source = reinterpret_cast<TreeT*>(kv.second.get().get());
- copyTree(newNode, source);
- destination->set(newNode->m_Name, newNodePtr);
- newNode->m_Parent = destination->m_Self;
- }
- }
-
- int increaseRefCount(TreeMeta* treeMeta)
- {
- bi::scoped_lock<bi::interprocess_mutex> lock(treeMeta->mutex);
- return ++treeMeta->referenceCount;
- }
-
- int decreaseRefCount(TreeMeta* treeMeta)
- {
- bi::scoped_lock<bi::interprocess_mutex> lock(treeMeta->mutex);
- return --treeMeta->referenceCount;
- }
-
- // see activateSHM() for return value
- //
- std::optional<std::string> createOrOpen(const std::string& SHMName, size_t size)
- {
- SharedMemoryT* newSHM = openSHM(SHMName);
-
- if (newSHM) {
- spdlog::get("usvfs")->info("{} opened in process {}", SHMName,
- ::GetCurrentProcessId());
- } else {
- newSHM = createSHM(SHMName, size);
-
- if (newSHM) {
- spdlog::get("usvfs")->info("{} created in process {}", SHMName,
- ::GetCurrentProcessId());
- }
- }
-
- if (!newSHM) {
- spdlog::get("usvfs")->error("failed to create or open {} in process {}", SHMName,
- ::GetCurrentProcessId());
-
- throw std::exception("no shm instance");
- }
-
- return activateSHM(newSHM, SHMName);
- }
-
- // see activateSHM() for return value
- //
- SharedMemoryT* createSHM(const std::string& SHMName, size_t size)
- {
- try {
- return new SharedMemoryT(bi::create_only, SHMName.c_str(),
- static_cast<unsigned int>(size));
- } catch (const bi::interprocess_exception&) {
- }
-
- return nullptr;
- }
-
- // see activateSHM() for return value
- //
- SharedMemoryT* openSHM(const std::string& SHMName)
- {
- try {
- return new SharedMemoryT(bi::open_only, SHMName.c_str());
- } catch (const bi::interprocess_exception&) {
- }
-
- return nullptr;
- }
-
- // makes the given shm current, returns the name of the previous shm block
- // if it is now unused and must be destroyed; if the block is still used by
- // another process, returns empty
- //
- // see reassign()
- //
- std::optional<std::string> activateSHM(SharedMemoryT* shm, const std::string& SHMName)
- {
- std::shared_ptr<SharedMemoryT> oldSHM = m_SHM;
-
- m_SHM.reset(shm);
- std::pair<TreeMeta*, SharedMemoryT::size_type> res = m_SHM->find<TreeMeta>("Meta");
-
- if (res.first == nullptr) {
- res.first = m_SHM->construct<TreeMeta>("Meta")(createEmpty(),
- m_SHM->get_segment_manager());
- if (res.first == nullptr) {
- USVFS_THROW_EXCEPTION(bi::bad_alloc());
- }
- if (m_TreeMeta != nullptr) {
- copyTree(res.first->tree.get(), m_TreeMeta->tree.get());
- }
- }
-
- increaseRefCount(res.first);
-
- std::optional<std::string> deadSHMName;
-
- if (oldSHM.get() != nullptr) {
- const bool lastUser = unassign(oldSHM, m_TreeMeta);
- if (lastUser) {
- deadSHMName = m_SHMName;
- }
- }
-
- m_TreeMeta = res.first;
- m_SHMName = SHMName;
-
- return deadSHMName;
- }
-
- static std::string followupName(const std::string& currentName)
- {
- std::regex pattern(R"exp((.*_)(\d+))exp");
- std::smatch match;
- regex_match(currentName, match, pattern);
-
- if (match.size() != 3) {
- USVFS_THROW_EXCEPTION(usage_error() << ex_msg("shared memory name invalid"));
- }
-
- const int count = boost::lexical_cast<int>(match[2]);
- return match[1].str() + std::to_string(count + 1);
- }
-
- bool unassign(const std::shared_ptr<SharedMemoryT>& shm, TreeMeta* tree)
- {
- if (tree == nullptr) {
- return true;
- }
-
- if (decreaseRefCount(tree) == 0) {
- shm->get_segment_manager()->destroy_ptr(tree);
- return true;
- } else {
- return false;
- }
- }
-
- // re-entrancy: every time a process switches to a new shared memory block, it
- // will know whether it was the last process to have a handle to it; when that
- // happens, the block will be destroyed to avoid leaking it
- //
- // destroying these blocks is somewhat dangerous: it ends up in boost, which
- // will try to access the filesystem to see if the name of the shared memory
- // corresponds to a file on the drive, which can call hooked functions and end
- // up right back here
- //
- // (note that in usvfs, only the shared memory for the log file uses a real
- // file on the filesystem, see shmlogger.cpp; all the tree stuff uses
- // anonymous, memory mapped files that live in the Windows pagefile)
- //
- // so the old blocks can be destroyed, but only after all the shenanigans with
- // finding the correct shared memory block are over and `m_TreeMeta` points to
- // a valid block, so all the names of the dead shared memory blocks are kept
- // in a vector and deallocated at the very end
- //
- void reassign()
- {
- // list of all the shared memory blocks that are now unused and can be
- // destroyed
- std::vector<std::string> deadSHMNames;
-
- if (m_TreeMeta->outdated) {
- // this block was marked as outdated, which should only happen when
- // another process has ran out of memory and started allocating blocks
- // with higher numbers
-
- spdlog::get("usvfs")->info("tree {0} is outdated, looking for another one",
- m_SHMName);
-
- if (findNewerBlock(deadSHMNames)) {
- // the new block was found and activated
- return;
- }
- } else {
- // this block isn't outdated, so reassign() was called because a bad_alloc
- // exception was thrown
- spdlog::get("usvfs")->info(
- "ran out of memory in tree {0}, will create another one", m_SHMName);
- }
-
- // either the block is full or it's outdated, but no higher block was found;
- // just create a new one
-
- createNewBlock(deadSHMNames);
-
- // remove the old shared memory blocks; this can be recursive and call
- // reassign() again, but it's safe at this point
- for (const std::string& name : deadSHMNames) {
- spdlog::get("usvfs")->info("destroying {0}", name);
- bi::shared_memory_object::remove(name.c_str());
- }
- }
-
- // tries a series of shm names above the current one in the hope of finding
- // the most recent one
- //
- // if the new block was found and activated correctly, returns true
- //
- // when findNewerBlock() returns false, this container will either still be
- // pointing to the same, outdated block as it started with, or it might have
- // moved up to another outdated block, but it will always be pointing to
- // a valid block in memory
- //
- bool findNewerBlock(std::vector<std::string>& deadSHMNames)
- {
- // how many blocks are checked above the current one; it's unlikely there
- // will ever be more than 15 to 20 blocks allocated, but this is high
- // because it's really the only way to keep processes connected to the same
- // shm block, so processes must not fail to find the next one
- constexpr int Tries = 100;
-
- std::string nextName = m_SHMName;
-
- for (int i = 0; i < Tries; ++i) {
- // the shm name is something like "mod_organizer_3", which becomes
- // "mod_organizer_4"
- nextName = followupName(nextName);
- spdlog::get("usvfs")->info("opening {0}", nextName);
-
- // open the shm, see if it exists
- SharedMemoryT* shm = openSHM(nextName);
-
- if (!shm) {
- // this is not necessarily an error, another process might have created
- // a bunch of blocks and destroyed them before this process had a chance
- // to see them, so just keep going
- spdlog::get("usvfs")->info("{0} doesn't exist", nextName);
- continue;
- }
-
- spdlog::get("usvfs")->info("{0} exists, activating", nextName);
- const auto deadSHMName = activateSHM(shm, nextName);
-
- // if this process was the last user of the previous block, it must be
- // deallocated, but only after this whole thing is finished, because it
- // can end up calling reassign() again
- if (deadSHMName) {
- spdlog::get("usvfs")->info("will destroy {0}", *deadSHMName);
- deadSHMNames.push_back(*deadSHMName);
- }
-
- // another process might have already created this block, run out of
- // memory and created more, so make sure to only stop when finding a block
- // that's not outdated
- if (m_TreeMeta->outdated) {
- spdlog::get("usvfs")->info("{0} is also outdated", nextName);
- } else {
- // shm opened correctly, activated and not outdated, done
- spdlog::get("usvfs")->info("{0} not outdated, taking it, size now {1}",
- nextName, byte_string(m_SHM->get_size()));
-
- return true;
- }
- }
-
- // this block is outdated, but no other valid block was found above; this
- // shouldn't happen, but just create a new block to make sure programs can
- // still run
-
- spdlog::get("usvfs")->error(
- "found no existing tree above {0}, will create a new one", m_SHMName);
-
- return false;
- }
-
- // creates a new block and activates it, throws on failure
- //
- void createNewBlock(std::vector<std::string>& deadSHMNames)
- {
- // the current block is now considered stale, so make sure other processes
- // are aware of it and try to find the new block
- //
- // todo: there really should be some synchronization here, another process
- // can pick up this flag before the next block has been created
- m_TreeMeta->outdated = true;
-
- // the shm name is something like "mod_organizer_3", which becomes
- // "mod_organizer_4"
- const std::string nextName = followupName(m_SHMName);
- spdlog::get("usvfs")->info("creating {0}", nextName);
-
- SharedMemoryT* shm = createSHM(nextName, m_SHM->get_size() * 2);
-
- if (!shm) {
- // this shouldn't happen
- spdlog::get("usvfs")->error("failed to create {0}", nextName);
- throw std::exception("cannot create block");
- }
-
- spdlog::get("usvfs")->info("{0} created, activating", nextName);
- const auto deadSHMName = activateSHM(shm, nextName);
-
- // if this process was the last user of the previous block, it must be
- // deallocated, but only after this whole thing is finished, because it
- // can end up calling reassign() again
- if (deadSHMName) {
- spdlog::get("usvfs")->info("will destroy {0}", *deadSHMName);
- deadSHMNames.push_back(*deadSHMName);
- }
-
- spdlog::get("usvfs")->info("tree {0} size now {1}", m_SHMName,
- byte_string(m_SHM->get_size()));
- }
-};
-
-} // namespace usvfs::shared
diff --git a/libs/usvfs/src/shared/unicodestring.cpp b/libs/usvfs/src/shared/unicodestring.cpp
deleted file mode 100644
index f997e7f..0000000
--- a/libs/usvfs/src/shared/unicodestring.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
-Userspace Virtual Filesystem
-
-Copyright (C) 2015 Sebastian Herbord. All rights reserved.
-
-This file is part of usvfs.
-
-usvfs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-usvfs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with usvfs. If not, see <http://www.gnu.org/licenses/>.
-*/
-#include "unicodestring.h"
-#include "logging.h"
-#include "stringcast.h"
-#include "stringutils.h"
-
-namespace usvfs
-{
-
-UnicodeString::UnicodeString(LPCWSTR string, size_t length)
-{
- if (length == std::string::npos) {
- length = wcslen(string);
- }
- m_Buffer.resize(length + 1);
- memcpy(m_Buffer.data(), string, length * sizeof(wchar_t));
- update();
-}
-
-UnicodeString::UnicodeString(const std::wstring& string)
-{
- m_Buffer.resize(string.length() + 1);
- memcpy(m_Buffer.data(), string.data(), string.length() * sizeof(wchar_t));
- update();
-}
-
-UnicodeString& UnicodeString::operator=(const std::wstring& string)
-{
- m_Buffer.resize(string.length() + 1);
- memcpy(m_Buffer.data(), string.data(), string.length() * sizeof(wchar_t));
- update();
- return *this;
-}
-
-UnicodeString& UnicodeString::appendPath(PUNICODE_STRING path)
-{
- if (path != nullptr && path->Buffer && path->Length) {
- auto appendAt = size();
- if (appendAt) {
- m_Buffer.resize(m_Buffer.size() + path->Length / sizeof(WCHAR) + 1);
- m_Buffer[appendAt++] = L'\\';
- } else
- m_Buffer.resize(path->Length / sizeof(WCHAR) + 1);
- memcpy(&m_Buffer[appendAt], path->Buffer, path->Length);
- update();
- }
-
- return *this;
-}
-
-void UnicodeString::update()
-{
- m_Data.Length = static_cast<USHORT>(size() * sizeof(WCHAR));
- m_Data.MaximumLength = static_cast<USHORT>((m_Buffer.capacity() - 1) * sizeof(WCHAR));
- m_Data.Buffer = m_Buffer.data();
-}
-
-} // namespace usvfs
diff --git a/libs/usvfs/src/shared/unicodestring.h b/libs/usvfs/src/shared/unicodestring.h
deleted file mode 100644
index 77071ad..0000000
--- a/libs/usvfs/src/shared/unicodestring.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
-Userspace Virtual Filesystem
-
-Copyright (C) 2015 Sebastian Herbord. All rights reserved.
-
-This file is part of usvfs.
-
-usvfs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-usvfs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with usvfs. If not, see <http://www.gnu.org/licenses/>.
-*/
-#pragma once
-
-#include "ntdll_declarations.h"
-#include "windows_sane.h"
-
-#include "formatters.h"
-
-namespace usvfs
-{
-
-/**
- * @brief C++ wrapper for the windows UNICODE_STRING structure
- */
-class UnicodeString
-{
-public:
- UnicodeString() : m_Buffer(1) { update(); }
-
- UnicodeString(const UnicodeString& other) : m_Buffer(other.m_Buffer) { update(); }
-
- UnicodeString(UnicodeString&& other) : m_Buffer(std::move(other.m_Buffer))
- {
- update();
- }
-
- UnicodeString(const std::wstring& string);
- UnicodeString(LPCWSTR string, size_t length = std::string::npos);
-
- UnicodeString& operator=(const std::wstring& string);
-
- UnicodeString& operator=(const UnicodeString& other)
- {
- m_Buffer = other.m_Buffer;
- update();
- return *this;
- }
-
- UnicodeString& operator=(UnicodeString&& other)
- {
- m_Buffer = std::move(other.m_Buffer);
- update();
- return *this;
- }
-
- /**
- * @brief convert to a WinNt Api-style unicode string. This is only valid as long
- * as the string isn't modified
- */
- explicit operator PUNICODE_STRING() { return &m_Data; }
-
- /**
- * @brief convert to a Win32 Api-style unicode string. This is only valid as long
- * as the string isn't modified
- */
- explicit operator LPCWSTR() const { return m_Data.Buffer; }
-
- /**
- * @return length of the string in 16-bit words (not including zero termination)
- */
- size_t size() const { return m_Buffer.size() - 1; }
-
- wchar_t operator[](size_t pos) const { return m_Buffer[pos]; }
-
- UnicodeString& appendPath(PUNICODE_STRING path);
-
-private:
- friend struct ::std::formatter<UnicodeString, char>;
-
- void update();
-
- UNICODE_STRING m_Data;
- std::vector<wchar_t> m_Buffer;
-};
-
-} // namespace usvfs
-
-template <>
-struct std::formatter<usvfs::UnicodeString, char>
- : std::formatter<PCUNICODE_STRING, char>
-{
- template <class FmtContext>
- FmtContext::iterator format(const usvfs::UnicodeString& v, FmtContext& ctx) const
- {
- if (v.size() == 0) {
- return std::format_to(ctx.out(), "<empty string>");
- } else {
- return std::formatter<PCUNICODE_STRING, char>::format(&v.m_Data, ctx);
- }
- }
-};
diff --git a/libs/usvfs/src/shared/wildcard.cpp b/libs/usvfs/src/shared/wildcard.cpp
deleted file mode 100644
index a2efe6d..0000000
--- a/libs/usvfs/src/shared/wildcard.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
-Userspace Virtual Filesystem
-
-Copyright (C) 2015 Sebastian Herbord. All rights reserved.
-
-This file is part of usvfs.
-
-usvfs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-usvfs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with usvfs. If not, see <http://www.gnu.org/licenses/>.
-*/
-#include "wildcard.h"
-#include "logging.h"
-#include "windows_sane.h"
-
-static bool IsInnerMatch(LPCWSTR pszString, LPCWSTR pszMatch)
-{
- while (*pszMatch != L'\0') {
- if ((*pszMatch == L'?') || (*pszMatch == L'>')) {
- if (!*pszString) {
- // ? must match exactly one character
- return false;
- }
-
- ++pszString;
- ++pszMatch;
- } else if ((*pszMatch == L'*') || (*pszMatch == L'<')) {
- if (IsInnerMatch(pszString, pszMatch + 1)) {
- // * may match empty string or we may have matched something already
- return true;
- }
-
- return *pszString && IsInnerMatch(pszString + 1, pszMatch);
-
- // the rest of the string can't be matched
- } else {
- if (CharUpperW(MAKEINTRESOURCEW(MAKELONG(*pszString++, 0))) !=
- CharUpperW(MAKEINTRESOURCEW(MAKELONG(*pszMatch++, 0)))) {
- // regular chars compare
- return false;
- }
- }
- }
-
- return !*pszString && !*pszMatch;
-}
-
-static LPCSTR InnerMatch(LPCSTR pszString, LPCSTR pszMatch)
-{
- // We have a special case where string is empty ("") and the mask is "*".
- // We need to handle this too. So we can't test on !*pszString here.
- // The loop breaks when the match string is exhausted.
- while (*pszString != '\0') {
- // Single wildcard character
- if ((*pszMatch == '?') || (*pszMatch == '>')) {
- // can't match directory separator
- if ((*pszString == '\\') || (*pszString == '/'))
- return nullptr;
-
- // Matches any character except empty string
- if (*pszString == '\0') {
- // string consumed, part of the pattern is left
- return pszMatch;
- }
-
- // OK next
- ++pszString;
- ++pszMatch;
- } else if ((*pszMatch == '*') || (*pszMatch == '<')) {
- // * doesn't match directory separators
- if ((*pszString == '\\') || (*pszString == '/')) {
- ++pszMatch;
- continue;
- }
-
- // Need to do some tricks.
-
- // 1. The wildcard * is ignored.
- // So just an empty string matches. This is done by recursion.
- // Because we eat one character from the match string, the
- // recursion will stop.
- {
- LPCSTR remainder = InnerMatch(pszString, pszMatch + 1);
- if (remainder != nullptr) {
- // we have a match and the * replaces no other character
- return remainder;
- }
- }
-
- // 2. Chance we eat the next character and try it again, with a
- // wildcard * match. This is done by recursion. Because we eat
- // one character from the string, the recursion will stop.
- if (*pszString != '\0') {
- LPCSTR remainder = InnerMatch(pszString + 1, pszMatch);
- if (remainder != nullptr) {
- return remainder;
- }
- }
-
- // Nothing worked with this wildcard.
- return nullptr;
- } else {
- // Standard compare of 2 chars. Note that *pszSring might be 0
- // here, but then we never get a match on *pszMask that has always
- // a value while inside this loop.
- if (CharUpperA(MAKEINTRESOURCEA(MAKELONG(*pszString++, 0))) !=
- CharUpperA(MAKEINTRESOURCEA(MAKELONG(*pszMatch++, 0))))
- return nullptr;
- }
- }
-
- // successful match if the input string was completely consumed
- if (*pszString == '\0') {
- while ((*pszMatch == '*') || (*pszMatch == '<')) {
- ++pszMatch;
- }
- return pszMatch;
- } else {
- return nullptr;
- }
-}
-
-namespace usvfs::shared::wildcard
-{
-
-bool Match(LPCWSTR pszString, LPCWSTR pszMatch)
-{
- if (*pszString == L'.') {
- // cmd.exe seems to ignore
- return Match(pszString + 1, pszMatch);
- } else {
- size_t len = wcslen(pszMatch);
- if ((len > 2) && (wcscmp(pszMatch + len - 2, L".*") == 0)) {
- // cmd.exe seems to completely ignore .* at the end.
- std::wstring temp(pszMatch, pszMatch + len - 2);
- return IsInnerMatch(pszString, temp.c_str());
- }
- return IsInnerMatch(pszString, pszMatch);
- }
-}
-
-bool Match(LPCSTR pszString, LPCSTR pszMatch)
-{
- if (*pszString == '.') {
- // cmd.exe seems to ignore
- return Match(pszString + 1, pszMatch);
- } else {
- size_t len = strlen(pszMatch);
- LPCSTR res = nullptr;
- if ((len > 2) && (strcmp(pszMatch + len - 2, ".*") == 0)) {
- // cmd.exe seems to completely ignore .* at the end.
- std::string temp(pszMatch, pszMatch + len - 2);
- res = InnerMatch(pszString, temp.c_str());
- } else {
- res = InnerMatch(pszString, pszMatch);
- }
- return ((res != nullptr) && (*res == '\0'));
- }
-}
-
-LPCSTR PartialMatch(LPCSTR pszString, LPCSTR pszMatch)
-{
- if (*pszString == '.') {
- // cmd.exe seems to ignore dots at the start
- return PartialMatch(pszString + 1, pszMatch);
- } else {
- size_t len = strlen(pszMatch);
- if ((len > 2) && (strcmp(pszMatch + len - 2, ".*") == 0)) {
- // in cmd.exe there seems to be no difference between <something>* and
- // <something>*.*
- std::string temp(pszMatch, pszMatch + len - 2);
- LPCSTR pos = InnerMatch(pszString, temp.c_str());
- if (pos != nullptr) {
- if (*pos == '\0') {
- return pszMatch + strlen(pszMatch);
- } else {
- return pszMatch + (pos - temp.c_str());
- }
- }
- }
- return InnerMatch(pszString, pszMatch);
- }
-}
-
-} // namespace usvfs::shared::wildcard
diff --git a/libs/usvfs/src/shared/wildcard.h b/libs/usvfs/src/shared/wildcard.h
deleted file mode 100644
index bf5b4a3..0000000
--- a/libs/usvfs/src/shared/wildcard.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-Userspace Virtual Filesystem
-
-Copyright (C) 2015 Sebastian Herbord. All rights reserved.
-
-This file is part of usvfs.
-
-usvfs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-usvfs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with usvfs. If not, see <http://www.gnu.org/licenses/>.
-*/
-/// Wildcard matching code
-/// by Martin Richter
-/// licensed under The Code Project Open License (CPOL)
-
-#pragma once
-
-#include "windows_sane.h"
-
-namespace usvfs::shared::wildcard
-{
-
-/**
- * @brief match string to wildcard windows-style
- * @param pszString Input string to match
- * @param pszMatch Match mask that may contain wildcards like ? and *
- * @note A ? sign matches any character, except an empty string.
- * @note A * sign matches any string inclusive an empty string.
- * @note Characters are compared caseless.
- * @return true if the string matches the pattern
- */
-bool Match(LPCWSTR pszString, LPCWSTR pszMatch);
-
-/**
- * @brief match string to wildcard windows-style
- * @param pszString Input string to match
- * @param pszMatch Match mask that may contain wildcards like ? and *
- * @note A ? sign matches any character, except an empty string.
- * @note A * sign matches any string inclusive an empty string.
- * @note Characters are compared caseless.
- * @return true if the string matches the pattern
- */
-bool Match(LPCSTR pszString, LPCSTR pszMatch);
-
-/**
- * @brief match string to wildcard windows-style
- * @param pszString Input string to match
- * @param pszMatch Match mask that may contain wildcards like ? and *
- * @note A ? sign matches any character, except an empty string.
- * @note A * sign matches any string inclusive an empty string.
- * @note Characters are compared caseless.
- * @return the "not-consumed" remainder of the pattern. If this points to a
- * zero terminator, this was a full match.
- * Returns nullptr if no match is possible
- */
-LPCSTR PartialMatch(LPCSTR pszString, LPCSTR pszMatch);
-
-} // namespace usvfs::shared::wildcard
diff --git a/libs/usvfs/src/shared/winapi.cpp b/libs/usvfs/src/shared/winapi.cpp
deleted file mode 100644
index e28a13c..0000000
--- a/libs/usvfs/src/shared/winapi.cpp
+++ /dev/null
@@ -1,490 +0,0 @@
-/*
-Userspace Virtual Filesystem
-
-Copyright (C) 2015 Sebastian Herbord. All rights reserved.
-
-This file is part of usvfs.
-
-usvfs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-usvfs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with usvfs. If not, see <http://www.gnu.org/licenses/>.
-*/
-#include "winapi.h"
-#include "exceptionex.h"
-#include "logging.h"
-#include "ntdll_declarations.h"
-#include "stringcast.h"
-#include "stringutils.h"
-#include "unicodestring.h"
-
-namespace winapi::ansi
-{
-
-std::string getModuleFileName(HMODULE module, HANDLE process)
-{
- std::wstring result = wide::getModuleFileName(module, process);
- return usvfs::shared::string_cast<std::string>(result);
-}
-
-std::string getCurrentDirectory()
-{
- std::string result;
- DWORD required = GetCurrentDirectoryA(0, nullptr);
- if (required == 0UL) {
- throw usvfs::shared::windows_error("failed to determine current working directory");
- }
- result.resize(required);
- GetCurrentDirectoryA(required, &result[0]);
- result.resize(required - 1);
- return result;
-}
-
-std::pair<std::string, std::string> getFullPathName(LPCSTR fileName)
-{
- static const int INIT_SIZE = 128;
- std::string result;
- result.resize(INIT_SIZE);
- LPSTR filePart = nullptr;
- DWORD requiredSize = GetFullPathNameA(fileName, INIT_SIZE, &result[0], &filePart);
- if (requiredSize >= INIT_SIZE) {
- result.resize(requiredSize);
- GetFullPathNameA(fileName, requiredSize, &result[0], &filePart);
- }
- if (requiredSize != 0UL) {
- return std::make_pair(result, std::string(filePart != nullptr ? filePart : ""));
- } else {
- return make_pair(result, std::string());
- }
-}
-
-} // namespace winapi::ansi
-
-namespace winapi::wide
-{
-
-std::wstring getModuleFileName(HMODULE module, HANDLE process)
-{
- std::wstring result;
- result.resize(64);
- DWORD rc = 0UL;
-
- while ((rc = (process == INVALID_HANDLE_VALUE)
- ? ::GetModuleFileNameW(module, &result[0],
- static_cast<DWORD>(result.size()))
- : ::GetModuleFileNameExW(process, module, &result[0],
- static_cast<DWORD>(result.size()))) ==
- result.size()) {
- result.resize(result.size() * 2);
- }
-
- if (rc == 0UL) {
- if (::GetLastError() == ERROR_PARTIAL_COPY) {
-#if BOOST_ARCH_X86_64
- return L"unknown (32-bit process)";
-#else
- return L"unknown (64-bit process)";
-#endif
- } else {
- throw usvfs::shared::windows_error("failed to retrieve module file name");
- }
- }
-
- result.resize(rc);
-
- return result;
-}
-
-std::pair<std::wstring, std::wstring> getFullPathName(LPCWSTR fileName)
-{
- wchar_t buf1[MAX_PATH];
- std::vector<wchar_t> buf2;
- wchar_t* result = buf1;
- LPWSTR filePart = nullptr;
- DWORD requiredSize = GetFullPathNameW(fileName, MAX_PATH, result, &filePart);
- if (requiredSize >= MAX_PATH) {
- buf2.resize(requiredSize);
- result = &buf2[0];
- requiredSize = GetFullPathNameW(fileName, requiredSize, result, &filePart);
- }
- return make_pair(std::wstring(result, requiredSize),
- std::wstring((requiredSize && filePart) ? filePart : L""));
-}
-
-std::wstring getCurrentDirectory()
-{
- // really great api this (::GetCurrentDirectoryW)
- // - if it succeeds, returns size in characters WITHOUT zero termination
- // - if it fails due to buffer too small, returns size in characters WITH zero
- // termination
- // - if it fails for other reasons, returns 0
- std::wstring result;
- DWORD required = GetCurrentDirectoryW(0, nullptr);
- if (required == 0UL) {
- throw usvfs::shared::windows_error("failed to determine current working directory");
- }
- result.resize(required);
- GetCurrentDirectoryW(required, &result[0]);
- result.resize(required - 1);
- return result;
-}
-
-std::wstring getKnownFolderPath(REFKNOWNFOLDERID folderID)
-{
- PWSTR writablePath;
-
- ::SHGetKnownFolderPath(folderID, 0, nullptr, &writablePath);
-
- ON_BLOCK_EXIT([writablePath]() {
- ::CoTaskMemFree(writablePath);
- });
-
- return std::wstring(writablePath);
-}
-
-} // namespace winapi::wide
-
-namespace winapi::ex
-{
-
-std::pair<uintptr_t, uintptr_t> getSectionRange(HANDLE moduleHandle)
-{
- std::pair<uintptr_t, uintptr_t> result;
- bool found = false;
- uintptr_t exeModule = reinterpret_cast<uintptr_t>(moduleHandle);
- if (exeModule == 0) {
- throw std::runtime_error("failed to determine address range of executable");
- }
-
- std::pair<uintptr_t, uintptr_t> totalRange{UINT_MAX, 0};
-
- PIMAGE_DOS_HEADER dosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(exeModule);
- PIMAGE_NT_HEADERS ntHeader =
- reinterpret_cast<PIMAGE_NT_HEADERS>(exeModule + dosHeader->e_lfanew);
- PIMAGE_SECTION_HEADER sectionHeader =
- reinterpret_cast<PIMAGE_SECTION_HEADER>(ntHeader + 1);
- for (int i = 0; i < ntHeader->FileHeader.NumberOfSections && !found; ++i) {
- if (memcmp(sectionHeader->Name, ".text", 5) == 0) {
- result.first = exeModule + sectionHeader->VirtualAddress;
- result.second = result.first + sectionHeader->Misc.VirtualSize;
- found = true;
- } else {
- uintptr_t start = exeModule + sectionHeader->VirtualAddress;
- totalRange.first = std::min(totalRange.first, start);
- totalRange.second = std::max<uintptr_t>(totalRange.second,
- start + sectionHeader->Misc.VirtualSize);
- }
- ++sectionHeader;
- }
-
- if (!found) {
- return totalRange;
- }
-
- return result;
-}
-
-OSVersion getOSVersion()
-{
- RTL_OSVERSIONINFOEXW versionInfo;
- ZeroMemory(&versionInfo, sizeof(RTL_OSVERSIONINFOEXW));
- versionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
- RtlGetVersion((PRTL_OSVERSIONINFOW)&versionInfo);
-
- OSVersion result;
- result.major = versionInfo.dwMajorVersion;
- result.minor = versionInfo.dwMinorVersion;
- result.build = versionInfo.dwBuildNumber;
- result.platformid = versionInfo.dwPlatformId;
- result.servicpack =
- versionInfo.wServicePackMajor << 16 | versionInfo.wServicePackMinor;
- return result;
-}
-
-} // namespace winapi::ex
-
-namespace winapi::ex::ansi
-{
-
-std::string errorString(DWORD errorCode)
-{
- std::ostringstream finalMessage;
-
- LPSTR buffer = nullptr;
-
- DWORD currentErrorCode = GetLastError();
-
- errorCode =
- errorCode != std::numeric_limits<DWORD>::max() ? errorCode : currentErrorCode;
-
- // TODO: the message is not english?
- if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- nullptr, errorCode,
- 0 //, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)
- ,
- (LPSTR)&buffer, 0, nullptr) == 0) {
- finalMessage << "(unknown error [" << errorCode << "])";
- } else {
- if (buffer != nullptr) {
- size_t end = strlen(buffer) - 1;
- while ((buffer[end] == '\n') || (buffer[end] == '\r')) {
- buffer[end--] = '\0';
- }
- finalMessage << "(" << buffer << " [" << errorCode << "])";
- LocalFree(buffer); // allocated by FormatMessage
- }
- }
-
- SetLastError(currentErrorCode); // restore error code because FormatMessage might
- // have modified it
- return finalMessage.str();
-}
-
-std::string toString(const FILETIME& time)
-{
- SYSTEMTIME temp;
- FileTimeToSystemTime(&time, &temp);
- std::ostringstream stream;
- stream << temp.wYear << "-" << temp.wMonth << "-" << temp.wDay << temp.wHour << ":"
- << temp.wMinute << ":" << temp.wSecond;
- return stream.str();
-}
-
-LPCSTR GetBaseName(LPCSTR string)
-{
- LPCSTR result = string + strlen(string) - 1;
- while (result > string) {
- if ((*result == '\\') || (*result == '/')) {
- ++result;
- break;
- } else {
- --result;
- }
- }
- return result;
-}
-
-} // namespace winapi::ex::ansi
-
-namespace winapi::ex::wide
-{
-
-bool fileExists(LPCWSTR fileName, bool* isDirectory)
-{
- DWORD attrib = GetFileAttributesW(fileName);
-
- if (attrib == INVALID_FILE_ATTRIBUTES) {
- return false;
- } else {
- if (isDirectory != nullptr) {
- *isDirectory = (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0;
- }
- return true;
- }
-}
-
-std::wstring errorString(DWORD errorCode)
-{
- std::wostringstream finalMessage;
-
- LPWSTR buffer = nullptr;
-
- DWORD currentErrorCode = GetLastError();
-
- errorCode =
- errorCode != std::numeric_limits<DWORD>::max() ? errorCode : currentErrorCode;
-
- // TODO: the message is not english?
- if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- nullptr, errorCode,
- 0 //, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)
- ,
- (LPWSTR)&buffer, 0, nullptr) == 0) {
- finalMessage << L"(unknown error [" << errorCode << "])";
- } else {
- if (buffer != nullptr) {
- size_t end = wcslen(buffer) - 1;
- while ((buffer[end] == L'\n') || (buffer[end] == L'\r')) {
- buffer[end--] = L'\0';
- }
- finalMessage << L"(" << buffer << L" [" << errorCode << L"])";
- LocalFree(buffer); // allocated by FormatMessage
- }
- }
-
- SetLastError(currentErrorCode); // restore error code because FormatMessage might
- // have modified it
- return finalMessage.str();
-}
-
-std::wstring toString(const FILETIME& time)
-{
- SYSTEMTIME temp;
- FileTimeToSystemTime(&time, &temp);
- std::wostringstream stream;
- stream << temp.wYear << "-" << temp.wMonth << "-" << temp.wDay << temp.wHour << ":"
- << temp.wMinute << ":" << temp.wSecond;
- return stream.str();
-}
-
-LPCWSTR GetBaseName(LPCWSTR string)
-{
- LPCWSTR result;
- if ((string == nullptr) || (string[0] == L'\0')) {
- result = string;
- } else {
- result = string + wcslen(string) - 1;
- }
-
- while (result > string) {
- if ((*result == L'\\') || (*result == L'/')) {
- ++result;
- break;
- } else {
- --result;
- }
- }
- return result;
-}
-
-LPWSTR GetBaseName(LPWSTR path)
-{
- LPCWSTR result = GetBaseName(static_cast<LPCWSTR>(path));
- return const_cast<LPWSTR>(result);
-}
-
-std::wstring getSectionName(PVOID addressIn, HANDLE process)
-{
- if (process == nullptr) {
- process = GetCurrentProcess();
- }
- HMODULE modules[1024];
- intptr_t address = reinterpret_cast<intptr_t>(addressIn);
- DWORD required;
- if (::EnumProcessModules(process, modules, sizeof(modules), &required)) {
- for (DWORD i = 0; i < (std::min<DWORD>(1024UL, required) / sizeof(HMODULE)); ++i) {
- std::pair<intptr_t, intptr_t> range = getSectionRange(modules[i]);
- if ((address > range.first) && (address < range.second)) {
- try {
- return winapi::wide::getModuleFileName(modules[i], process);
- } catch (const std::exception&) {
- return std::wstring(L"unknown");
- }
- }
- }
- }
- return std::wstring(L"unknown");
-}
-
-std::vector<FileResult> quickFindFiles(LPCWSTR directoryName, LPCWSTR pattern)
-{
- std::vector<FileResult> result;
-
- static const unsigned int BUFFER_SIZE = 1024;
-
- HANDLE hdl = CreateFileW(directoryName, GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
-
- ON_BLOCK_EXIT([hdl]() {
- CloseHandle(hdl);
- });
-
- uint8_t buffer[BUFFER_SIZE];
-
- NTSTATUS res = STATUS_SUCCESS; // status success
- while (res == STATUS_SUCCESS) {
- IO_STATUS_BLOCK status;
-
- res = NtQueryDirectoryFile(
- hdl, nullptr, nullptr, nullptr, &status, buffer, BUFFER_SIZE,
- FileFullDirectoryInformation, FALSE,
- static_cast<PUNICODE_STRING>(usvfs::UnicodeString(pattern)), FALSE);
- if (res == STATUS_SUCCESS) {
- FILE_FULL_DIR_INFORMATION* info =
- reinterpret_cast<FILE_FULL_DIR_INFORMATION*>(buffer);
- void* endPos = buffer + status.Information;
- while (info < endPos) {
- FileResult file;
- file.fileName =
- std::wstring(info->FileName, info->FileNameLength / sizeof(wchar_t));
- file.attributes = info->FileAttributes;
-
- result.push_back(file);
- if (info->NextEntryOffset == 0) {
- break;
- } else {
- info = reinterpret_cast<FILE_FULL_DIR_INFORMATION*>(
- reinterpret_cast<uint8_t*>(info) + info->NextEntryOffset);
- }
- }
- }
- }
-
- return result;
-}
-
-bool createPath(boost::filesystem::path path, LPSECURITY_ATTRIBUTES securityAttributes)
-{
- // sanity and guaranteed recursion end:
- if (!path.has_relative_path())
- throw usvfs::shared::windows_error(
- "createPath() refusing to create non-existing top level path: " +
- path.string());
-
- DWORD attr = GetFileAttributesW(path.c_str());
- DWORD err = GetLastError();
- if (attr != INVALID_FILE_ATTRIBUTES) {
- if (attr & FILE_ATTRIBUTE_DIRECTORY)
- return false; // if directory already exists all is good
- else
- throw usvfs::shared::windows_error("createPath() called on a file: " +
- path.string());
- }
- if (err != ERROR_FILE_NOT_FOUND && err != ERROR_PATH_NOT_FOUND)
- throw usvfs::shared::windows_error(
- "createPath() GetFileAttributesW failed on: " + path.string(), err);
-
- if (err != ERROR_FILE_NOT_FOUND) // ERROR_FILE_NOT_FOUND means parent directory
- // already exists
- createPath(path.parent_path(),
- securityAttributes); // otherwise create parent directory (recursively)
-
- BOOL res = CreateDirectoryW(path.c_str(), securityAttributes);
- if (!res) {
- err = GetLastError();
- throw usvfs::shared::windows_error(
- "createPath() CreateDirectoryW failed on: " + path.string(), err);
- }
- return true;
-}
-
-std::wstring getWindowsBuildLab(bool ex)
-{
- HKEY hKey = nullptr;
- auto res = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
- LR"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)", 0,
- KEY_READ, &hKey);
- if (res != ERROR_SUCCESS || !hKey)
- return L"Opening HKLM Windows NT\\CurrentVersion failed?!";
- WCHAR buf[200];
- DWORD size = static_cast<DWORD>(sizeof(buf));
- res = RegQueryValueExW(hKey, ex ? L"BuildLabEx" : L"BuildLab", NULL, NULL,
- reinterpret_cast<LPBYTE>(buf), &size);
- if (res != ERROR_SUCCESS || size > sizeof(buf))
- return ex ? L"BuildLabEx reg value not found?!" : L"BuildLab reg value not found?!";
- size /= sizeof(buf[0]);
- if (size && !buf[size - 1])
- --size;
- return std::wstring(buf, size);
-}
-
-} // namespace winapi::ex::wide
diff --git a/libs/usvfs/src/shared/winapi.h b/libs/usvfs/src/shared/winapi.h
deleted file mode 100644
index f94eff6..0000000
--- a/libs/usvfs/src/shared/winapi.h
+++ /dev/null
@@ -1,610 +0,0 @@
-/*
-Userspace Virtual Filesystem
-
-Copyright (C) 2015 Sebastian Herbord. All rights reserved.
-
-This file is part of usvfs.
-
-usvfs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-usvfs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with usvfs. If not, see <http://www.gnu.org/licenses/>.
-*/
-#pragma once
-
-#include "logging.h"
-#include "stringcast.h"
-#include "windows_sane.h"
-#include <ShlObj.h>
-
-#define ALIAS(alias, original) \
- template <typename... Args> \
- auto alias(Args&&... args) -> decltype(original(std::forward<Args>(args)...)) \
- { \
- return original(std::forward<Args>(args)...); \
- }
-
-#define ALIAST(alias, original) \
- template <typename T, typename... Args> \
- auto alias<T>(Args && ... args) \
- -> decltype(original<T>(std::forward<Args>(args)...)) \
- { \
- return original<T>(std::forward<Args>(args)...); \
- }
-
-namespace winapi
-{
-
-struct parameter_error : public std::runtime_error
-{
- parameter_error(const std::string& msg) : runtime_error(msg) {}
-};
-
-} // namespace winapi
-
-namespace winapi::process
-{
-
-/**
- * @brief result of process creation
- */
-struct Result
-{
- Result()
- {
- ::ZeroMemory(&processInfo, sizeof(PROCESS_INFORMATION));
- ::ZeroMemory(&startupInfo, sizeof(STARTUPINFO));
- startupInfo.cb = sizeof(STARTUPINFO);
- }
-
- Result(Result&& reference)
- : valid(reference.valid), startupInfo(reference.startupInfo),
- processInfo(reference.processInfo), errorCode(reference.errorCode)
- {
- reference.valid = false;
- }
-
- ~Result()
- {
- if (valid) {
- CloseHandle(processInfo.hProcess);
- CloseHandle(processInfo.hThread);
- }
-
- if (stdoutPipe != INVALID_HANDLE_VALUE) {
- CloseHandle(stdoutPipe);
- }
- }
-
- Result(const Result&) = delete;
-
- size_t readStdout(std::vector<uint8_t>& buffer, bool& eof)
- {
- if (stdoutPipe != INVALID_HANDLE_VALUE) {
- DWORD read;
- BOOL res = ReadFile(stdoutPipe, &buffer[0], static_cast<DWORD>(buffer.size()),
- &read, nullptr);
- eof = (res == TRUE) && (read == 0);
- return static_cast<size_t>(read);
- } else {
- eof = true;
- return 0;
- }
- }
-
- bool valid{false};
- STARTUPINFO startupInfo;
- PROCESS_INFORMATION processInfo;
- DWORD errorCode{0UL};
-
- HANDLE stdoutPipe{INVALID_HANDLE_VALUE};
-};
-
-/**
- * @brief internal class to handle process creation with named parameters.
- */
-template <typename CharT>
-class _Create
-{
-public:
- _Create(const std::basic_string<CharT>& binaryName);
- _Create(const _Create<CharT>& reference) = delete;
- _Create<CharT>& operator=(const _Create<CharT>& reference) = delete;
-
- _Create(_Create<CharT>&& reference)
- : m_CurrentDirectory(std::move(reference.m_CurrentDirectory)),
- m_ProcessAttributes(reference.m_ProcessAttributes),
- m_ThreadAttributes(reference.m_ThreadAttributes),
- m_InheritHandles(reference.m_InheritHandles),
- m_CreationFlags(std::move(reference.m_CreationFlags)),
- m_Executed(reference.m_Executed)
- {
- // stringstream should be moveable but it seems it isn't on mingw
- m_CommandLine << reference.m_CommandLine.rdbuf();
- }
-
- /// named parameter "argument". May be called repeatedly. This is
- /// directly appended to the command line with a separating space. No
- /// quoting happens
- template <typename ArgT>
- _Create& argument(const ArgT& argin)
- {
- m_CommandLine << " " << argin;
- return *this;
- }
-
- template <typename ArgT>
- _Create& arg(const ArgT& argin)
- {
- return this->argument(argin);
- }
-
- template <typename IterT>
- _Create& arguments(IterT begin, IterT end)
- {
- for (; begin != end; ++begin) {
- m_CommandLine << " " << *begin;
- }
-
- return *this;
- }
-
- /// @brief set the working directory for the process
- _Create& workingDirectory(const std::basic_string<CharT>& path);
-
- /// @brief set process attributes
- _Create& processAttributes(SECURITY_ATTRIBUTES* attributes);
-
- /// @brief set thread attributes
- _Create& threadAttributes(SECURITY_ATTRIBUTES* attributes);
-
- /// @brief activate inheriting handles
- _Create& inheritHandles();
-
- /// @brief have the process start suspended
- _Create& suspended();
-
- /// @brief set the process up to output stout to a pipe which can be
- /// retrieved through the result object
- _Create& stdoutPipe();
-
- /// @brief end the named parameter cascade and create the process
- Result operator()()
- {
- m_CommandLine.seekp(0, std::ios::end);
- unsigned int length = static_cast<unsigned int>(m_CommandLine.tellp());
- std::unique_ptr<CharT[]> clBuffer(new CharT[length + 1]);
- memset(clBuffer.get(), 0, (length + 1) * sizeof(CharT));
- memcpy(clBuffer.get(), m_CommandLine.str().c_str(), length * sizeof(CharT));
- Result result;
-
- if (m_StdoutPipe) {
- result.stdoutPipe = setupPipe(result.startupInfo.hStdOutput);
- result.startupInfo.dwFlags |= STARTF_USESTDHANDLES;
- }
-
- result.valid =
- createProcessInt(nullptr, clBuffer.get(), m_ProcessAttributes,
- m_ThreadAttributes, m_InheritHandles, m_CreationFlags, nullptr,
- m_CurrentDirectory.length() > 0 ? m_CurrentDirectory.c_str()
- : nullptr,
- &result.startupInfo, &result.processInfo) == TRUE;
-
- if (m_Stdout != INVALID_HANDLE_VALUE) {
- // got to close the write end of pipes
- CloseHandle(result.startupInfo.hStdOutput);
- }
-
- if (result.valid) {
- result.errorCode = NOERROR;
- } else {
- result.errorCode = GetLastError();
- }
- return result;
- }
-
-private:
- static BOOL createProcessInt(LPCWSTR lpApplicationName, LPWSTR lpCommandLine,
- SECURITY_ATTRIBUTES* lpProcessAttributes,
- SECURITY_ATTRIBUTES* lpThreadAttributes,
- BOOL bInheritHandles, DWORD dwCreationFlags,
- LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory,
- LPSTARTUPINFOW lpStartupInfo,
- LPPROCESS_INFORMATION lpProcessInformation)
- {
- return ::CreateProcessW(lpApplicationName, lpCommandLine, lpProcessAttributes,
- lpThreadAttributes, bInheritHandles, dwCreationFlags,
- lpEnvironment, lpCurrentDirectory, lpStartupInfo,
- lpProcessInformation);
- }
-
- static BOOL createProcessInt(LPCSTR lpApplicationName, LPSTR lpCommandLine,
- SECURITY_ATTRIBUTES* lpProcessAttributes,
- SECURITY_ATTRIBUTES* lpThreadAttributes,
- BOOL bInheritHandles, DWORD dwCreationFlags,
- LPVOID lpEnvironment, LPCSTR lpCurrentDirectory,
- LPSTARTUPINFOW lpStartupInfo,
- LPPROCESS_INFORMATION lpProcessInformation)
- {
- std::wstring executable;
- if (lpApplicationName != nullptr) {
- executable = usvfs::shared::string_cast<std::wstring>(lpApplicationName);
- }
-
- std::wstring cmdline;
- if (lpCommandLine != nullptr) {
- cmdline = usvfs::shared::string_cast<std::wstring>(lpCommandLine);
- }
-
- std::wstring cwd;
- if (lpCurrentDirectory != nullptr) {
- cwd = usvfs::shared::string_cast<std::wstring>(lpCurrentDirectory);
- }
-
- return ::CreateProcessW(lpApplicationName != nullptr ? executable.c_str() : nullptr,
- lpCommandLine != nullptr ? &cmdline[0] : nullptr,
- lpProcessAttributes, lpThreadAttributes, bInheritHandles,
- dwCreationFlags, lpEnvironment,
- lpCurrentDirectory != nullptr ? cwd.c_str() : nullptr,
- lpStartupInfo, lpProcessInformation);
- }
-
- HANDLE setupPipe(HANDLE& childHandle)
- {
- SECURITY_ATTRIBUTES attr;
- attr.nLength = sizeof(SECURITY_ATTRIBUTES);
- attr.bInheritHandle = TRUE;
- attr.lpSecurityDescriptor = nullptr;
-
- HANDLE pipe[2];
-
- CreatePipe(&pipe[0], &pipe[1], &attr, 0);
- SetHandleInformation(pipe[0], HANDLE_FLAG_INHERIT, 0);
-
- childHandle = pipe[1];
-
- return pipe[0];
- }
-
-private:
- std::basic_stringstream<CharT> m_CommandLine;
- std::basic_string<CharT> m_CurrentDirectory{};
- SECURITY_ATTRIBUTES* m_ProcessAttributes{nullptr};
- SECURITY_ATTRIBUTES* m_ThreadAttributes{nullptr};
- BOOL m_InheritHandles{false};
- DWORD m_CreationFlags{0UL};
- bool m_Executed{false};
- bool m_StdoutPipe{false};
-
- HANDLE m_Stdout{INVALID_HANDLE_VALUE};
-};
-
-} // namespace winapi::process
-
-namespace winapi::file
-{
-/**
- * @brief internal class to handle file creation (opening) with named
- * parameters.
- */
-template <typename CharT, DWORD DefaultDisposition>
-class _Create
-{
-public:
- _Create(const std::basic_string<CharT>& fileName) : m_FileName(fileName) {}
-
- _Create& access(DWORD desiredAccess)
- {
- m_DesiredAccess = desiredAccess;
- return *this;
- }
-
- _Create& share(DWORD shareMode)
- {
- m_ShareMode = shareMode;
- return *this;
- }
-
- _Create& createAlways()
- {
- m_CreationDisposition = CREATE_ALWAYS;
- return *this;
- }
-
- _Create& openAlways()
- {
- m_CreationDisposition = OPEN_ALWAYS;
- return *this;
- }
-
- _Create& security(SECURITY_ATTRIBUTES* attributes)
- {
- m_SecurityAttributes = attributes;
- return *this;
- }
-
- _Create& templateFile(HANDLE templateFile)
- {
- m_Template = templateFile;
- return *this;
- }
-
- /// @brief end the named parameter cascade and open the file
- HANDLE operator()()
- {
- return callDelegate(
- std::integral_constant<bool, sizeof(CharT) == sizeof(wchar_t)>());
- }
-
-private:
- HANDLE callDelegate(std::true_type)
- {
- return ::CreateFileW(m_FileName.c_str(), m_DesiredAccess, m_ShareMode,
- m_SecurityAttributes, m_CreationDisposition, m_Flags,
- m_Template);
- }
-
- HANDLE callDelegate(std::false_type)
- {
- return ::CreateFileA(m_FileName.c_str(), m_DesiredAccess, m_ShareMode,
- m_SecurityAttributes, m_CreationDisposition, m_Flags,
- m_Template);
- }
-
-private:
- std::basic_string<CharT> m_FileName;
- DWORD m_DesiredAccess{GENERIC_ALL};
- DWORD m_ShareMode{0UL};
- DWORD m_CreationDisposition{DefaultDisposition};
- DWORD m_Flags{FILE_ATTRIBUTE_NORMAL};
- HANDLE m_Template{nullptr};
- SECURITY_ATTRIBUTES* m_SecurityAttributes{nullptr};
-};
-
-} // namespace winapi::file
-
-namespace winapi::ansi
-{
-
-std::string getModuleFileName(HMODULE module, HANDLE process = INVALID_HANDLE_VALUE);
-std::pair<std::string, std::string> getFullPathName(LPCSTR fileName);
-std::string getCurrentDirectory();
-typedef process::_Create<char> createProcess;
-typedef file::_Create<char, CREATE_NEW> createFile;
-typedef file::_Create<char, OPEN_EXISTING> openFile;
-
-} // namespace winapi::ansi
-
-namespace winapi::wide
-{
-
-std::wstring getModuleFileName(HMODULE module, HANDLE process = INVALID_HANDLE_VALUE);
-std::pair<std::wstring, std::wstring> getFullPathName(LPCWSTR fileName);
-std::wstring getCurrentDirectory();
-std::wstring getKnownFolderPath(REFKNOWNFOLDERID folderID);
-
-typedef process::_Create<wchar_t> createProcess;
-typedef file::_Create<wchar_t, CREATE_NEW> createFile;
-typedef file::_Create<wchar_t, OPEN_EXISTING> openFile;
-
-} // namespace winapi::wide
-
-/**
- * useful convenience functions close to the api
- */
-namespace winapi::ex
-{
-
-/**
- * @brief retrieve the address range covering the code section of a module
- * @param moduleHandle handle to the module
- * @return start and end address of the code section
- * @note the code section can only be identified if it has the standardized section name
- * ".text" Otherwise the whole address range of all sections in the module is returned.
- * This happens for compressed exectuables for example
- */
-std::pair<uintptr_t, uintptr_t> getSectionRange(HANDLE moduleHandle);
-
-struct OSVersion
-{
- DWORD major;
- DWORD minor;
- DWORD build;
- DWORD platformid;
- DWORD servicpack;
-};
-
-OSVersion getOSVersion();
-
-} // namespace winapi::ex
-
-namespace winapi::ex::ansi
-{
-
-/**
- * @brief retrieve an error string for a windows error message
- * @param errorCode the error code to look up. If this is left at the default,
- * ::GetLastError is used
- * @return string representation of the error. Currently this is localized
- */
-std::string errorString(DWORD errorCode = std::numeric_limits<DWORD>::max());
-
-/**
- * @brief convert filetime to string
- * @param time time to convert
- * @return a string representation (currently only supports utc and iso format with
- * second precision)
- */
-std::string toString(const FILETIME& time);
-
-/**
- * @brief find file name in a windows file path
- * @param path the path to search in
- * @return the file name of the path or an empty string if the path ends on
- * a slash
- * @note this function doesn't access the file system so it doesn't depend
- * on whether the file actually exists. This also means it can't
- * determine if a path that doesn't end on a slash refers to a file or
- * directory
- * @note the return value is a pointer into the same buffer, no copy is
- * created
- */
-LPCSTR GetBaseName(LPCSTR string);
-
-} // namespace winapi::ex::ansi
-
-namespace winapi::ex::wide
-{
-/**
- * retrieve the name of the binary section containing the specified address
- * @param address the address to test
- * @param process the process for which to retrieve the section. If this is
- * nullptr, the current process is analized.
- * @return name of the section or "unknown" if no matching section was found
- */
-std::wstring getSectionName(PVOID address, HANDLE process = nullptr);
-
-/**
- * @brief test if a file exists
- * @param path path to check
- * @param isDirectory (optional) if this isn't null, it will be set to true if the path
- * specifies a directory, false otherwise
- * @return true if the file (or directory) exists.
- */
-bool fileExists(LPCWSTR fileName, bool* isDirectory = nullptr);
-
-/**
- * @brief retrieve an error string for a windows error message
- * @param errorCode the error code to look up. If this is left at the default,
- * ::GetLastError is used
- * @return string representation of the error. Currently this is localized
- */
-std::wstring errorString(DWORD errorCode = std::numeric_limits<DWORD>::max());
-
-/**
- * @brief convert filetime to string
- * @param time time to convert
- * @return a string representation (currently only supports utc and iso format with
- * second precision)
- */
-std::wstring toString(const FILETIME& time);
-
-/**
- * @brief find file name in a windows file path
- * @param path the path to search in
- * @return the file name of the path or an empty string if the path ends on
- * a slash
- * @note this function doesn't access the file system so it doesn't depend
- * on whether the file actually exists. This also means it can't
- * determine if a path that doesn't end on a slash refers to a file or
- * directory
- * @note the return value is a pointer into the same buffer, no copy is
- * created
- */
-LPCWSTR GetBaseName(LPCWSTR path);
-
-/**
- * @see const-variant of this function
- */
-LPWSTR GetBaseName(LPWSTR path);
-
-struct FileResult
-{
- std::wstring fileName;
- ULONG attributes;
-};
-
-/**
- * @brief a quick function to find all files in a directory or files following a
- * pattern. This uses NtQueryDirectoryFile api internally so it should be faster than
- * the usual FindFirstFile/FindNextFile pattern
- * @param directoryName name of the directory to search in
- * @param pattern name pattern that needs to match
- * @return the list of files found
- */
-std::vector<FileResult> quickFindFiles(LPCWSTR directoryName, LPCWSTR pattern);
-
-/**
- * @brief create the specified directory including all intermediate
- * directories
- * @param path the path to create
- * @param securityAttributes the security attributes to use for all created
- * directories. if this is null (default), the standard attributes
- * are used
- * @return true if the directory (and possibly parent directories) were actually created
- * and false if the directory already existed. Throws exceptions on failure.
- */
-bool createPath(boost::filesystem::path path,
- LPSECURITY_ATTRIBUTES securityAttributes = nullptr);
-inline bool createPath(LPCWSTR path, LPSECURITY_ATTRIBUTES securityAttributes = nullptr)
-{
- return createPath(boost::filesystem::path(path), securityAttributes);
-}
-
-std::wstring getWindowsBuildLab(bool ex = false);
-
-} // namespace winapi::ex::wide
-
-namespace winapi::process
-{
-
-template <typename CharT>
-_Create<CharT>::_Create(const std::basic_string<CharT>& binaryName)
-{
- if (binaryName.length() > MAX_PATH) {
- throw parameter_error("executable filename can't be longer than 260 characters");
- }
- m_CommandLine << "\"" << binaryName << "\"";
-}
-
-template <typename CharT>
-_Create<CharT>& _Create<CharT>::workingDirectory(const std::basic_string<CharT>& path)
-{
- m_CurrentDirectory = path;
- return *this;
-}
-
-template <typename CharT>
-_Create<CharT>& _Create<CharT>::processAttributes(SECURITY_ATTRIBUTES* attributes)
-{
- m_ProcessAttributes = attributes;
- return *this;
-}
-
-template <typename CharT>
-_Create<CharT>& _Create<CharT>::threadAttributes(SECURITY_ATTRIBUTES* attributes)
-{
- m_ThreadAttributes = attributes;
- return *this;
-}
-
-template <typename CharT>
-_Create<CharT>& _Create<CharT>::inheritHandles()
-{
- m_InheritHandles = true;
- return *this;
-}
-
-template <typename CharT>
-_Create<CharT>& _Create<CharT>::suspended()
-{
- m_CreationFlags |= CREATE_SUSPENDED;
- return *this;
-}
-
-template <typename CharT>
-_Create<CharT>& _Create<CharT>::stdoutPipe()
-{
- m_StdoutPipe = true;
- return *this;
-}
-
-} // namespace winapi::process
diff --git a/libs/usvfs/src/shared/windows_sane.h b/libs/usvfs/src/shared/windows_sane.h
deleted file mode 100644
index 7bb3726..0000000
--- a/libs/usvfs/src/shared/windows_sane.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-Userspace Virtual Filesystem
-
-Copyright (C) 2015 Sebastian Herbord. All rights reserved.
-
-This file is part of usvfs.
-
-usvfs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-usvfs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with usvfs. If not, see <http://www.gnu.org/licenses/>.
-*/
-#pragma once
-
-#ifndef NOMINMAX
-#define NOMINMAX
-#endif
-
-#define WIN32_LEAN_AND_MEAN
-#include <Windows.h>