winfsp unit tests and fixes

This commit is contained in:
Scott E. Graves 2024-11-07 08:31:39 -06:00
parent 9562ac2c62
commit 7bc1440b8b

View File

@ -53,7 +53,7 @@ TYPED_TEST(winfsp_test, info_can_get_basic_info) {
FILETIME file_time{};
::GetSystemTimeAsFileTime(&file_time);
auto time_low = ((PLARGE_INTEGER)&file_time)->QuadPart;
auto time_low = reinterpret_cast<PLARGE_INTEGER>(&file_time)->QuadPart;
auto time_high = time_low + 10000 * 10000 /* 10 seconds */;
auto file_path{
@ -137,11 +137,33 @@ TYPED_TEST(winfsp_test, info_can_get_file_name_info) {
::CloseHandle(handle);
}
TYPED_TEST(winfsp_test, info_get_file_name_info_buffer_too_small) {
auto file_path{
utils::path::combine(this->mount_location, {"test_file_2"}),
};
auto handle =
::CreateFileA(file_path.c_str(), GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0);
ASSERT_NE(INVALID_HANDLE_VALUE, handle);
std::array<std::uint8_t, sizeof(FILE_NAME_INFO)> name_info{};
EXPECT_FALSE(
::GetFileInformationByHandleEx(handle, FileNameInfo, name_info.data(),
static_cast<DWORD>(name_info.size())));
EXPECT_EQ(ERROR_MORE_DATA, ::GetLastError());
auto *info = reinterpret_cast<FILE_NAME_INFO *>(name_info.data());
EXPECT_EQ('\\', info->FileName[0U]);
::CloseHandle(handle);
}
TYPED_TEST(winfsp_test, info_can_get_file_info) {
FILETIME file_time{};
::GetSystemTimeAsFileTime(&file_time);
auto time_low = ((PLARGE_INTEGER)&file_time)->QuadPart;
auto time_low = reinterpret_cast<PLARGE_INTEGER>(&file_time)->QuadPart;
auto time_high = time_low + 10000 * 10000 /* 10 seconds */;
auto file_path{
@ -156,14 +178,26 @@ TYPED_TEST(winfsp_test, info_can_get_file_info) {
BY_HANDLE_FILE_INFORMATION file_info{};
EXPECT_TRUE(::GetFileInformationByHandle(handle, &file_info));
EXPECT_LE(time_low, ((PLARGE_INTEGER)&file_info.ftCreationTime)->QuadPart);
EXPECT_GT(time_high, ((PLARGE_INTEGER)&file_info.ftCreationTime)->QuadPart);
EXPECT_LE(
time_low,
reinterpret_cast<PLARGE_INTEGER>(&file_info.ftCreationTime)->QuadPart);
EXPECT_GT(
time_high,
reinterpret_cast<PLARGE_INTEGER>(&file_info.ftCreationTime)->QuadPart);
EXPECT_LE(time_low, ((PLARGE_INTEGER)&file_info.ftLastAccessTime)->QuadPart);
EXPECT_GT(time_high, ((PLARGE_INTEGER)&file_info.ftLastAccessTime)->QuadPart);
EXPECT_LE(
time_low,
reinterpret_cast<PLARGE_INTEGER>(&file_info.ftLastAccessTime)->QuadPart);
EXPECT_GT(
time_high,
reinterpret_cast<PLARGE_INTEGER>(&file_info.ftLastAccessTime)->QuadPart);
EXPECT_LE(time_low, ((PLARGE_INTEGER)&file_info.ftLastWriteTime)->QuadPart);
EXPECT_GT(time_high, ((PLARGE_INTEGER)&file_info.ftLastWriteTime)->QuadPart);
EXPECT_LE(
time_low,
reinterpret_cast<PLARGE_INTEGER>(&file_info.ftLastWriteTime)->QuadPart);
EXPECT_GT(
time_high,
reinterpret_cast<PLARGE_INTEGER>(&file_info.ftLastWriteTime)->QuadPart);
EXPECT_EQ(0U, file_info.nFileSizeHigh);
EXPECT_EQ(0U, file_info.nFileSizeLow);
@ -176,6 +210,199 @@ TYPED_TEST(winfsp_test, info_can_get_file_info) {
::CloseHandle(handle);
}
TYPED_TEST(winfsp_test, info_can_get_file_path) {
auto file_path{
utils::path::combine(this->mount_location, {"test_file_2"}),
};
auto handle =
::CreateFileA(file_path.c_str(), GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0);
ASSERT_NE(INVALID_HANDLE_VALUE, handle);
std::string final_path;
final_path.resize(MAX_PATH + 1U);
auto result = ::GetFinalPathNameByHandleA(
handle, final_path.data(), final_path.size() - 1U,
VOLUME_NAME_NONE | FILE_NAME_OPENED);
auto expected_name{
std::string{"\\repertory\\"} +
utils::string::to_lower(this->mount_location).at(0U) +
"\\test_file_2",
};
EXPECT_EQ(result, static_cast<DWORD>(expected_name.size()));
EXPECT_STREQ(expected_name.c_str(), final_path.c_str());
::CloseHandle(handle);
}
TYPED_TEST(winfsp_test, info_can_set_file_info_attributes_to_hidden) {
auto file_path{
utils::path::combine(this->mount_location, {"test_file_2"}),
};
auto handle =
::CreateFileA(file_path.c_str(), GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0);
ASSERT_NE(INVALID_HANDLE_VALUE, handle);
EXPECT_TRUE(::SetFileAttributesA(file_path.c_str(), FILE_ATTRIBUTE_HIDDEN));
BY_HANDLE_FILE_INFORMATION file_info{};
EXPECT_TRUE(::GetFileInformationByHandle(handle, &file_info));
EXPECT_EQ(FILE_ATTRIBUTE_HIDDEN, file_info.dwFileAttributes);
::CloseHandle(handle);
}
TYPED_TEST(
winfsp_test,
info_can_set_file_info_attributes_to_hidden_ignoring_directory_attribute) {
auto file_path{
utils::path::combine(this->mount_location, {"test_file_2"}),
};
auto handle =
::CreateFileA(file_path.c_str(), GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0);
ASSERT_NE(INVALID_HANDLE_VALUE, handle);
EXPECT_TRUE(::SetFileAttributesA(
file_path.c_str(), FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_HIDDEN));
BY_HANDLE_FILE_INFORMATION file_info{};
EXPECT_TRUE(::GetFileInformationByHandle(handle, &file_info));
EXPECT_EQ(FILE_ATTRIBUTE_HIDDEN, file_info.dwFileAttributes);
::CloseHandle(handle);
}
TYPED_TEST(winfsp_test, info_can_set_creation_file_time) {
auto file_path{
utils::path::combine(this->mount_location, {"test_file_2"}),
};
auto handle =
::CreateFileA(file_path.c_str(), GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0);
ASSERT_NE(INVALID_HANDLE_VALUE, handle);
BY_HANDLE_FILE_INFORMATION orig_file_info{};
EXPECT_TRUE(::GetFileInformationByHandle(handle, &orig_file_info));
static constexpr const UINT64 file_time{
116444736000000000ULL + 0x4200000042ULL,
};
EXPECT_TRUE(::SetFileTime(handle,
reinterpret_cast<const FILETIME *>(&file_time),
nullptr, nullptr));
BY_HANDLE_FILE_INFORMATION file_info{};
EXPECT_TRUE(::GetFileInformationByHandle(handle, &file_info));
EXPECT_EQ(file_time, *reinterpret_cast<PUINT64>(&file_info.ftCreationTime));
EXPECT_EQ(*reinterpret_cast<PUINT64>(&orig_file_info.ftLastAccessTime),
*reinterpret_cast<PUINT64>(&file_info.ftLastAccessTime));
EXPECT_EQ(*reinterpret_cast<PUINT64>(&orig_file_info.ftLastWriteTime),
*reinterpret_cast<PUINT64>(&file_info.ftLastWriteTime));
::CloseHandle(handle);
}
TYPED_TEST(winfsp_test, info_can_set_accessed_file_time) {
auto file_path{
utils::path::combine(this->mount_location, {"test_file_2"}),
};
auto handle =
::CreateFileA(file_path.c_str(), GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0);
ASSERT_NE(INVALID_HANDLE_VALUE, handle);
BY_HANDLE_FILE_INFORMATION orig_file_info{};
EXPECT_TRUE(::GetFileInformationByHandle(handle, &orig_file_info));
static constexpr const UINT64 file_time{
116444736000000000ULL + 0x4200000042ULL,
};
EXPECT_TRUE(::SetFileTime(handle, nullptr,
reinterpret_cast<const FILETIME *>(&file_time),
nullptr));
BY_HANDLE_FILE_INFORMATION file_info{};
EXPECT_TRUE(::GetFileInformationByHandle(handle, &file_info));
EXPECT_EQ(file_time, *reinterpret_cast<PUINT64>(&file_info.ftLastAccessTime));
EXPECT_EQ(*reinterpret_cast<PUINT64>(&orig_file_info.ftCreationTime),
*reinterpret_cast<PUINT64>(&file_info.ftCreationTime));
EXPECT_EQ(*reinterpret_cast<PUINT64>(&orig_file_info.ftLastWriteTime),
*reinterpret_cast<PUINT64>(&file_info.ftLastWriteTime));
::CloseHandle(handle);
}
TYPED_TEST(winfsp_test, info_can_set_written_file_time) {
auto file_path{
utils::path::combine(this->mount_location, {"test_file_2"}),
};
auto handle =
::CreateFileA(file_path.c_str(), GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0);
ASSERT_NE(INVALID_HANDLE_VALUE, handle);
BY_HANDLE_FILE_INFORMATION orig_file_info{};
EXPECT_TRUE(::GetFileInformationByHandle(handle, &orig_file_info));
static constexpr const UINT64 file_time{
116444736000000000ULL + 0x4200000042ULL,
};
EXPECT_TRUE(::SetFileTime(handle, nullptr, nullptr,
reinterpret_cast<const FILETIME *>(&file_time)));
BY_HANDLE_FILE_INFORMATION file_info{};
EXPECT_TRUE(::GetFileInformationByHandle(handle, &file_info));
EXPECT_EQ(file_time, *reinterpret_cast<PUINT64>(&file_info.ftLastWriteTime));
EXPECT_EQ(*reinterpret_cast<PUINT64>(&orig_file_info.ftLastAccessTime),
*reinterpret_cast<PUINT64>(&file_info.ftLastAccessTime));
EXPECT_EQ(*reinterpret_cast<PUINT64>(&orig_file_info.ftCreationTime),
*reinterpret_cast<PUINT64>(&file_info.ftCreationTime));
::CloseHandle(handle);
}
TYPED_TEST(winfsp_test, info_can_set_file_size) {
auto file_path{
utils::path::combine(this->mount_location, {"test_file_2"}),
};
auto handle =
::CreateFileA(file_path.c_str(), GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0);
ASSERT_NE(INVALID_HANDLE_VALUE, handle);
auto offset = ::SetFilePointer(handle, 42, nullptr, FILE_BEGIN);
EXPECT_EQ(42U, offset);
EXPECT_TRUE(::SetEndOfFile(handle));
BY_HANDLE_FILE_INFORMATION file_info{};
EXPECT_TRUE(::GetFileInformationByHandle(handle, &file_info));
EXPECT_EQ(0U, file_info.nFileSizeHigh);
EXPECT_EQ(42U, file_info.nFileSizeLow);
::CloseHandle(handle);
}
} // namespace repertory
#endif // defined(_WIN32)