diff --git a/test/tvfs_test/main.cpp b/test/tvfs_test/main.cpp
index 553a251..b0cc453 100644
--- a/test/tvfs_test/main.cpp
+++ b/test/tvfs_test/main.cpp
@@ -25,48 +25,44 @@ along with usvfs. If not, see .
#include
-#pragma warning (push, 3)
-#include
+#pragma warning(push, 3)
#include
+#include
#include
-#pragma warning (pop)
-
+#pragma warning(pop)
#include
-#include
#include
+#include
-#include
#include
+#include
#include
-#include
-#include
#include
#include
-#include
#include
-
-
+#include
+#include
+#include
namespace spd = spdlog;
namespace ush = usvfs::shared;
-
-// name of a file to be created in the virtual fs. Shouldn't exist on disc but the directory must exist
-static LPCSTR VIRTUAL_FILEA = "C:/np.exe";
+// name of a file to be created in the virtual fs. Shouldn't exist on disc but the
+// directory must exist
+static LPCSTR VIRTUAL_FILEA = "C:/np.exe";
static LPCWSTR VIRTUAL_FILEW = L"C:/np.exe";
// a real file on disc that has to exist
-static LPCSTR REAL_FILEA = "C:/windows/notepad.exe";
+static LPCSTR REAL_FILEA = "C:/windows/notepad.exe";
static LPCWSTR REAL_FILEW = L"C:/windows/notepad.exe";
-static LPCSTR REAL_DIRA = "C:/windows/Logs";
+static LPCSTR REAL_DIRA = "C:/windows/Logs";
static LPCWSTR REAL_DIRW = L"C:/windows/Logs";
-
static std::shared_ptr logger()
{
std::shared_ptr result = spdlog::get("test");
@@ -76,9 +72,10 @@ static std::shared_ptr logger()
return result;
}
-auto defaultUsvfsParams(const char* instanceName = "usvfs_test") {
- std::unique_ptr parameters{
- usvfsCreateParameters(), &usvfsFreeParameters };
+auto defaultUsvfsParams(const char* instanceName = "usvfs_test")
+{
+ std::unique_ptr parameters{
+ usvfsCreateParameters(), &usvfsFreeParameters};
usvfsSetInstanceName(parameters.get(), instanceName);
usvfsSetDebugMode(parameters.get(), true);
@@ -92,13 +89,15 @@ auto defaultUsvfsParams(const char* instanceName = "usvfs_test") {
class USVFSTest : public testing::Test
{
public:
- void SetUp() {
+ void SetUp()
+ {
SHMLogger::create("usvfs");
// need to initialize logging in the context of the dll
usvfsInitLogging();
}
- void TearDown() {
+ void TearDown()
+ {
std::array buffer;
while (SHMLogger::instance().tryGet(buffer.data(), buffer.size())) {
std::cout << buffer.data() << std::endl;
@@ -112,19 +111,22 @@ class USVFSTest : public testing::Test
class USVFSTestWithReroute : public testing::Test
{
public:
- void SetUp() {
+ void SetUp()
+ {
SHMLogger::create("usvfs");
// need to initialize logging in the context of the dll
usvfsInitLogging();
auto params = defaultUsvfsParams();
m_Context.reset(usvfsCreateHookContext(*params, ::GetModuleHandle(nullptr)));
- usvfs::RedirectionTreeContainer &tree = m_Context->redirectionTable();
- tree.addFile(ush::string_cast(VIRTUAL_FILEW, ush::CodePage::UTF8).c_str()
- , usvfs::RedirectionDataLocal(REAL_FILEA));
+ usvfs::RedirectionTreeContainer& tree = m_Context->redirectionTable();
+ tree.addFile(
+ ush::string_cast(VIRTUAL_FILEW, ush::CodePage::UTF8).c_str(),
+ usvfs::RedirectionDataLocal(REAL_FILEA));
}
- void TearDown() {
+ void TearDown()
+ {
std::array buffer;
while (SHMLogger::instance().tryGet(buffer.data(), buffer.size())) {
std::cout << buffer.data() << std::endl;
@@ -132,6 +134,7 @@ class USVFSTestWithReroute : public testing::Test
m_Context.reset();
SHMLogger::free();
}
+
private:
std::unique_ptr m_Context;
};
@@ -139,13 +142,15 @@ class USVFSTestWithReroute : public testing::Test
class USVFSTestAuto : public testing::Test
{
public:
- void SetUp() {
+ void SetUp()
+ {
auto params = defaultUsvfsParams();
usvfsConnectVFS(params.get());
SHMLogger::create("usvfs");
}
- void TearDown() {
+ void TearDown()
+ {
usvfsDisconnectVFS();
std::array buffer;
@@ -158,21 +163,28 @@ class USVFSTestAuto : public testing::Test
private:
};
-
TEST_F(USVFSTest, CanResizeRedirectiontree)
{
using usvfs::shared::MissingThrow;
ASSERT_NO_THROW({
- usvfs::RedirectionTreeContainer container("treetest_shm", 1024);
- for (char i = 'a'; i <= 'z'; ++i) {
- for (char j = 'a'; j <= 'z'; ++j) {
- std::string name = std::string(R"(C:\temp\)") + i + j;
- container.addFile(name, usvfs::RedirectionDataLocal("gaga"), false);
- }
+ usvfs::RedirectionTreeContainer container("treetest_shm", 1024);
+ for (char i = 'a'; i <= 'z'; ++i) {
+ for (char j = 'a'; j <= 'z'; ++j) {
+ std::string name = std::string(R"(C:\temp\)") + i + j;
+ container.addFile(name, usvfs::RedirectionDataLocal("gaga"), false);
}
+ }
- ASSERT_EQ("gaga", container->node("C:")->node("temp")->node("aa", MissingThrow)->data().linkTarget);
- ASSERT_EQ("gaga", container->node("C:")->node("temp")->node("az", MissingThrow)->data().linkTarget);
+ ASSERT_EQ("gaga", container->node("C:")
+ ->node("temp")
+ ->node("aa", MissingThrow)
+ ->data()
+ .linkTarget);
+ ASSERT_EQ("gaga", container->node("C:")
+ ->node("temp")
+ ->node("az", MissingThrow)
+ ->data()
+ .linkTarget);
});
}
@@ -181,15 +193,11 @@ TEST_F(USVFSTest, CreateFileHookReportsCorrectErrorOnMissingFile)
{
ASSERT_NO_THROW({
USVFSParameters params;
- USVFSInitParameters(¶ms, "usvfs_test", true, LogLevel::Debug, CrashDumpsType::None, "");
- std::unique_ptr ctx(CreateHookContext(params, ::GetModuleHandle(nullptr)));
- HANDLE res = usvfs::hook_CreateFileW(VIRTUAL_FILEW
- , GENERIC_READ
- , FILE_SHARE_READ | FILE_SHARE_WRITE
- , nullptr
- , OPEN_EXISTING
- , FILE_ATTRIBUTE_NORMAL
- , nullptr);
+ USVFSInitParameters(¶ms, "usvfs_test", true, LogLevel::Debug,
+CrashDumpsType::None, ""); std::unique_ptr
+ctx(CreateHookContext(params, ::GetModuleHandle(nullptr))); HANDLE res =
+usvfs::hook_CreateFileW(VIRTUAL_FILEW , GENERIC_READ , FILE_SHARE_READ |
+FILE_SHARE_WRITE , nullptr , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , nullptr);
ASSERT_EQ(INVALID_HANDLE_VALUE, res);
ASSERT_EQ(ERROR_FILE_NOT_FOUND, ::GetLastError());
@@ -211,20 +219,20 @@ TEST_F(USVFSTestWithReroute, CreateFileHookRedirectsFile)
}
*/
-
TEST_F(USVFSTest, GetFileAttributesHookReportsCorrectErrorOnMissingFile)
{
ASSERT_NO_THROW({
try {
- auto params = defaultUsvfsParams();
- std::unique_ptr ctx(usvfsCreateHookContext(*params, ::GetModuleHandle(nullptr)));
- DWORD res = usvfs::hook_GetFileAttributesW(VIRTUAL_FILEW);
+ auto params = defaultUsvfsParams();
+ std::unique_ptr ctx(
+ usvfsCreateHookContext(*params, ::GetModuleHandle(nullptr)));
+ DWORD res = usvfs::hook_GetFileAttributesW(VIRTUAL_FILEW);
- ASSERT_EQ(INVALID_FILE_ATTRIBUTES, res);
- ASSERT_EQ(ERROR_FILE_NOT_FOUND, ::GetLastError());
+ ASSERT_EQ(INVALID_FILE_ATTRIBUTES, res);
+ ASSERT_EQ(ERROR_FILE_NOT_FOUND, ::GetLastError());
} catch (const std::exception& e) {
- logger()->error("Exception: {}", e.what());
- throw;
+ logger()->error("Exception: {}", e.what());
+ throw;
}
});
}
@@ -232,21 +240,24 @@ TEST_F(USVFSTest, GetFileAttributesHookReportsCorrectErrorOnMissingFile)
TEST_F(USVFSTest, GetFileAttributesHookRedirectsFile)
{
auto params = defaultUsvfsParams();
- std::unique_ptr ctx(usvfsCreateHookContext(*params, ::GetModuleHandle(nullptr)));
- usvfs::RedirectionTreeContainer &tree = ctx->redirectionTable();
+ std::unique_ptr ctx(
+ usvfsCreateHookContext(*params, ::GetModuleHandle(nullptr)));
+ usvfs::RedirectionTreeContainer& tree = ctx->redirectionTable();
- tree.addFile(ush::string_cast(VIRTUAL_FILEW, ush::CodePage::UTF8).c_str()
- , usvfs::RedirectionDataLocal(REAL_FILEA));
+ tree.addFile(
+ ush::string_cast(VIRTUAL_FILEW, ush::CodePage::UTF8).c_str(),
+ usvfs::RedirectionDataLocal(REAL_FILEA));
- ASSERT_EQ(::GetFileAttributesW(REAL_FILEW)
- , usvfs::hook_GetFileAttributesW(VIRTUAL_FILEW));
+ ASSERT_EQ(::GetFileAttributesW(REAL_FILEW),
+ usvfs::hook_GetFileAttributesW(VIRTUAL_FILEW));
}
/*
TEST_F(USVFSTest, GetFullPathNameOnRegularCurrentDirectory)
{
USVFSParameters params;
- USVFSInitParameters(¶ms, "usvfs_test", true, LogLevel::Debug, CrashDumpsType::None, "");
- std::unique_ptr ctx(CreateHookContext(params, ::GetModuleHandle(nullptr)));
+ USVFSInitParameters(¶ms, "usvfs_test", true, LogLevel::Debug,
+CrashDumpsType::None, ""); std::unique_ptr
+ctx(CreateHookContext(params, ::GetModuleHandle(nullptr)));
std::wstring expected = winapi::wide::getCurrentDirectory() + L"\\filename.txt";
@@ -254,7 +265,8 @@ TEST_F(USVFSTest, GetFullPathNameOnRegularCurrentDirectory)
std::unique_ptr buffer(new wchar_t[bufferLength]);
LPWSTR filePart = nullptr;
- DWORD res = usvfs::hook_GetFullPathNameW(L"filename.txt", bufferLength, buffer.get(), &filePart);
+ DWORD res = usvfs::hook_GetFullPathNameW(L"filename.txt", bufferLength, buffer.get(),
+&filePart);
ASSERT_NE(0UL, res);
ASSERT_EQ(expected, std::wstring(buffer.get()));
@@ -263,37 +275,37 @@ TEST_F(USVFSTest, GetFullPathNameOnRegularCurrentDirectory)
// small wrapper to call usvfs::hook_NtOpenFile with a path
//
// at some point in time, changes were made to USVFS such that calling a hooked
-// function from a handle obtained from a non-hooked function would not work anymore,
+// function from a handle obtained from a non-hooked function would not work anymore,
// meaning that function such as CreateFileW that have no hook equivalent cannot
// be used to test hook functions
-//
+//
// this function is useful to simulate a CreateFileW by internally using the hook
// version of NtOpenFile
//
-HANDLE hooked_NtOpenFile(LPCWSTR path, ACCESS_MASK accessMask, ULONG shareAccess, ULONG openOptions)
+HANDLE hooked_NtOpenFile(LPCWSTR path, ACCESS_MASK accessMask, ULONG shareAccess,
+ ULONG openOptions)
{
constexpr size_t BUFFER_SIZE = 2048;
IO_STATUS_BLOCK statusBlock;
OBJECT_ATTRIBUTES attributes;
- attributes.SecurityDescriptor = 0;
+ attributes.SecurityDescriptor = 0;
attributes.SecurityQualityOfService = 0;
- attributes.RootDirectory = 0;
- attributes.Attributes = 0;
- attributes.Length = sizeof(OBJECT_ATTRIBUTES);
+ attributes.RootDirectory = 0;
+ attributes.Attributes = 0;
+ attributes.Length = sizeof(OBJECT_ATTRIBUTES);
WCHAR stringBuffer[BUFFER_SIZE];
- UNICODE_STRING string;
+ UNICODE_STRING string;
string.Buffer = stringBuffer;
lstrcpyW(stringBuffer, L"\\??\\");
lstrcatW(stringBuffer, path);
- string.Length = lstrlenW(stringBuffer) * 2;
- string.MaximumLength = BUFFER_SIZE;
+ string.Length = lstrlenW(stringBuffer) * 2;
+ string.MaximumLength = BUFFER_SIZE;
attributes.ObjectName = &string;
-
+
HANDLE ret = INVALID_HANDLE_VALUE;
- if (usvfs::hook_NtOpenFile(&ret, accessMask, &attributes,
- &statusBlock, shareAccess, openOptions) != STATUS_SUCCESS)
- {
+ if (usvfs::hook_NtOpenFile(&ret, accessMask, &attributes, &statusBlock, shareAccess,
+ openOptions) != STATUS_SUCCESS) {
return INVALID_HANDLE_VALUE;
}
@@ -303,29 +315,19 @@ HANDLE hooked_NtOpenFile(LPCWSTR path, ACCESS_MASK accessMask, ULONG shareAccess
TEST_F(USVFSTest, NtQueryDirectoryFileRegularFile)
{
auto params = defaultUsvfsParams();
- std::unique_ptr ctx(usvfsCreateHookContext(*params, ::GetModuleHandle(nullptr)));
+ std::unique_ptr ctx(
+ usvfsCreateHookContext(*params, ::GetModuleHandle(nullptr)));
- HANDLE hdl = hooked_NtOpenFile(
- L"C:\\"
- , FILE_GENERIC_READ
- , FILE_SHARE_READ | FILE_SHARE_WRITE
- , FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
+ HANDLE hdl =
+ hooked_NtOpenFile(L"C:\\", FILE_GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
ASSERT_NE(INVALID_HANDLE_VALUE, hdl);
IO_STATUS_BLOCK status;
char buffer[1024];
- usvfs::hook_NtQueryDirectoryFile(hdl
- , nullptr
- , nullptr
- , nullptr
- , &status
- , buffer
- , 1024
- , FileDirectoryInformation
- , TRUE
- , nullptr
- , TRUE);
+ usvfs::hook_NtQueryDirectoryFile(hdl, nullptr, nullptr, nullptr, &status, buffer,
+ 1024, FileDirectoryInformation, TRUE, nullptr, TRUE);
ASSERT_EQ(STATUS_SUCCESS, status.Status);
@@ -335,16 +337,15 @@ TEST_F(USVFSTest, NtQueryDirectoryFileRegularFile)
TEST_F(USVFSTest, NtQueryDirectoryFileFindsVirtualFile)
{
auto params = defaultUsvfsParams();
- std::unique_ptr ctx(usvfsCreateHookContext(*params, ::GetModuleHandle(nullptr)));
- usvfs::RedirectionTreeContainer &tree = ctx->redirectionTable();
+ std::unique_ptr ctx(
+ usvfsCreateHookContext(*params, ::GetModuleHandle(nullptr)));
+ usvfs::RedirectionTreeContainer& tree = ctx->redirectionTable();
tree.addFile(L"C:\\np.exe", usvfs::RedirectionDataLocal(REAL_FILEA));
- HANDLE hdl = hooked_NtOpenFile(
- L"C:\\"
- , FILE_GENERIC_READ
- , FILE_SHARE_READ | FILE_SHARE_WRITE
- , FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
+ HANDLE hdl =
+ hooked_NtOpenFile(L"C:\\", FILE_GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
ASSERT_NE(INVALID_HANDLE_VALUE, hdl);
IO_STATUS_BLOCK status;
@@ -352,19 +353,12 @@ TEST_F(USVFSTest, NtQueryDirectoryFileFindsVirtualFile)
usvfs::UnicodeString fileName(L"np.exe");
- usvfs::hook_NtQueryDirectoryFile(hdl
- , nullptr
- , nullptr
- , nullptr
- , &status
- , buffer
- , 1024
- , FileDirectoryInformation
- , TRUE
- , static_cast(fileName)
- , TRUE);
-
- FILE_DIRECTORY_INFORMATION *info = reinterpret_cast(buffer);
+ usvfs::hook_NtQueryDirectoryFile(hdl, nullptr, nullptr, nullptr, &status, buffer,
+ 1024, FileDirectoryInformation, TRUE,
+ static_cast(fileName), TRUE);
+
+ FILE_DIRECTORY_INFORMATION* info =
+ reinterpret_cast(buffer);
ASSERT_EQ(STATUS_SUCCESS, status.Status);
ASSERT_EQ(0, wcscmp(info->FileName, L"np.exe"));
@@ -373,6 +367,27 @@ TEST_F(USVFSTest, NtQueryDirectoryFileFindsVirtualFile)
TEST_F(USVFSTest, NtQueryObjectVirtualFile)
{
+ std::wstring c_drive_device;
+ {
+ // find the device path for C:
+ HANDLE hdl = ::CreateFileW(
+ L"C:\\", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, nullptr);
+ ASSERT_NE(INVALID_HANDLE_VALUE, hdl);
+
+ char buffer[2048];
+ ASSERT_EQ(STATUS_SUCCESS, ::NtQueryObject(hdl, ObjectNameInformation, buffer,
+ sizeof(buffer), nullptr));
+
+ OBJECT_NAME_INFORMATION* information =
+ reinterpret_cast(buffer);
+
+ c_drive_device =
+ std::wstring(information->Name.Buffer, information->Name.Length / 2);
+
+ ::CloseHandle(hdl);
+ }
+
auto params = defaultUsvfsParams();
std::unique_ptr ctx(
usvfsCreateHookContext(*params, ::GetModuleHandle(nullptr)));
@@ -380,10 +395,9 @@ TEST_F(USVFSTest, NtQueryObjectVirtualFile)
tree.addFile(L"C:\\np.exe", usvfs::RedirectionDataLocal(REAL_FILEA));
- HANDLE hdl = hooked_NtOpenFile(L"C:\\np.exe"
- , FILE_GENERIC_READ
- , FILE_SHARE_READ | FILE_SHARE_WRITE
- , FILE_NON_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT);
+ HANDLE hdl = hooked_NtOpenFile(L"C:\\np.exe", FILE_GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_NON_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT);
ASSERT_NE(INVALID_HANDLE_VALUE, hdl) << "last error=" << ::GetLastError();
{
@@ -416,23 +430,26 @@ TEST_F(USVFSTest, NtQueryObjectVirtualFile)
sizeof(buffer), nullptr);
ASSERT_EQ(STATUS_SUCCESS, res);
- OBJECT_NAME_INFORMATION *information = reinterpret_cast(buffer);
- ASSERT_EQ(L"\\Device\\HarddiskVolume3\\np.exe", std::wstring(information->Name.Buffer, information->Name.Length / sizeof(wchar_t)));
+ OBJECT_NAME_INFORMATION* information =
+ reinterpret_cast(buffer);
+ ASSERT_EQ(c_drive_device + L"np.exe",
+ std::wstring(information->Name.Buffer,
+ information->Name.Length / sizeof(wchar_t)));
}
usvfs::hook_NtClose(hdl);
}
-
TEST_F(USVFSTestAuto, CannotCreateLinkToFileInNonexistantDirectory)
{
- ASSERT_EQ(FALSE, usvfsVirtualLinkFile(REAL_FILEW, L"c:/this_directory_shouldnt_exist/np.exe", FALSE));
+ ASSERT_EQ(FALSE, usvfsVirtualLinkFile(
+ REAL_FILEW, L"c:/this_directory_shouldnt_exist/np.exe", FALSE));
}
TEST_F(USVFSTestAuto, CanCreateMultipleLinks)
{
- static LPCWSTR outFile = LR"(C:\np.exe)";
- static LPCWSTR outDir = LR"(C:\logs)";
+ static LPCWSTR outFile = LR"(C:\np.exe)";
+ static LPCWSTR outDir = LR"(C:\logs)";
static LPCWSTR outDirCanonizeTest = LR"(C:\.\not/../logs\.\a\.\b\.\c\..\.\..\.\..\)";
ASSERT_EQ(TRUE, usvfsVirtualLinkFile(REAL_FILEW, outFile, 0));
ASSERT_EQ(TRUE, usvfsVirtualLinkDirectoryStatic(REAL_DIRW, outDir, 0));
@@ -441,22 +458,25 @@ TEST_F(USVFSTestAuto, CanCreateMultipleLinks)
ASSERT_NE(INVALID_FILE_ATTRIBUTES, usvfs::hook_GetFileAttributesW(outFile));
ASSERT_NE(INVALID_FILE_ATTRIBUTES, usvfs::hook_GetFileAttributesW(outDir));
ASSERT_EQ(0UL, usvfs::hook_GetFileAttributesW(outFile) & FILE_ATTRIBUTE_DIRECTORY);
- ASSERT_NE(0UL, usvfs::hook_GetFileAttributesW(outDir) & FILE_ATTRIBUTE_DIRECTORY);
- ASSERT_NE(0UL, usvfs::hook_GetFileAttributesW(outDirCanonizeTest) & FILE_ATTRIBUTE_DIRECTORY);
+ ASSERT_NE(0UL, usvfs::hook_GetFileAttributesW(outDir) & FILE_ATTRIBUTE_DIRECTORY);
+ ASSERT_NE(0UL, usvfs::hook_GetFileAttributesW(outDirCanonizeTest) &
+ FILE_ATTRIBUTE_DIRECTORY);
}
-int main(int argc, char **argv) {
+int main(int argc, char** argv)
+{
using namespace test;
auto dllPath = path_of_usvfs_lib(platform_dependant_executable("usvfs", "dll"));
ScopedLoadLibrary loadDll(dllPath.c_str());
if (!loadDll) {
- std::wcerr << L"failed to load usvfs dll: " << dllPath.c_str() << L", " << GetLastError() << std::endl;
+ std::wcerr << L"failed to load usvfs dll: " << dllPath.c_str() << L", "
+ << GetLastError() << std::endl;
return 1;
}
- // note: this makes the logger available only to functions statically linked to the test binary, not those
- // called in the dll
+ // note: this makes the logger available only to functions statically linked to the
+ // test binary, not those called in the dll
auto logger = spdlog::stdout_logger_mt("usvfs");
logger->set_level(spdlog::level::warn);
testing::InitGoogleTest(&argc, argv);