Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add File & Directory skipping #61

Merged
merged 12 commits into from
Jun 8, 2024
41 changes: 41 additions & 0 deletions .clang-format
Twinki14 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -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']
16 changes: 16 additions & 0 deletions include/sharedparameters.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::string> forcedLibraries(const std::string& processName);
void clearForcedLibraries();
Expand All @@ -77,6 +85,12 @@ class DLLEXPORT SharedParameters
using ProcessList = boost::container::flat_set<
DWORD, std::less<DWORD>, DWORDAllocatorT>;

using FileSuffixSkipList = boost::container::flat_set<
shared::StringT, std::less<shared::StringT>, StringAllocatorT>;

using DirectorySkipList = boost::container::flat_set<
shared::StringT, std::less<shared::StringT>, StringAllocatorT>;

using ForcedLibraries = boost::container::slist<
ForcedLibrary, ForcedLibraryAllocatorT>;

Expand All @@ -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;
};

Expand Down
24 changes: 24 additions & 0 deletions include/usvfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Twinki14 marked this conversation as resolved.
Show resolved Hide resolved

/**
* 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
Twinki14 marked this conversation as resolved.
Show resolved Hide resolved
*/
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
Expand Down
50 changes: 50 additions & 0 deletions src/usvfs_dll/hookcontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::string>(fileSuffix, shared::CodePage::UTF8);

if (fsuffix.empty()) {
return;
}

spdlog::get("usvfs")->debug("skipping files with the suffix '{}'", fsuffix);
Twinki14 marked this conversation as resolved.
Show resolved Hide resolved
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<std::string>(wFilename, ush::CodePage::UTF8);
Al12rs marked this conversation as resolved.
Show resolved Hide resolved

return m_Parameters->fileShouldBeSkipped(filename);
}

void usvfs::HookContext::addSkipDirectory(const std::wstring& directory)
{
const auto dir = shared::string_cast<std::string>(directory, shared::CodePage::UTF8);
Al12rs marked this conversation as resolved.
Show resolved Hide resolved

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<std::string>(wDirectory, ush::CodePage::UTF8);

return m_Parameters->directoryShouldBeSkipped(directory);
}

void HookContext::forceLoadLibrary(
const std::wstring& wprocess, const std::wstring& wpath)
{
Expand Down
8 changes: 8 additions & 0 deletions src/usvfs_dll/hookcontext.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::wstring> librariesToForceLoad(const std::wstring &processName);
Expand Down
78 changes: 78 additions & 0 deletions src/usvfs_dll/sharedparameters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
}
Expand Down Expand Up @@ -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;
Twinki14 marked this conversation as resolved.
Show resolved Hide resolved

{
bi::scoped_lock lock(m_mutex);

for (const shared::StringT& skipFileSuffix : m_fileSuffixSkipList) {
Twinki14 marked this conversation as resolved.
Show resolved Hide resolved
if (boost::algorithm::iends_with(file, skipFileSuffix)) {
skipFile = true;
Twinki14 marked this conversation as resolved.
Show resolved Hide resolved
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) {
Twinki14 marked this conversation as resolved.
Show resolved Hide resolved
if (boost::algorithm::equals(directory, skipDir)) {
skip = true;
Twinki14 marked this conversation as resolved.
Show resolved Hide resolved
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)
{
Expand Down
33 changes: 33 additions & 0 deletions src/usvfs_dll/usvfs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Twinki14 marked this conversation as resolved.
Show resolved Hide resolved
continue;
}

VirtualLinkDirectoryStatic((sourceW + file.fileName).c_str(),
(destinationW + file.fileName).c_str(),
flags);
Expand All @@ -771,6 +776,10 @@ BOOL WINAPI VirtualLinkDirectoryStatic(LPCWSTR source, LPCWSTR destination, unsi
std::string nameU8 = ush::string_cast<std::string>(
file.fileName.c_str(), ush::CodePage::UTF8);

if (context->fileShouldBeSkipped(file.fileName)) {
Twinki14 marked this conversation as resolved.
Show resolved Hide resolved
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(
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion vsbuild/external_dependencies.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<Import Project="external_dependencies_local.props" Condition="Exists('external_dependencies_local.props')"/>
</ImportGroup>
<PropertyGroup Label="UserMacros">
<BOOST_PATH Condition="'$(BOOST_PATH)'==''">..\..\boost_1_79_0</BOOST_PATH>
<BOOST_PATH Condition="'$(BOOST_PATH)'==''">..\..\boost_1_85_0</BOOST_PATH>
<BOOST_PATH Condition="'$(BOOST_PATH)'!=''">$(BOOST_PATH)</BOOST_PATH>
<GTEST_PATH Condition="'$(GTEST_PATH)'==''">..\..\googletest</GTEST_PATH>
</PropertyGroup>
Expand Down