ReadFile/WriteFile: Require overlapped I/O on overlapped handles (#99)

This commit is contained in:
2025-10-23 23:07:56 -07:00
committed by GitHub
parent 5597da607a
commit 1500a4f815
2 changed files with 37 additions and 0 deletions

View File

@@ -718,6 +718,15 @@ BOOL WIN_FUNC WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWr
return FALSE; return FALSE;
} }
if (lpNumberOfBytesWritten && (!file->overlapped || lpOverlapped == nullptr)) {
*lpNumberOfBytesWritten = 0;
}
if (file->overlapped && lpOverlapped == nullptr) {
wibo::lastError = ERROR_INVALID_PARAMETER;
return FALSE;
}
std::optional<off_t> offset; std::optional<off_t> offset;
bool updateFilePointer = true; bool updateFilePointer = true;
if (lpOverlapped != nullptr) { if (lpOverlapped != nullptr) {
@@ -808,6 +817,11 @@ BOOL WIN_FUNC ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead
*lpNumberOfBytesRead = 0; *lpNumberOfBytesRead = 0;
} }
if (file->overlapped && lpOverlapped == nullptr) {
wibo::lastError = ERROR_INVALID_PARAMETER;
return FALSE;
}
std::optional<off_t> offset; std::optional<off_t> offset;
bool updateFilePointer = true; bool updateFilePointer = true;
if (lpOverlapped != nullptr) { if (lpOverlapped != nullptr) {

View File

@@ -95,6 +95,28 @@ static void write_fixture_file(void) {
TEST_CHECK(CloseHandle(file)); TEST_CHECK(CloseHandle(file));
} }
static void test_overlapped_requires_overlapped_structure(void) {
HANDLE file = CreateFileA(g_tempFilename, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
TEST_CHECK(file != INVALID_HANDLE_VALUE);
char buffer[8] = {0};
DWORD bytesRead = 0xFFFFFFFFu;
SetLastError(0);
TEST_CHECK(!ReadFile(file, buffer, sizeof(buffer), &bytesRead, NULL));
TEST_CHECK_EQ(ERROR_INVALID_PARAMETER, GetLastError());
TEST_CHECK_EQ(0U, bytesRead);
static const char payload[] = "data";
DWORD bytesWritten = 0xFFFFFFFFu;
SetLastError(0);
TEST_CHECK(!WriteFile(file, payload, (DWORD)(sizeof(payload) - 1), &bytesWritten, NULL));
TEST_CHECK_EQ(ERROR_INVALID_PARAMETER, GetLastError());
TEST_CHECK_EQ(0U, bytesWritten);
TEST_CHECK(CloseHandle(file));
}
static void test_synchronous_overlapped_read(void) { static void test_synchronous_overlapped_read(void) {
HANDLE file = CreateFileA(g_tempFilename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); HANDLE file = CreateFileA(g_tempFilename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
TEST_CHECK(file != INVALID_HANDLE_VALUE); TEST_CHECK(file != INVALID_HANDLE_VALUE);
@@ -455,6 +477,7 @@ int main(void) {
DeleteFileA(g_tempFilename); DeleteFileA(g_tempFilename);
write_fixture_file(); write_fixture_file();
test_synchronous_overlapped_read(); test_synchronous_overlapped_read();
test_overlapped_requires_overlapped_structure();
test_overlapped_read_with_event(); test_overlapped_read_with_event();
test_overlapped_read_without_event(); test_overlapped_read_without_event();
test_overlapped_eof(); test_overlapped_eof();