aboutsummaryrefslogtreecommitdiff
path: root/libs/usvfs/test/tvfs_test/main.cpp
diff options
context:
space:
mode:
authorSulfurNitride <SulfurNitride@users.noreply.github.com>2026-04-12 02:40:16 -0500
committerSulfurNitride <SulfurNitride@users.noreply.github.com>2026-04-12 02:40:16 -0500
commitbf7a57fc55493247a624ecfd65e4d73964e7d8d2 (patch)
tree0a4b2d6123672768187a5ab863e63cd3f21bb319 /libs/usvfs/test/tvfs_test/main.cpp
parente0fb66428a9b78b4c326df8d7e30429a5b271d74 (diff)
Remove vendored usvfs and Windows-only usvfs code paths
The Linux port uses its own in-process FUSE VFS (FuseConnector), so usvfs was dead weight: libs/usvfs/ was never built, usvfsconnector.cpp was explicitly REMOVE_ITEM'd from the source list, and every call site was already guarded by #ifdef _WIN32 with a working Linux branch (the Windows build is also broken on this branch, since FUSE3 is a hard find_package dependency). - Drop libs/usvfs/ and src/src/usvfsconnector.{cpp,h} - Collapse #ifdef _WIN32 / usvfs include branches in organizercore, mainwindow, settings, util, spawn - Remove getUsvfsVersionString() and the "usvfs: ..." log field - Remove vfs32/64DLLName APPPARAMs (nothing reads them) - Relabel About dialog "usvfs:" row to "VFS: FUSE 3"
Diffstat (limited to 'libs/usvfs/test/tvfs_test/main.cpp')
-rw-r--r--libs/usvfs/test/tvfs_test/main.cpp585
1 files changed, 0 insertions, 585 deletions
diff --git a/libs/usvfs/test/tvfs_test/main.cpp b/libs/usvfs/test/tvfs_test/main.cpp
deleted file mode 100644
index 7c7998b..0000000
--- a/libs/usvfs/test/tvfs_test/main.cpp
+++ /dev/null
@@ -1,585 +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/>.
-*/
-
-// this file depends on so many stuff that the easiest way is to include
-// pch.h from shared
-#include "pch.h"
-
-#include <test_helpers.h>
-
-#include <fstream>
-#include <iostream>
-
-#include <inject.h>
-#include <stringutils.h>
-#include <windows_sane.h>
-
-#include <spdlog/sinks/stdout_sinks.h>
-#include <spdlog/spdlog.h>
-
-#include <hookcontext.h>
-#include <hooks/kernel32.h>
-#include <hooks/ntdll.h>
-#include <logging.h>
-#include <stringcast.h>
-#include <unicodestring.h>
-#include <usvfs.h>
-
-#include <gmock/gmock-matchers.h>
-#include <gtest/gtest.h>
-
-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";
-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 LPCWSTR REAL_FILEW = L"C:/windows/notepad.exe";
-
-static LPCSTR REAL_DIRA = "C:/windows/Logs";
-static LPCWSTR REAL_DIRW = L"C:/windows/Logs";
-
-static std::shared_ptr<spdlog::logger> logger()
-{
- std::shared_ptr<spdlog::logger> result = spdlog::get("test");
- if (result.get() == nullptr) {
- result = spdlog::stdout_logger_mt("test");
- }
- return result;
-}
-
-auto defaultUsvfsParams(const char* instanceName = "usvfs_test")
-{
- std::unique_ptr<usvfsParameters, decltype(&usvfsFreeParameters)> parameters{
- usvfsCreateParameters(), &usvfsFreeParameters};
-
- usvfsSetInstanceName(parameters.get(), instanceName);
- usvfsSetDebugMode(parameters.get(), true);
- usvfsSetLogLevel(parameters.get(), LogLevel::Debug);
- usvfsSetCrashDumpType(parameters.get(), CrashDumpsType::None);
- usvfsSetCrashDumpPath(parameters.get(), "");
-
- return std::move(parameters);
-}
-
-class USVFSTest : public testing::Test
-{
-public:
- void SetUp()
- {
- SHMLogger::create("usvfs");
- // need to initialize logging in the context of the dll
- usvfsInitLogging();
- }
-
- void TearDown()
- {
- std::array<char, 1024> buffer;
- while (SHMLogger::instance().tryGet(buffer.data(), buffer.size())) {
- std::cout << buffer.data() << std::endl;
- }
- SHMLogger::free();
- }
-
-private:
-};
-
-class USVFSTestWithReroute : public testing::Test
-{
-public:
- 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<std::string>(VIRTUAL_FILEW, ush::CodePage::UTF8).c_str(),
- usvfs::RedirectionDataLocal(REAL_FILEA));
- }
-
- void TearDown()
- {
- std::array<char, 1024> buffer;
- while (SHMLogger::instance().tryGet(buffer.data(), buffer.size())) {
- std::cout << buffer.data() << std::endl;
- }
- m_Context.reset();
- SHMLogger::free();
- }
-
-private:
- std::unique_ptr<usvfs::HookContext> m_Context;
-};
-
-class USVFSTestAuto : public testing::Test
-{
-public:
- void SetUp()
- {
- auto params = defaultUsvfsParams();
- usvfsConnectVFS(params.get());
- SHMLogger::create("usvfs");
- }
-
- void TearDown()
- {
- usvfsDisconnectVFS();
-
- std::array<char, 1024> buffer;
- while (SHMLogger::instance().tryGet(buffer.data(), buffer.size())) {
- std::cout << buffer.data() << std::endl;
- }
- SHMLogger::free();
- }
-
-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);
- }
- }
-
- 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);
- });
-}
-
-/*
-TEST_F(USVFSTest, CreateFileHookReportsCorrectErrorOnMissingFile)
-{
- ASSERT_NO_THROW({
- USVFSParameters params;
- USVFSInitParameters(&params, "usvfs_test", true, LogLevel::Debug,
-CrashDumpsType::None, ""); std::unique_ptr<usvfs::HookContext>
-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());
- });
-}
-*/
-
-/*
-TEST_F(USVFSTestWithReroute, CreateFileHookRedirectsFile)
-{
- ASSERT_NE(INVALID_HANDLE_VALUE
- , usvfs::hook_CreateFileW(VIRTUAL_FILEW
- , GENERIC_READ
- , FILE_SHARE_READ | FILE_SHARE_WRITE
- , nullptr
- , OPEN_EXISTING
- , FILE_ATTRIBUTE_NORMAL
- , nullptr));
-}
-*/
-
-TEST_F(USVFSTest, GetFileAttributesHookReportsCorrectErrorOnMissingFile)
-{
- ASSERT_NO_THROW({
- try {
- auto params = defaultUsvfsParams();
- std::unique_ptr<usvfs::HookContext> 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());
- } catch (const std::exception& e) {
- logger()->error("Exception: {}", e.what());
- throw;
- }
- });
-}
-
-TEST_F(USVFSTest, GetFileAttributesHookRedirectsFile)
-{
- auto params = defaultUsvfsParams();
- std::unique_ptr<usvfs::HookContext> ctx(
- usvfsCreateHookContext(*params, ::GetModuleHandle(nullptr)));
- usvfs::RedirectionTreeContainer& tree = ctx->redirectionTable();
-
- tree.addFile(
- ush::string_cast<std::string>(VIRTUAL_FILEW, ush::CodePage::UTF8).c_str(),
- usvfs::RedirectionDataLocal(REAL_FILEA));
-
- ASSERT_EQ(::GetFileAttributesW(REAL_FILEW),
- usvfs::hook_GetFileAttributesW(VIRTUAL_FILEW));
-}
-/*
-TEST_F(USVFSTest, GetFullPathNameOnRegularCurrentDirectory)
-{
- USVFSParameters params;
- USVFSInitParameters(&params, "usvfs_test", true, LogLevel::Debug,
-CrashDumpsType::None, ""); std::unique_ptr<usvfs::HookContext>
-ctx(CreateHookContext(params, ::GetModuleHandle(nullptr)));
-
- std::wstring expected = winapi::wide::getCurrentDirectory() + L"\\filename.txt";
-
- DWORD bufferLength = 32767;
- std::unique_ptr<wchar_t[]> buffer(new wchar_t[bufferLength]);
- LPWSTR filePart = nullptr;
-
- DWORD res = usvfs::hook_GetFullPathNameW(L"filename.txt", bufferLength, buffer.get(),
-&filePart);
-
- ASSERT_NE(0UL, res);
- ASSERT_EQ(expected, std::wstring(buffer.get()));
-}*/
-
-// 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,
-// 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)
-{
- constexpr size_t BUFFER_SIZE = 2048;
- IO_STATUS_BLOCK statusBlock;
- OBJECT_ATTRIBUTES attributes;
- attributes.SecurityDescriptor = 0;
- attributes.SecurityQualityOfService = 0;
- attributes.RootDirectory = 0;
- attributes.Attributes = 0;
- attributes.Length = sizeof(OBJECT_ATTRIBUTES);
-
- WCHAR stringBuffer[BUFFER_SIZE];
- UNICODE_STRING string;
- string.Buffer = stringBuffer;
- lstrcpyW(stringBuffer, L"\\??\\");
- lstrcatW(stringBuffer, path);
- string.Length = static_cast<USHORT>(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) {
- return INVALID_HANDLE_VALUE;
- }
-
- return ret;
-}
-
-TEST_F(USVFSTest, NtQueryDirectoryFileRegularFile)
-{
- auto params = defaultUsvfsParams();
- std::unique_ptr<usvfs::HookContext> 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);
- 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);
-
- ASSERT_EQ(STATUS_SUCCESS, status.Status);
-
- usvfs::hook_NtClose(hdl);
-}
-
-TEST_F(USVFSTest, NtQueryDirectoryFileFindsVirtualFile)
-{
- auto params = defaultUsvfsParams();
- std::unique_ptr<usvfs::HookContext> 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);
- ASSERT_NE(INVALID_HANDLE_VALUE, hdl);
-
- IO_STATUS_BLOCK status;
- char buffer[1024];
-
- usvfs::UnicodeString fileName(L"np.exe");
-
- usvfs::hook_NtQueryDirectoryFile(hdl, nullptr, nullptr, nullptr, &status, buffer,
- 1024, FileDirectoryInformation, TRUE,
- static_cast<PUNICODE_STRING>(fileName), TRUE);
-
- FILE_DIRECTORY_INFORMATION* info =
- reinterpret_cast<FILE_DIRECTORY_INFORMATION*>(buffer);
- ASSERT_EQ(STATUS_SUCCESS, status.Status);
- ASSERT_EQ(0, wcscmp(info->FileName, L"np.exe"));
-
- usvfs::hook_NtClose(hdl);
-}
-
-TEST_F(USVFSTest, NtQueryDirectoryFileExVirtualFile)
-{
- auto params = defaultUsvfsParams();
- std::unique_ptr<usvfs::HookContext> ctx(
- usvfsCreateHookContext(*params, ::GetModuleHandle(nullptr)));
- usvfs::RedirectionTreeContainer& tree = ctx->redirectionTable();
-
- tree.addFile(L"C:\\0123456789.txt", usvfs::RedirectionDataLocal(REAL_FILEA));
- tree.addFile(L"C:\\123456", usvfs::RedirectionDataLocal(REAL_FILEA));
- tree.addFile(L"C:\\abcdef", usvfs::RedirectionDataLocal(REAL_FILEA));
- tree.addFile(L"C:\\abcdefghijklmnopqrstuvwxyz.txt",
- 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);
- ASSERT_NE(INVALID_HANDLE_VALUE, hdl);
-
- IO_STATUS_BLOCK status;
-
- constexpr size_t BUFFER_SIZE = 2048;
- char buffer[BUFFER_SIZE];
-
- std::vector<std::wstring> foundFiles;
- while (usvfs::hook_NtQueryDirectoryFileEx(
- hdl, nullptr, nullptr, nullptr, &status, buffer, BUFFER_SIZE,
- FileFullDirectoryInformation, 0, nullptr) == STATUS_SUCCESS) {
- std::size_t offset = 0;
- while (offset < BUFFER_SIZE) {
- const auto* info = reinterpret_cast<FILE_FULL_DIR_INFORMATION*>(buffer + offset);
- foundFiles.emplace_back(info->FileName, info->FileNameLength / sizeof(wchar_t));
-
- if (info->NextEntryOffset == 0) {
- break; // no more entries
- }
-
- offset += info->NextEntryOffset;
- }
- }
-
- ASSERT_THAT(foundFiles,
- ::testing::IsSupersetOf({L"0123456789.txt", L"123456", L"abcdef",
- L"abcdefghijklmnopqrstuvwxyz.txt"}));
-
- usvfs::hook_NtClose(hdl);
-}
-
-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<OBJECT_NAME_INFORMATION*>(buffer);
-
- c_drive_device =
- std::wstring(information->Name.Buffer, information->Name.Length / 2);
-
- ::CloseHandle(hdl);
- }
-
- auto params = defaultUsvfsParams();
- std::unique_ptr<usvfs::HookContext> 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:\\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();
-
- {
- char buffer[1024];
- IO_STATUS_BLOCK status;
- const auto res = usvfs::hook_NtQueryInformationFile(
- hdl, &status, buffer, sizeof(buffer), FileNameInformation);
- ASSERT_EQ(STATUS_SUCCESS, res);
- ASSERT_EQ(STATUS_SUCCESS, status.Status);
-
- FILE_NAME_INFORMATION* fileNameInfo =
- reinterpret_cast<FILE_NAME_INFORMATION*>(buffer);
- ASSERT_EQ(L"\\np.exe",
- std::wstring(fileNameInfo->FileName, fileNameInfo->FileNameLength / 2));
- }
-
- {
- char buffer[1024];
- IO_STATUS_BLOCK status;
- const auto res = usvfs::hook_NtQueryInformationFile(
- hdl, &status, buffer, sizeof(buffer), FileNormalizedNameInformation);
- ASSERT_EQ(STATUS_SUCCESS, res);
- ASSERT_EQ(STATUS_SUCCESS, status.Status);
- ASSERT_EQ(sizeof(ULONG) + 7 * 2, status.Information);
-
- FILE_NAME_INFORMATION* fileNameInfo =
- reinterpret_cast<FILE_NAME_INFORMATION*>(buffer);
- ASSERT_EQ(L"\\np.exe",
- std::wstring(fileNameInfo->FileName, fileNameInfo->FileNameLength / 2));
- }
-
- // buffer of size should be too small for the original path (\Windows\notepad.exe)
- // but not for \np.exe
- {
- // the required size should be sizeof(ULONG) + 7 * 2 but apparently that is
- // not enough for the CI so using 16 * 2 which should be large enough for
- // the hooked version, but still too short for the non-hooked one
- char buffer[sizeof(ULONG) + 7 * 2];
- IO_STATUS_BLOCK status;
- NTSTATUS res;
-
- res = ::NtQueryInformationFile(hdl, &status, buffer, sizeof(buffer),
- FileNameInformation);
- ASSERT_EQ(STATUS_BUFFER_OVERFLOW, res);
- ASSERT_EQ(STATUS_BUFFER_OVERFLOW, status.Status);
-
- res = usvfs::hook_NtQueryInformationFile(hdl, &status, buffer, sizeof(buffer),
- FileNameInformation);
- ASSERT_EQ(STATUS_SUCCESS, res);
- ASSERT_EQ(STATUS_SUCCESS, status.Status);
- ASSERT_EQ(sizeof(ULONG) + 7 * 2, status.Information);
-
- FILE_NAME_INFORMATION* fileNameInfo =
- reinterpret_cast<FILE_NAME_INFORMATION*>(buffer);
- ASSERT_EQ(L"\\np.exe",
- std::wstring(fileNameInfo->FileName, fileNameInfo->FileNameLength / 2));
- }
-
- {
- char buffer[2048];
- const auto res = usvfs::hook_NtQueryObject(hdl, ObjectNameInformation, buffer,
- sizeof(buffer), nullptr);
- ASSERT_EQ(STATUS_SUCCESS, res);
-
- OBJECT_NAME_INFORMATION* information =
- reinterpret_cast<OBJECT_NAME_INFORMATION*>(buffer);
- ASSERT_EQ(c_drive_device + L"np.exe",
- std::wstring(information->Name.Buffer,
- information->Name.Length / sizeof(wchar_t)));
- }
-
- {
- // expected length is sizeof struct + size of path (in bytes), including the
- // null-character
- const auto expectedLength =
- sizeof(OBJECT_NAME_INFORMATION) + c_drive_device.size() * 2 + 12 + 2;
- ULONG requiredLength;
- NTSTATUS res;
- char buffer[2048];
-
- res =
- usvfs::hook_NtQueryObject(hdl, ObjectNameInformation, buffer,
- sizeof(OBJECT_NAME_INFORMATION) - 1, &requiredLength);
- ASSERT_EQ(STATUS_INFO_LENGTH_MISMATCH, res);
- ASSERT_EQ(expectedLength, requiredLength);
-
- res = usvfs::hook_NtQueryObject(hdl, ObjectNameInformation, buffer,
- sizeof(OBJECT_NAME_INFORMATION), &requiredLength);
- ASSERT_EQ(STATUS_BUFFER_OVERFLOW, res);
- ASSERT_EQ(expectedLength, requiredLength);
- }
-
- usvfs::hook_NtClose(hdl);
-}
-
-TEST_F(USVFSTestAuto, CannotCreateLinkToFileInNonexistantDirectory)
-{
- 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 outDirCanonizeTest = LR"(C:\.\not/../logs\.\a\.\b\.\c\..\.\..\.\..\)";
- ASSERT_EQ(TRUE, usvfsVirtualLinkFile(REAL_FILEW, outFile, 0));
- ASSERT_EQ(TRUE, usvfsVirtualLinkDirectoryStatic(REAL_DIRW, outDir, 0));
-
- // both file and dir exist and have the correct type
- 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);
-}
-
-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;
- return 1;
- }
-
- // 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);
- int res = RUN_ALL_TESTS();
-
- return res;
-}