From 3338fcf91fe003540a1a53be08085f175701febc Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sat, 9 Nov 2024 11:50:27 -0600 Subject: [PATCH] winfsp unit tests and fixes --- .../src/drives/winfsp/winfsp_drive.cpp | 27 ++- .../src/winfsp_drive_rdrw_test.cpp | 217 ++++++++++-------- 2 files changed, 132 insertions(+), 112 deletions(-) diff --git a/repertory/librepertory/src/drives/winfsp/winfsp_drive.cpp b/repertory/librepertory/src/drives/winfsp/winfsp_drive.cpp index 3ac40e1e..854ab901 100644 --- a/repertory/librepertory/src/drives/winfsp/winfsp_drive.cpp +++ b/repertory/librepertory/src/drives/winfsp/winfsp_drive.cpp @@ -848,6 +848,10 @@ auto winfsp_drive::Read(PVOID /*file_node*/, PVOID file_desc, PVOID buffer, api_path = file->get_api_path(); + if (offset >= file->get_file_size()) { + return STATUS_END_OF_FILE; + } + if (length == 0U) { return handle_error(api_error::success); } @@ -859,19 +863,22 @@ auto winfsp_drive::Read(PVOID /*file_node*/, PVOID file_desc, PVOID buffer, } *bytes_transferred = static_cast(data.size()); - if ((length > 0) && (data.size() != length)) { + + auto short_read = data.size() != length; + + if (not data.empty()) { + ::CopyMemory(buffer, data.data(), data.size()); + data.clear(); + } + + auto ret = handle_error(provider_.set_item_meta( + api_path, META_ACCESSED, std::to_string(utils::time::get_time_now()))); + + if (short_read) { ::SetLastError(ERROR_HANDLE_EOF); } - if (data.empty()) { - return handle_error(api_error::success); - } - - ::CopyMemory(buffer, data.data(), data.size()); - data.clear(); - - return handle_error(provider_.set_item_meta( - api_path, META_ACCESSED, std::to_string(utils::time::get_time_now()))); + return ret; } auto winfsp_drive::ReadDirectory(PVOID /*file_node*/, PVOID file_desc, diff --git a/repertory/repertory_test/src/winfsp_drive_rdrw_test.cpp b/repertory/repertory_test/src/winfsp_drive_rdrw_test.cpp index 2d2a766c..5a7e8932 100644 --- a/repertory/repertory_test/src/winfsp_drive_rdrw_test.cpp +++ b/repertory/repertory_test/src/winfsp_drive_rdrw_test.cpp @@ -290,112 +290,124 @@ static void test_overlapped_file(auto mount_location, auto &&file_path, EXPECT_TRUE(ret || ERROR_IO_PENDING == ::GetLastError()); EXPECT_TRUE(::GetOverlappedResult(handle, &overlapped, &bytes_written, TRUE)); EXPECT_EQ(bytes_per_sector, bytes_written); - // - // Overlapped.Offset = 2 * BytesPerSector; - // Success = WriteFile(Handle, Buffer[0], BytesPerSector, &BytesTransferred, - // &Overlapped); - // ASSERT(Success || ERROR_IO_PENDING == GetLastError()); - // Success = GetOverlappedResult(Handle, &Overlapped, &BytesTransferred, - // TRUE); ASSERT(Success); ASSERT(BytesPerSector == BytesTransferred); - // - // Overlapped.Offset = 0; - // memset(AllocBuffer[1], 0, AllocBufferSize); - // Success = ReadFile(Handle, Buffer[1], BytesPerSector, &BytesTransferred, - // &Overlapped); - // ASSERT(Success || ERROR_IO_PENDING == GetLastError()); - // Success = GetOverlappedResult(Handle, &Overlapped, &BytesTransferred, - // TRUE); ASSERT(Success); ASSERT(BytesPerSector == BytesTransferred); - // ASSERT(0 == memcmp(Buffer[0], Buffer[1], BytesTransferred)); - // - // Overlapped.Offset = 2 * BytesPerSector; - // memset(AllocBuffer[1], 0, AllocBufferSize); - // Success = ReadFile(Handle, Buffer[1], BytesPerSector, &BytesTransferred, - // &Overlapped); - // ASSERT(Success || ERROR_IO_PENDING == GetLastError()); - // Success = GetOverlappedResult(Handle, &Overlapped, &BytesTransferred, - // TRUE); ASSERT(Success); ASSERT(BytesPerSector == BytesTransferred); - // ASSERT(0 == memcmp(Buffer[0], Buffer[1], BytesTransferred)); - // - // Overlapped.Offset = 2 * BytesPerSector; - // memset(AllocBuffer[1], 0, AllocBufferSize); - // Success = ReadFile(Handle, Buffer[1], 2 * BytesPerSector, - // &BytesTransferred, - // &Overlapped); - // ASSERT(Success || ERROR_IO_PENDING == GetLastError()); - // Success = GetOverlappedResult(Handle, &Overlapped, &BytesTransferred, - // TRUE); ASSERT(Success); ASSERT(BytesPerSector == BytesTransferred); - // ASSERT(0 == memcmp(Buffer[0], Buffer[1], BytesTransferred)); - // - // Overlapped.Offset = 3 * BytesPerSector; - // memset(AllocBuffer[1], 0, AllocBufferSize); - // Success = ReadFile(Handle, Buffer[1], BytesPerSector, &BytesTransferred, - // &Overlapped); - // ASSERT(Success || ERROR_IO_PENDING == GetLastError() || - // ERROR_HANDLE_EOF == GetLastError()); - // if (ERROR_HANDLE_EOF != GetLastError()) { - // Success = GetOverlappedResult(Handle, &Overlapped, &BytesTransferred, - // TRUE); ASSERT(!Success && ERROR_HANDLE_EOF == GetLastError()); - // } - // ASSERT(0 == BytesTransferred); - // ASSERT(0 == memcmp(Buffer[0], Buffer[1], BytesTransferred)); - // - // Overlapped.Offset = 0; - // Success = WriteFile(Handle, Buffer[0], 2 * SystemInfo.dwPageSize, - // &BytesTransferred, &Overlapped); - // ASSERT(Success || ERROR_IO_PENDING == GetLastError()); - // Success = GetOverlappedResult(Handle, &Overlapped, &BytesTransferred, - // TRUE); ASSERT(Success); ASSERT(2 * SystemInfo.dwPageSize == + + overlapped.Offset = 2U * bytes_per_sector; + ret = ::WriteFile(handle, write_buffer.data(), bytes_per_sector, + &bytes_written, &overlapped); + EXPECT_TRUE(ret || ERROR_IO_PENDING == ::GetLastError()); + EXPECT_TRUE(::GetOverlappedResult(handle, &overlapped, &bytes_written, TRUE)); + EXPECT_EQ(bytes_per_sector, bytes_written); + + data_buffer read_buffer{}; + read_buffer.resize(buffer_size); + overlapped.Offset = 0U; + DWORD bytes_read{}; + ret = ::ReadFile(handle, read_buffer.data(), bytes_per_sector, &bytes_read, + &overlapped); + + EXPECT_TRUE(ret || ERROR_IO_PENDING == ::GetLastError()); + EXPECT_TRUE(::GetOverlappedResult(handle, &overlapped, &bytes_read, TRUE)); + + EXPECT_EQ(bytes_per_sector, bytes_read); + EXPECT_EQ(0, + std::memcmp(write_buffer.data(), read_buffer.data(), bytes_read)); + + read_buffer.clear(); + read_buffer.resize(buffer_size); + overlapped.Offset = 2U * bytes_per_sector; + ret = ::ReadFile(handle, read_buffer.data(), bytes_per_sector, &bytes_read, + &overlapped); + EXPECT_TRUE(ret || ERROR_IO_PENDING == ::GetLastError()); + EXPECT_TRUE(::GetOverlappedResult(handle, &overlapped, &bytes_read, TRUE)); + EXPECT_EQ(bytes_per_sector, bytes_read); + EXPECT_EQ(0, + std::memcmp(write_buffer.data(), read_buffer.data(), bytes_read)); + + read_buffer.clear(); + read_buffer.resize(buffer_size); + overlapped.Offset = 2U * bytes_per_sector; + ret = ::ReadFile(handle, read_buffer.data(), 2U * bytes_per_sector, + &bytes_read, &overlapped); + EXPECT_TRUE(ret || ERROR_IO_PENDING == ::GetLastError()); + EXPECT_TRUE(::GetOverlappedResult(handle, &overlapped, &bytes_read, TRUE)); + EXPECT_EQ(bytes_per_sector, bytes_read); + EXPECT_EQ(0, + std::memcmp(write_buffer.data(), read_buffer.data(), bytes_read)); + + read_buffer.clear(); + read_buffer.resize(buffer_size); + overlapped.Offset = 3U * bytes_per_sector; + ret = ::ReadFile(handle, read_buffer.data(), bytes_per_sector, &bytes_read, + &overlapped); + EXPECT_TRUE(ret || ERROR_IO_PENDING == ::GetLastError() || + ERROR_HANDLE_EOF == ::GetLastError()); + if (ERROR_HANDLE_EOF != ::GetLastError()) { + ret = ::GetOverlappedResult(handle, &overlapped, &bytes_read, TRUE); + EXPECT_FALSE(ret); + EXPECT_EQ(ERROR_HANDLE_EOF, ::GetLastError()); + } + EXPECT_EQ(0U, bytes_read); + EXPECT_EQ(0, + std::memcmp(write_buffer.data(), read_buffer.data(), bytes_read)); + + // overlapped.Offset = 0; + // ret = WriteFile(handle, Buffer[0], 2 * SystemInfo.dwPageSize, + // &BytesTransferred, &overlapped); + // ASSERT(ret || ERROR_IO_PENDING == ::GetLastError()); + // ret = GetOverlappedResult(handle, &overlapped, &BytesTransferred, + // TRUE); ASSERT(ret); ASSERT(2 * SystemInfo.dwPageSize == // BytesTransferred); // - // Overlapped.Offset = 0; + // overlapped.Offset = 0; // memset(AllocBuffer[1], 0, AllocBufferSize); - // Success = ReadFile(Handle, Buffer[1], 2 * SystemInfo.dwPageSize, - // &BytesTransferred, &Overlapped); - // ASSERT(Success || ERROR_IO_PENDING == GetLastError()); - // Success = GetOverlappedResult(Handle, &Overlapped, &BytesTransferred, - // TRUE); ASSERT(Success); ASSERT(2 * SystemInfo.dwPageSize == + // ret = ReadFile(handle, Buffer[1], 2 * SystemInfo.dwPageSize, + // &BytesTransferred, &overlapped); + // ASSERT(ret || ERROR_IO_PENDING == ::GetLastError()); + // ret = GetOverlappedResult(handle, &overlapped, &BytesTransferred, + // TRUE); ASSERT(ret); ASSERT(2 * SystemInfo.dwPageSize == // BytesTransferred); ASSERT(0 == memcmp(Buffer[0], Buffer[1], // BytesTransferred)); // // Buffer[0] = AllocBuffer[0]; // Buffer[1] = AllocBuffer[0]; // - // Overlapped.Offset = 0; - // Success = WriteFile(Handle, Buffer[0], 2 * SystemInfo.dwPageSize, - // &BytesTransferred, &Overlapped); - // ASSERT(Success || ERROR_IO_PENDING == GetLastError()); - // Success = GetOverlappedResult(Handle, &Overlapped, &BytesTransferred, - // TRUE); ASSERT(Success); ASSERT(2 * SystemInfo.dwPageSize == + // overlapped.Offset = 0; + // ret = WriteFile(handle, Buffer[0], 2 * SystemInfo.dwPageSize, + // &BytesTransferred, &overlapped); + // ASSERT(ret || ERROR_IO_PENDING == ::GetLastError()); + // ret = GetOverlappedResult(handle, &overlapped, &BytesTransferred, + // TRUE); ASSERT(ret); ASSERT(2 * SystemInfo.dwPageSize == // BytesTransferred); // - // Overlapped.Offset = 0; + // overlapped.Offset = 0; // memset(AllocBuffer[1], 0, AllocBufferSize); - // Success = ReadFile(Handle, Buffer[1], 2 * SystemInfo.dwPageSize, - // &BytesTransferred, &Overlapped); - // ASSERT(Success || ERROR_IO_PENDING == GetLastError()); - // Success = GetOverlappedResult(Handle, &Overlapped, &BytesTransferred, - // TRUE); ASSERT(Success); ASSERT(2 * SystemInfo.dwPageSize == + // ret = ReadFile(handle, Buffer[1], 2 * SystemInfo.dwPageSize, + // &BytesTransferred, &overlapped); + // ASSERT(ret || ERROR_IO_PENDING == ::GetLastError()); + // ret = GetOverlappedResult(handle, &overlapped, &BytesTransferred, + // TRUE); ASSERT(ret); ASSERT(2 * SystemInfo.dwPageSize == // BytesTransferred); ASSERT(0 == memcmp(Buffer[0], Buffer[1], // BytesTransferred)); // - // Overlapped.Offset = 0; - // Success = - // WriteFile(Handle, Buffer[0], 2 * SystemInfo.dwPageSize + - // BytesPerSector, - // &BytesTransferred, &Overlapped); - // ASSERT(Success || ERROR_IO_PENDING == GetLastError()); - // Success = GetOverlappedResult(Handle, &Overlapped, &BytesTransferred, - // TRUE); ASSERT(Success); ASSERT(2 * SystemInfo.dwPageSize + BytesPerSector + // overlapped.Offset = 0; + // ret = + // WriteFile(handle, Buffer[0], 2 * SystemInfo.dwPageSize + + // bytes_per_sector, + // &BytesTransferred, &overlapped); + // ASSERT(ret || ERROR_IO_PENDING == ::GetLastError()); + // ret = GetOverlappedResult(handle, &overlapped, &BytesTransferred, + // TRUE); ASSERT(ret); ASSERT(2 * SystemInfo.dwPageSize + bytes_per_sector // == BytesTransferred); // - // Overlapped.Offset = 0; + // overlapped.Offset = 0; // memset(AllocBuffer[1], 0, AllocBufferSize); - // Success = - // ReadFile(Handle, Buffer[1], 2 * SystemInfo.dwPageSize + BytesPerSector, - // &BytesTransferred, &Overlapped); - // ASSERT(Success || ERROR_IO_PENDING == GetLastError()); - // Success = GetOverlappedResult(Handle, &Overlapped, &BytesTransferred, - // TRUE); ASSERT(Success); ASSERT(2 * SystemInfo.dwPageSize + BytesPerSector + // ret = + // ReadFile(handle, Buffer[1], 2 * SystemInfo.dwPageSize + + // bytes_per_sector, + // &BytesTransferred, &overlapped); + // ASSERT(ret || ERROR_IO_PENDING == ::GetLastError()); + // ret = GetOverlappedResult(handle, &overlapped, &BytesTransferred, + // TRUE); ASSERT(ret); ASSERT(2 * SystemInfo.dwPageSize + bytes_per_sector // == BytesTransferred); ASSERT(0 == memcmp(Buffer[0], Buffer[1], // BytesTransferred)); // @@ -408,29 +420,30 @@ static void test_overlapped_file(auto mount_location, auto &&file_path, nullptr); ASSERT_NE(INVALID_HANDLE_VALUE, handle); - // Overlapped.Offset = 0; + // overlapped.Offset = 0; // memset(AllocBuffer[1], 0, AllocBufferSize); - // Success = - // ReadFile(Handle, Buffer[1], 2 * SystemInfo.dwPageSize + BytesPerSector, - // &BytesTransferred, &Overlapped); - // ASSERT(Success || ERROR_IO_PENDING == GetLastError()); - // Success = GetOverlappedResult(Handle, &Overlapped, &BytesTransferred, - // TRUE); ASSERT(Success); ASSERT(2 * SystemInfo.dwPageSize + BytesPerSector + // ret = + // ReadFile(handle, Buffer[1], 2 * SystemInfo.dwPageSize + + // bytes_per_sector, + // &BytesTransferred, &overlapped); + // ASSERT(ret || ERROR_IO_PENDING == ::GetLastError()); + // ret = GetOverlappedResult(handle, &overlapped, &BytesTransferred, + // TRUE); ASSERT(ret); ASSERT(2 * SystemInfo.dwPageSize + bytes_per_sector // == BytesTransferred); ASSERT(0 == memcmp(Buffer[0], Buffer[1], // BytesTransferred)); // - // Success = CloseHandle(Handle); - // ASSERT(Success); + // ret = CloseHandle(Handle); + // ASSERT(ret); // - // Handle = + // handle = // CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, // FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, // 0); - // ASSERT(INVALID_HANDLE_VALUE == Handle); - // ASSERT(ERROR_FILE_NOT_FOUND == GetLastError()); + // ASSERT(INVALID_HANDLE_VALUE == handle); + // ASSERT(ERROR_FILE_NOT_FOUND == ::GetLastError()); // - // Success = CloseHandle(Overlapped.hEvent); - // ASSERT(Success); + // ret = CloseHandle(overlapped.hEvent); + // ASSERT(ret); EXPECT_TRUE(::CloseHandle(handle));