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
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
28 changes: 28 additions & 0 deletions include/usvfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,34 @@ 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 usvfsAddSkipFileSuffix(LPWSTR fileSuffix);

/**
* clears the file suffix skip-list
*/
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,
* regardless of it's path, for example if .git is added,
* any sub-path or root-path containing a .git directory
* will have the .git directory skipped during directory linking
* @param directory name of the directory
*/
DLLEXPORT VOID WINAPI usvfsAddSkipDirectory(LPWSTR directory);

/**
* clears the directory skip-list
*/
DLLEXPORT VOID WINAPI usvfsClearSkipDirectories();

/**
* 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("added skip file 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<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("added skip directory '{}'", 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
58 changes: 58 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,62 @@ 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
{
bi::scoped_lock lock(m_mutex);
Al12rs marked this conversation as resolved.
Show resolved Hide resolved

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;
}

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
{
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;
}

void SharedParameters::addForcedLibrary(
const std::string& processName, const std::string& libraryPath)
{
Expand Down
29 changes: 27 additions & 2 deletions src/usvfs_dll/usvfs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -762,12 +762,13 @@ 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 ((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)) {
Twinki14 marked this conversation as resolved.
Show resolved Hide resolved
std::string nameU8 = ush::string_cast<std::string>(
file.fileName.c_str(), ush::CodePage::UTF8);

Expand Down Expand Up @@ -878,6 +879,30 @@ VOID WINAPI ClearExecutableBlacklist()
}


VOID WINAPI usvfsAddSkipFileSuffix(LPWSTR fileSuffix)
{
context->addSkipFileSuffix(fileSuffix);
}


VOID WINAPI usvfsClearSkipFileSuffixes()
{
context->clearSkipFileSuffixes();
}


VOID WINAPI usvfsAddSkipDirectory(LPWSTR directory)
{
context->addSkipDirectory(directory);
}


VOID WINAPI usvfsClearSkipDirectories()
{
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