From f47f5daa0155368069ecef30ecffff3380de7922 Mon Sep 17 00:00:00 2001 From: Twinki Date: Mon, 27 May 2024 00:40:45 -0400 Subject: [PATCH 01/10] WIP: Add File & Directory skipping # Motivations # Modifications - - Update BOOST_PATH for the correct boost version - Add .clang-format --- .clang-format | 41 +++++++++++++++ include/sharedparameters.h | 16 ++++++ include/usvfs.h | 24 +++++++++ src/usvfs_dll/hookcontext.cpp | 50 ++++++++++++++++++ src/usvfs_dll/hookcontext.h | 8 +++ src/usvfs_dll/sharedparameters.cpp | 78 +++++++++++++++++++++++++++++ src/usvfs_dll/usvfs.cpp | 33 ++++++++++++ vsbuild/external_dependencies.props | 2 +- 8 files changed, 251 insertions(+), 1 deletion(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..6098e1f5 --- /dev/null +++ b/.clang-format @@ -0,0 +1,41 @@ +--- +# We'll use defaults from the LLVM style, but with 4 columns indentation. +BasedOnStyle: LLVM +IndentWidth: 2 +--- +Language: Cpp +DeriveLineEnding: false +UseCRLF: true +DerivePointerAlignment: false +PointerAlignment: Left +AlignConsecutiveAssignments: true +AllowShortFunctionsOnASingleLine: Inline +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: Empty +AlwaysBreakTemplateDeclarations: Yes +AccessModifierOffset: -2 +AlignTrailingComments: true +SpacesBeforeTrailingComments: 2 +NamespaceIndentation: Inner +MaxEmptyLinesToKeep: 1 +BreakBeforeBraces: Custom +BraceWrapping: + AfterCaseLabel: false + AfterClass: true + AfterControlStatement: false + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterStruct: true + AfterUnion: true + AfterExternBlock: true + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: false + SplitEmptyNamespace: true +ColumnLimit: 88 +ForEachMacros: ['Q_FOREACH', 'foreach'] diff --git a/include/sharedparameters.h b/include/sharedparameters.h index 48e60c59..5ade246a 100644 --- a/include/sharedparameters.h +++ b/include/sharedparameters.h @@ -57,6 +57,14 @@ class DLLEXPORT SharedParameters void clearExecutableBlacklist(); bool executableBlacklisted(const std::string& app, const std::string& cmd) const; + void addSkipFileSuffix(const std::string& fileSuffix); + void clearSkipFileSuffixes(); + bool fileShouldBeSkipped(const std::string& file) const; + + void addSkipDirectory(const std::string& directory); + void clearSkipDirectories(); + bool directoryShouldBeSkipped(const std::string& directory) const; + void addForcedLibrary(const std::string& process, const std::string& path); std::vector forcedLibraries(const std::string& processName); void clearForcedLibraries(); @@ -77,6 +85,12 @@ class DLLEXPORT SharedParameters using ProcessList = boost::container::flat_set< DWORD, std::less, DWORDAllocatorT>; + using FileSuffixSkipList = boost::container::flat_set< + shared::StringT, std::less, StringAllocatorT>; + + using DirectorySkipList = boost::container::flat_set< + shared::StringT, std::less, StringAllocatorT>; + using ForcedLibraries = boost::container::slist< ForcedLibrary, ForcedLibraryAllocatorT>; @@ -93,6 +107,8 @@ class DLLEXPORT SharedParameters uint32_t m_userCount; ProcessBlacklist m_processBlacklist; ProcessList m_processList; + FileSuffixSkipList m_fileSuffixSkipList; + DirectorySkipList m_directorySkipList; ForcedLibraries m_forcedLibraries; }; diff --git a/include/usvfs.h b/include/usvfs.h index 1a91c303..a65b48b4 100644 --- a/include/usvfs.h +++ b/include/usvfs.h @@ -154,6 +154,30 @@ DLLEXPORT VOID WINAPI BlacklistExecutable(LPWSTR executableName); */ DLLEXPORT VOID WINAPI ClearExecutableBlacklist(); +/** + * adds a file suffix to a list to skip during file linking + * .txt and some_file.txt are both valid file suffixes, + * not to be confused with file extensions + * @param fileSuffix a valid file suffix + */ +DLLEXPORT VOID WINAPI AddSkipFileSuffix(LPWSTR fileSuffix); + +/** + * clears the file suffix skip-list + */ +DLLEXPORT VOID WINAPI ClearSkipFileSuffixes(); + +/** + * adds a directory to be skipped during linking + * @param directory full name of the directory + */ +DLLEXPORT VOID WINAPI AddSkipDirectory(LPWSTR directory); + +/** + * clears the directory skip-list + */ +DLLEXPORT VOID WINAPI ClearSkipDirectories(); + /** * adds a library to be force loaded when the given process is injected * @param diff --git a/src/usvfs_dll/hookcontext.cpp b/src/usvfs_dll/hookcontext.cpp index 15a763a5..3766c0b6 100644 --- a/src/usvfs_dll/hookcontext.cpp +++ b/src/usvfs_dll/hookcontext.cpp @@ -216,6 +216,56 @@ BOOL HookContext::executableBlacklisted(LPCWSTR wapp, LPCWSTR wcmd) const return m_Parameters->executableBlacklisted(app, cmd); } +void usvfs::HookContext::addSkipFileSuffix(const std::wstring& fileSuffix) +{ + const auto fsuffix = shared::string_cast(fileSuffix, shared::CodePage::UTF8); + + if (fsuffix.empty()) { + return; + } + + spdlog::get("usvfs")->debug("skipping files with the suffix '{}'", fsuffix); + m_Parameters->addSkipFileSuffix(fsuffix); +} + +void usvfs::HookContext::clearSkipFileSuffixes() +{ + spdlog::get("usvfs")->debug("clearing skip file suffixes"); + m_Parameters->clearSkipFileSuffixes(); +} + +BOOL usvfs::HookContext::fileShouldBeSkipped(const std::wstring& wFilename) const +{ + const std::string filename = ush::string_cast(wFilename, ush::CodePage::UTF8); + + return m_Parameters->fileShouldBeSkipped(filename); +} + +void usvfs::HookContext::addSkipDirectory(const std::wstring& directory) +{ + const auto dir = shared::string_cast(directory, shared::CodePage::UTF8); + + if (dir.empty()) { + return; + } + + spdlog::get("usvfs")->debug("skipping directories named '{}'", dir); + m_Parameters->addSkipDirectory(dir); +} + +void usvfs::HookContext::clearSkipDirectories() +{ + spdlog::get("usvfs")->debug("clearing skip directories"); + m_Parameters->clearSkipDirectories(); +} + +BOOL usvfs::HookContext::directoryShouldBeSkipped(const std::wstring& wDirectory) const +{ + const std::string directory = ush::string_cast(wDirectory, ush::CodePage::UTF8); + + return m_Parameters->directoryShouldBeSkipped(directory); +} + void HookContext::forceLoadLibrary( const std::wstring& wprocess, const std::wstring& wpath) { diff --git a/src/usvfs_dll/hookcontext.h b/src/usvfs_dll/hookcontext.h index 12b003eb..6b2c29f2 100644 --- a/src/usvfs_dll/hookcontext.h +++ b/src/usvfs_dll/hookcontext.h @@ -144,6 +144,14 @@ class HookContext void clearExecutableBlacklist(); BOOL HookContext::executableBlacklisted(LPCWSTR lpApplicationName, LPCWSTR lpCommandLine) const; + void addSkipFileSuffix(const std::wstring& fileSuffix); + void clearSkipFileSuffixes(); + BOOL HookContext::fileShouldBeSkipped(const std::wstring& wFilename) const; + + void addSkipDirectory(const std::wstring& directory); + void clearSkipDirectories(); + BOOL HookContext::directoryShouldBeSkipped(const std::wstring& wDirectory) const; + void forceLoadLibrary(const std::wstring &processName, const std::wstring &libraryPath); void clearLibraryForceLoads(); std::vector librariesToForceLoad(const std::wstring &processName); diff --git a/src/usvfs_dll/sharedparameters.cpp b/src/usvfs_dll/sharedparameters.cpp index d37f9bdf..5c5a7aec 100644 --- a/src/usvfs_dll/sharedparameters.cpp +++ b/src/usvfs_dll/sharedparameters.cpp @@ -37,6 +37,8 @@ SharedParameters::SharedParameters(const usvfsParameters& reference, , m_userCount(1) , m_processBlacklist(allocator) , m_processList(allocator) + , m_fileSuffixSkipList(allocator) + , m_directorySkipList(allocator) , m_forcedLibraries(allocator) { } @@ -198,6 +200,82 @@ bool SharedParameters::executableBlacklisted( return false; } +void SharedParameters::addSkipFileSuffix(const std::string& fileSuffix) +{ + bi::scoped_lock lock(m_mutex); + + m_fileSuffixSkipList.insert(shared::StringT(fileSuffix.begin(), fileSuffix.end(), + m_fileSuffixSkipList.get_allocator())); +} + +void SharedParameters::clearSkipFileSuffixes() +{ + bi::scoped_lock lock(m_mutex); + m_fileSuffixSkipList.clear(); +} + +bool SharedParameters::fileShouldBeSkipped(const std::string& file) const +{ + bool skipFile = false; + std::string log; + + { + bi::scoped_lock lock(m_mutex); + + for (const shared::StringT& skipFileSuffix : m_fileSuffixSkipList) { + if (boost::algorithm::iends_with(file, skipFileSuffix)) { + skipFile = true; + break; + } + } + } + + if (skipFile) { + spdlog::get("usvfs")->debug("skipping file '{}'", file); + return true; + } + + return false; +} + +void SharedParameters::addSkipDirectory(const std::string& directory) +{ + bi::scoped_lock lock(m_mutex); + + m_directorySkipList.insert(shared::StringT(directory.begin(), directory.end(), + m_directorySkipList.get_allocator())); +} + +void SharedParameters::clearSkipDirectories() +{ + bi::scoped_lock lock(m_mutex); + m_directorySkipList.clear(); +} + +bool SharedParameters::directoryShouldBeSkipped(const std::string& directory) const +{ + bool skip = false; + std::string log; + + { + bi::scoped_lock lock(m_mutex); + + for (const shared::StringT& skipDir : m_directorySkipList) { + if (boost::algorithm::equals(directory, skipDir)) { + skip = true; + break; + } + } + } + + if (skip) { + spdlog::get("usvfs")->debug("skipping directory '{}'", directory); + return true; + } + + return false; +} + void SharedParameters::addForcedLibrary( const std::string& processName, const std::string& libraryPath) { diff --git a/src/usvfs_dll/usvfs.cpp b/src/usvfs_dll/usvfs.cpp index 652d2e46..027ffd2e 100644 --- a/src/usvfs_dll/usvfs.cpp +++ b/src/usvfs_dll/usvfs.cpp @@ -763,6 +763,11 @@ BOOL WINAPI VirtualLinkDirectoryStatic(LPCWSTR source, LPCWSTR destination, unsi winapi::ex::wide::quickFindFiles(sourceP.c_str(), L"*")) { if (file.attributes & FILE_ATTRIBUTE_DIRECTORY) { if ((file.fileName != L".") && (file.fileName != L"..")) { + + if (context->directoryShouldBeSkipped(file.fileName)) { + continue; + } + VirtualLinkDirectoryStatic((sourceW + file.fileName).c_str(), (destinationW + file.fileName).c_str(), flags); @@ -771,6 +776,10 @@ BOOL WINAPI VirtualLinkDirectoryStatic(LPCWSTR source, LPCWSTR destination, unsi std::string nameU8 = ush::string_cast( file.fileName.c_str(), ush::CodePage::UTF8); + if (context->fileShouldBeSkipped(file.fileName)) { + continue; + } + // TODO could save memory here by storing only the file name for the // source and constructing the full name using the parent directory context->redirectionTable().addFile( @@ -878,6 +887,30 @@ VOID WINAPI ClearExecutableBlacklist() } +VOID WINAPI AddSkipFileSuffix(LPWSTR fileSuffix) +{ + context->addSkipFileSuffix(fileSuffix); +} + + +VOID WINAPI ClearSkipFileSuffixes() +{ + context->clearSkipFileSuffixes(); +} + + +VOID WINAPI AddSkipDirectory(LPWSTR directory) +{ + context->addSkipDirectory(directory); +} + + +VOID WINAPI ClearSkipDirectories() +{ + context->clearSkipDirectories(); +} + + VOID WINAPI ForceLoadLibrary(LPWSTR processName, LPWSTR libraryPath) { context->forceLoadLibrary(processName, libraryPath); diff --git a/vsbuild/external_dependencies.props b/vsbuild/external_dependencies.props index 16738ca0..9f03216b 100644 --- a/vsbuild/external_dependencies.props +++ b/vsbuild/external_dependencies.props @@ -4,7 +4,7 @@ - ..\..\boost_1_79_0 + ..\..\boost_1_85_0 $(BOOST_PATH) ..\..\googletest From 14f9025e2d25390aea925bb1c9738c60d6f9fac7 Mon Sep 17 00:00:00 2001 From: Twinki Date: Mon, 27 May 2024 15:08:23 -0400 Subject: [PATCH 02/10] Update sharedparameters.cpp --- src/usvfs_dll/sharedparameters.cpp | 40 ++++++++---------------------- 1 file changed, 10 insertions(+), 30 deletions(-) diff --git a/src/usvfs_dll/sharedparameters.cpp b/src/usvfs_dll/sharedparameters.cpp index 5c5a7aec..ac72d917 100644 --- a/src/usvfs_dll/sharedparameters.cpp +++ b/src/usvfs_dll/sharedparameters.cpp @@ -216,25 +216,15 @@ void SharedParameters::clearSkipFileSuffixes() bool SharedParameters::fileShouldBeSkipped(const std::string& file) const { - bool skipFile = false; - std::string log; - - { - bi::scoped_lock lock(m_mutex); + bi::scoped_lock lock(m_mutex); - for (const shared::StringT& skipFileSuffix : m_fileSuffixSkipList) { - if (boost::algorithm::iends_with(file, skipFileSuffix)) { - skipFile = true; - break; - } + for (const auto& skipFileSuffix : m_fileSuffixSkipList) { + if (boost::algorithm::iends_with(file, skipFileSuffix)) { + spdlog::get("usvfs")->debug("skipping file '{}'", file); + return true; } } - if (skipFile) { - spdlog::get("usvfs")->debug("skipping file '{}'", file); - return true; - } - return false; } @@ -254,25 +244,15 @@ void SharedParameters::clearSkipDirectories() bool SharedParameters::directoryShouldBeSkipped(const std::string& directory) const { - bool skip = false; - std::string log; - - { - bi::scoped_lock lock(m_mutex); + bi::scoped_lock lock(m_mutex); - for (const shared::StringT& skipDir : m_directorySkipList) { - if (boost::algorithm::equals(directory, skipDir)) { - skip = true; - break; - } + for (const auto& skipDir : m_directorySkipList) { + if (boost::algorithm::equals(directory, skipDir)) { + spdlog::get("usvfs")->debug("skipping directory '{}'", directory); + return true; } } - if (skip) { - spdlog::get("usvfs")->debug("skipping directory '{}'", directory); - return true; - } - return false; } From e163b3832fe09dd4e87efc97c26e9b5856654ecb Mon Sep 17 00:00:00 2001 From: Twinki Date: Mon, 27 May 2024 15:11:35 -0400 Subject: [PATCH 03/10] Update hookcontext.cpp --- src/usvfs_dll/hookcontext.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/usvfs_dll/hookcontext.cpp b/src/usvfs_dll/hookcontext.cpp index 3766c0b6..aca64016 100644 --- a/src/usvfs_dll/hookcontext.cpp +++ b/src/usvfs_dll/hookcontext.cpp @@ -224,7 +224,7 @@ void usvfs::HookContext::addSkipFileSuffix(const std::wstring& fileSuffix) return; } - spdlog::get("usvfs")->debug("skipping files with the suffix '{}'", fsuffix); + spdlog::get("usvfs")->debug("added skip file suffix '{}'", fsuffix); m_Parameters->addSkipFileSuffix(fsuffix); } @@ -249,7 +249,7 @@ void usvfs::HookContext::addSkipDirectory(const std::wstring& directory) return; } - spdlog::get("usvfs")->debug("skipping directories named '{}'", dir); + spdlog::get("usvfs")->debug("added skip directory '{}'", dir); m_Parameters->addSkipDirectory(dir); } From a76397904e11472126dbf3d36f62d1ce646a7d42 Mon Sep 17 00:00:00 2001 From: Twinki Date: Mon, 27 May 2024 15:12:28 -0400 Subject: [PATCH 04/10] Remove .clang-format --- .clang-format | 41 ----------------------------------------- 1 file changed, 41 deletions(-) delete mode 100644 .clang-format diff --git a/.clang-format b/.clang-format deleted file mode 100644 index 6098e1f5..00000000 --- a/.clang-format +++ /dev/null @@ -1,41 +0,0 @@ ---- -# We'll use defaults from the LLVM style, but with 4 columns indentation. -BasedOnStyle: LLVM -IndentWidth: 2 ---- -Language: Cpp -DeriveLineEnding: false -UseCRLF: true -DerivePointerAlignment: false -PointerAlignment: Left -AlignConsecutiveAssignments: true -AllowShortFunctionsOnASingleLine: Inline -AllowShortIfStatementsOnASingleLine: Never -AllowShortLambdasOnASingleLine: Empty -AlwaysBreakTemplateDeclarations: Yes -AccessModifierOffset: -2 -AlignTrailingComments: true -SpacesBeforeTrailingComments: 2 -NamespaceIndentation: Inner -MaxEmptyLinesToKeep: 1 -BreakBeforeBraces: Custom -BraceWrapping: - AfterCaseLabel: false - AfterClass: true - AfterControlStatement: false - AfterEnum: true - AfterFunction: true - AfterNamespace: true - AfterStruct: true - AfterUnion: true - AfterExternBlock: true - BeforeCatch: false - BeforeElse: false - BeforeLambdaBody: false - BeforeWhile: false - IndentBraces: false - SplitEmptyFunction: false - SplitEmptyRecord: false - SplitEmptyNamespace: true -ColumnLimit: 88 -ForEachMacros: ['Q_FOREACH', 'foreach'] From d0c6902817ad0e3da251f18ccd7b352c59b46631 Mon Sep 17 00:00:00 2001 From: Twinki Date: Mon, 27 May 2024 15:20:11 -0400 Subject: [PATCH 05/10] Update usvfs.h and usvfs.cpp --- include/usvfs.h | 16 ++++++++++------ src/usvfs_dll/usvfs.cpp | 20 ++++++-------------- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/include/usvfs.h b/include/usvfs.h index a65b48b4..7a6c6302 100644 --- a/include/usvfs.h +++ b/include/usvfs.h @@ -160,23 +160,27 @@ DLLEXPORT VOID WINAPI ClearExecutableBlacklist(); * not to be confused with file extensions * @param fileSuffix a valid file suffix */ -DLLEXPORT VOID WINAPI AddSkipFileSuffix(LPWSTR fileSuffix); +DLLEXPORT VOID WINAPI usvfsAddSkipFileSuffix(LPWSTR fileSuffix); /** * clears the file suffix skip-list */ -DLLEXPORT VOID WINAPI ClearSkipFileSuffixes(); +DLLEXPORT VOID WINAPI usvfsClearSkipFileSuffixes(); /** - * adds a directory to be skipped during linking - * @param directory full name of the directory + * adds a directory name that will be skipped during directory linking + * not a path. Any directory matching the name will be skipped, + * regardless of it's path, for example if .git is added, + * any sub-path or root-path containing a .git directory + * will be skipped during directory linking + * @param directory name of the directory */ -DLLEXPORT VOID WINAPI AddSkipDirectory(LPWSTR directory); +DLLEXPORT VOID WINAPI usvfsAddSkipDirectory(LPWSTR directory); /** * clears the directory skip-list */ -DLLEXPORT VOID WINAPI ClearSkipDirectories(); +DLLEXPORT VOID WINAPI usvfsClearSkipDirectories(); /** * adds a library to be force loaded when the given process is injected diff --git a/src/usvfs_dll/usvfs.cpp b/src/usvfs_dll/usvfs.cpp index 027ffd2e..34dd4574 100644 --- a/src/usvfs_dll/usvfs.cpp +++ b/src/usvfs_dll/usvfs.cpp @@ -762,24 +762,16 @@ BOOL WINAPI VirtualLinkDirectoryStatic(LPCWSTR source, LPCWSTR destination, unsi for (winapi::ex::wide::FileResult file : winapi::ex::wide::quickFindFiles(sourceP.c_str(), L"*")) { if (file.attributes & FILE_ATTRIBUTE_DIRECTORY) { - if ((file.fileName != L".") && (file.fileName != L"..")) { - - if (context->directoryShouldBeSkipped(file.fileName)) { - continue; - } + if ((file.fileName != L".") && (file.fileName != L"..") && !context->directoryShouldBeSkipped(file.fileName)) { VirtualLinkDirectoryStatic((sourceW + file.fileName).c_str(), (destinationW + file.fileName).c_str(), flags); } - } else { + } else if (!context->fileShouldBeSkipped(file.fileName)) { std::string nameU8 = ush::string_cast( file.fileName.c_str(), ush::CodePage::UTF8); - if (context->fileShouldBeSkipped(file.fileName)) { - continue; - } - // TODO could save memory here by storing only the file name for the // source and constructing the full name using the parent directory context->redirectionTable().addFile( @@ -887,25 +879,25 @@ VOID WINAPI ClearExecutableBlacklist() } -VOID WINAPI AddSkipFileSuffix(LPWSTR fileSuffix) +VOID WINAPI usvfsAddSkipFileSuffix(LPWSTR fileSuffix) { context->addSkipFileSuffix(fileSuffix); } -VOID WINAPI ClearSkipFileSuffixes() +VOID WINAPI usvfsClearSkipFileSuffixes() { context->clearSkipFileSuffixes(); } -VOID WINAPI AddSkipDirectory(LPWSTR directory) +VOID WINAPI usvfsAddSkipDirectory(LPWSTR directory) { context->addSkipDirectory(directory); } -VOID WINAPI ClearSkipDirectories() +VOID WINAPI usvfsClearSkipDirectories() { context->clearSkipDirectories(); } From 41fdefdc25939a7be29bc69c61fb23b5ac5c252a Mon Sep 17 00:00:00 2001 From: Twinki Date: Mon, 27 May 2024 15:22:03 -0400 Subject: [PATCH 06/10] tweak comments again --- include/usvfs.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/usvfs.h b/include/usvfs.h index 7a6c6302..37e1c114 100644 --- a/include/usvfs.h +++ b/include/usvfs.h @@ -168,11 +168,11 @@ DLLEXPORT VOID WINAPI usvfsAddSkipFileSuffix(LPWSTR fileSuffix); DLLEXPORT VOID WINAPI usvfsClearSkipFileSuffixes(); /** - * adds a directory name that will be skipped during directory linking - * not a path. Any directory matching the name will be skipped, + * adds a directory name that will be skipped during directory linking. + * Not a path. Any directory matching the name will be skipped, * regardless of it's path, for example if .git is added, * any sub-path or root-path containing a .git directory - * will be skipped during directory linking + * will have the .git directory skipped during directory linking * @param directory name of the directory */ DLLEXPORT VOID WINAPI usvfsAddSkipDirectory(LPWSTR directory); From 40c3ae8baf49cff94d448c0ada9f8038b33c62d9 Mon Sep 17 00:00:00 2001 From: Twinki Date: Mon, 27 May 2024 15:27:37 -0400 Subject: [PATCH 07/10] more logging adjustments --- src/usvfs_dll/sharedparameters.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/usvfs_dll/sharedparameters.cpp b/src/usvfs_dll/sharedparameters.cpp index ac72d917..29f4c4b0 100644 --- a/src/usvfs_dll/sharedparameters.cpp +++ b/src/usvfs_dll/sharedparameters.cpp @@ -220,7 +220,7 @@ bool SharedParameters::fileShouldBeSkipped(const std::string& file) const for (const auto& skipFileSuffix : m_fileSuffixSkipList) { if (boost::algorithm::iends_with(file, skipFileSuffix)) { - spdlog::get("usvfs")->debug("skipping file '{}'", file); + spdlog::get("usvfs")->debug("file '{}' should be skipped, matches file suffix '{}'", file, skipFileSuffix); return true; } } @@ -248,7 +248,7 @@ bool SharedParameters::directoryShouldBeSkipped(const std::string& directory) co for (const auto& skipDir : m_directorySkipList) { if (boost::algorithm::equals(directory, skipDir)) { - spdlog::get("usvfs")->debug("skipping directory '{}'", directory); + spdlog::get("usvfs")->debug("directory '{}' should be skipped", directory); return true; } } From 89afc55d06d64e04c47860ad62a09013c6cae601 Mon Sep 17 00:00:00 2001 From: Twinki Date: Sat, 1 Jun 2024 18:37:09 -0400 Subject: [PATCH 08/10] Switch to "get", add skipping to VirtualLinkFile --- include/sharedparameters.h | 4 +- include/usvfs.h | 1 + src/usvfs_dll/hookcontext.cpp | 12 ++--- src/usvfs_dll/hookcontext.h | 4 +- src/usvfs_dll/sharedparameters.cpp | 24 ++-------- src/usvfs_dll/usvfs.cpp | 77 ++++++++++++++++++++++++++---- 6 files changed, 81 insertions(+), 41 deletions(-) diff --git a/include/sharedparameters.h b/include/sharedparameters.h index 5ade246a..073f4b44 100644 --- a/include/sharedparameters.h +++ b/include/sharedparameters.h @@ -59,11 +59,11 @@ class DLLEXPORT SharedParameters void addSkipFileSuffix(const std::string& fileSuffix); void clearSkipFileSuffixes(); - bool fileShouldBeSkipped(const std::string& file) const; + std::vector skipFileSuffixes() const; void addSkipDirectory(const std::string& directory); void clearSkipDirectories(); - bool directoryShouldBeSkipped(const std::string& directory) const; + std::vector skipDirectories() const; void addForcedLibrary(const std::string& process, const std::string& path); std::vector forcedLibraries(const std::string& processName); diff --git a/include/usvfs.h b/include/usvfs.h index 37e1c114..8490cd1c 100644 --- a/include/usvfs.h +++ b/include/usvfs.h @@ -49,6 +49,7 @@ static const unsigned int LINKFLAG_CREATETARGET = 0x00000004; // if set, file // If there different create-target have been set for an element and one of its // ancestors, the inner-most create-target is used static const unsigned int LINKFLAG_RECURSIVE = 0x00000008; // if set, directories are linked recursively +static const unsigned int LINKFLAG_FAILIFSKIPPED = 0x00000010; // if set, linking fails if the file or directory is skipped extern "C" { diff --git a/src/usvfs_dll/hookcontext.cpp b/src/usvfs_dll/hookcontext.cpp index aca64016..0a75faaa 100644 --- a/src/usvfs_dll/hookcontext.cpp +++ b/src/usvfs_dll/hookcontext.cpp @@ -234,11 +234,9 @@ void usvfs::HookContext::clearSkipFileSuffixes() m_Parameters->clearSkipFileSuffixes(); } -BOOL usvfs::HookContext::fileShouldBeSkipped(const std::wstring& wFilename) const +std::vector usvfs::HookContext::skipFileSuffixes() const { - const std::string filename = ush::string_cast(wFilename, ush::CodePage::UTF8); - - return m_Parameters->fileShouldBeSkipped(filename); + return m_Parameters->skipFileSuffixes(); } void usvfs::HookContext::addSkipDirectory(const std::wstring& directory) @@ -259,11 +257,9 @@ void usvfs::HookContext::clearSkipDirectories() m_Parameters->clearSkipDirectories(); } -BOOL usvfs::HookContext::directoryShouldBeSkipped(const std::wstring& wDirectory) const +std::vector usvfs::HookContext::skipDirectories() const { - const std::string directory = ush::string_cast(wDirectory, ush::CodePage::UTF8); - - return m_Parameters->directoryShouldBeSkipped(directory); + return m_Parameters->skipDirectories(); } void HookContext::forceLoadLibrary( diff --git a/src/usvfs_dll/hookcontext.h b/src/usvfs_dll/hookcontext.h index 6b2c29f2..e28af1de 100644 --- a/src/usvfs_dll/hookcontext.h +++ b/src/usvfs_dll/hookcontext.h @@ -146,11 +146,11 @@ class HookContext void addSkipFileSuffix(const std::wstring& fileSuffix); void clearSkipFileSuffixes(); - BOOL HookContext::fileShouldBeSkipped(const std::wstring& wFilename) const; + std::vector skipFileSuffixes() const; void addSkipDirectory(const std::wstring& directory); void clearSkipDirectories(); - BOOL HookContext::directoryShouldBeSkipped(const std::wstring& wDirectory) const; + std::vector skipDirectories () const; void forceLoadLibrary(const std::wstring &processName, const std::wstring &libraryPath); void clearLibraryForceLoads(); diff --git a/src/usvfs_dll/sharedparameters.cpp b/src/usvfs_dll/sharedparameters.cpp index 29f4c4b0..fa468b3c 100644 --- a/src/usvfs_dll/sharedparameters.cpp +++ b/src/usvfs_dll/sharedparameters.cpp @@ -214,18 +214,10 @@ void SharedParameters::clearSkipFileSuffixes() m_fileSuffixSkipList.clear(); } -bool SharedParameters::fileShouldBeSkipped(const std::string& file) const +std::vector SharedParameters::skipFileSuffixes() const { bi::scoped_lock lock(m_mutex); - - for (const auto& skipFileSuffix : m_fileSuffixSkipList) { - if (boost::algorithm::iends_with(file, skipFileSuffix)) { - spdlog::get("usvfs")->debug("file '{}' should be skipped, matches file suffix '{}'", file, skipFileSuffix); - return true; - } - } - - return false; + return { m_fileSuffixSkipList.begin(), m_fileSuffixSkipList.end() }; } void SharedParameters::addSkipDirectory(const std::string& directory) @@ -242,18 +234,10 @@ void SharedParameters::clearSkipDirectories() m_directorySkipList.clear(); } -bool SharedParameters::directoryShouldBeSkipped(const std::string& directory) const +std::vector SharedParameters::skipDirectories() const { bi::scoped_lock lock(m_mutex); - - for (const auto& skipDir : m_directorySkipList) { - if (boost::algorithm::equals(directory, skipDir)) { - spdlog::get("usvfs")->debug("directory '{}' should be skipped", directory); - return true; - } - } - - return false; + return { m_directorySkipList.begin(), m_directorySkipList.end() }; } void SharedParameters::addForcedLibrary( diff --git a/src/usvfs_dll/usvfs.cpp b/src/usvfs_dll/usvfs.cpp index 34dd4574..82b779f7 100644 --- a/src/usvfs_dll/usvfs.cpp +++ b/src/usvfs_dll/usvfs.cpp @@ -672,6 +672,33 @@ bool assertPathExists(usvfs::RedirectionTreeContainer &table, LPCWSTR path) return true; } +static bool fileNameInSkipSuffixes(const std::string& fileNameUtf8, + const std::vector& skipFileSuffixes) +{ + for (const auto& skipFileSuffix : skipFileSuffixes) { + if (boost::algorithm::iends_with(fileNameUtf8, skipFileSuffix)) { + spdlog::get("usvfs")->debug( + "file '{}' should be skipped, matches file suffix '{}'", fileNameUtf8, + skipFileSuffix); + return true; + } + } + return false; +} + +static bool fileNameInSkipDirectories(const std::string& directoryNameUtf8, + const std::vector& skipDirectories) +{ + for (const auto& skipDir : skipDirectories) { + if (boost::algorithm::equals(directoryNameUtf8, skipDir)) { + spdlog::get("usvfs")->debug("directory '{}' should be skipped", + directoryNameUtf8); + return true; + } + } + return false; +} + BOOL WINAPI VirtualLinkFile(LPCWSTR source, LPCWSTR destination, unsigned int flags) { @@ -683,8 +710,16 @@ BOOL WINAPI VirtualLinkFile(LPCWSTR source, LPCWSTR destination, return FALSE; } - std::string sourceU8 - = ush::string_cast(source, ush::CodePage::UTF8); + const auto skipFileSuffixes = context->skipFileSuffixes(); + + std::string sourceU8 = ush::string_cast(source, ush::CodePage::UTF8); + + // Check if the file should be skipped + if (fileNameInSkipSuffixes(sourceU8, skipFileSuffixes)) { + // return false when we want to fail when the file is skipped + return (flags & LINKFLAG_FAILIFSKIPPED) ? FALSE : TRUE; + } + auto res = context->redirectionTable().addFile( bfs::path(destination), usvfs::RedirectionDataLocal(sourceU8), !(flags & LINKFLAG_FAILIFEXISTS)); @@ -728,7 +763,6 @@ static usvfs::shared::TreeFlags convertRedirectionFlags(unsigned int flags) return result; } - BOOL WINAPI VirtualLinkDirectoryStatic(LPCWSTR source, LPCWSTR destination, unsigned int flags) { // TODO change notification not yet implemented @@ -752,6 +786,9 @@ BOOL WINAPI VirtualLinkDirectoryStatic(LPCWSTR source, LPCWSTR destination, unsi usvfs::shared::FLAG_DIRECTORY | convertRedirectionFlags(flags), (flags & LINKFLAG_CREATETARGET) != 0); + const auto skipDirectories = context->skipDirectories(); + const auto skipFileSuffixes = context->skipFileSuffixes(); + if ((flags & LINKFLAG_RECURSIVE) != 0) { std::wstring sourceP(source); std::wstring sourceW = sourceP + L"\\"; @@ -762,15 +799,37 @@ BOOL WINAPI VirtualLinkDirectoryStatic(LPCWSTR source, LPCWSTR destination, unsi for (winapi::ex::wide::FileResult file : winapi::ex::wide::quickFindFiles(sourceP.c_str(), L"*")) { if (file.attributes & FILE_ATTRIBUTE_DIRECTORY) { - if ((file.fileName != L".") && (file.fileName != L"..") && !context->directoryShouldBeSkipped(file.fileName)) { + if ((file.fileName != L".") && (file.fileName != L"..")) { + + const auto nameU8 = ush::string_cast(file.fileName.c_str(), + ush::CodePage::UTF8); + // Check if the directory should be skipped + if (fileNameInSkipDirectories(nameU8, skipDirectories)) { + // Fail if we desire to fail when a dir/file is skipped + if (flags & LINKFLAG_FAILIFSKIPPED) { + spdlog::get("usvfs")->debug("directory skipped, failing as defined by link flags"); + return FALSE; + } + + continue; + } VirtualLinkDirectoryStatic((sourceW + file.fileName).c_str(), - (destinationW + file.fileName).c_str(), - flags); + (destinationW + file.fileName).c_str(), flags); + } + } else { + const auto nameU8 = ush::string_cast(file.fileName.c_str(), ush::CodePage::UTF8); + + // Check if the file should be skipped + if (fileNameInSkipSuffixes(nameU8, skipFileSuffixes)) { + // Fail if we desire to fail when a dir/file is skipped + if (flags & LINKFLAG_FAILIFSKIPPED) { + spdlog::get("usvfs")->debug("file skipped, failing as defined by link flags"); + return FALSE; + } + + continue; } - } else if (!context->fileShouldBeSkipped(file.fileName)) { - std::string nameU8 = ush::string_cast( - file.fileName.c_str(), ush::CodePage::UTF8); // TODO could save memory here by storing only the file name for the // source and constructing the full name using the parent directory From 0eaa734ae151238669bdd2b89a4992831329c8f2 Mon Sep 17 00:00:00 2001 From: Twinki Date: Sat, 1 Jun 2024 19:03:55 -0400 Subject: [PATCH 09/10] log tweaks --- src/usvfs_dll/usvfs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/usvfs_dll/usvfs.cpp b/src/usvfs_dll/usvfs.cpp index 82b779f7..b84c85bf 100644 --- a/src/usvfs_dll/usvfs.cpp +++ b/src/usvfs_dll/usvfs.cpp @@ -807,7 +807,7 @@ BOOL WINAPI VirtualLinkDirectoryStatic(LPCWSTR source, LPCWSTR destination, unsi if (fileNameInSkipDirectories(nameU8, skipDirectories)) { // Fail if we desire to fail when a dir/file is skipped if (flags & LINKFLAG_FAILIFSKIPPED) { - spdlog::get("usvfs")->debug("directory skipped, failing as defined by link flags"); + spdlog::get("usvfs")->debug("directory '{}' skipped, failing as defined by link flags", nameU8); return FALSE; } @@ -824,7 +824,7 @@ BOOL WINAPI VirtualLinkDirectoryStatic(LPCWSTR source, LPCWSTR destination, unsi if (fileNameInSkipSuffixes(nameU8, skipFileSuffixes)) { // Fail if we desire to fail when a dir/file is skipped if (flags & LINKFLAG_FAILIFSKIPPED) { - spdlog::get("usvfs")->debug("file skipped, failing as defined by link flags"); + spdlog::get("usvfs")->debug("file '{}' skipped, failing as defined by link flags", nameU8); return FALSE; } From 0f6c464bba4a80db3c50993ab3ed13a0032448cd Mon Sep 17 00:00:00 2001 From: Twinki Date: Mon, 3 Jun 2024 18:19:31 -0400 Subject: [PATCH 10/10] comments --- include/usvfs.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/usvfs.h b/include/usvfs.h index 8490cd1c..ca0350a5 100644 --- a/include/usvfs.h +++ b/include/usvfs.h @@ -50,7 +50,9 @@ static const unsigned int LINKFLAG_CREATETARGET = 0x00000004; // if set, file // ancestors, the inner-most create-target is used static const unsigned int LINKFLAG_RECURSIVE = 0x00000008; // if set, directories are linked recursively static const unsigned int LINKFLAG_FAILIFSKIPPED = 0x00000010; // if set, linking fails if the file or directory is skipped - + // files or directories are skipped depending on whats been added to + // the skip file suffixes or skip directories list in + // the sharedparameters class, those lists are checked during virtual linking extern "C" {