Signed-off-by: Paul Gofman gofmanp@gmail.com --- dlls/kernel32/tests/file.c | 65 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+)
diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c index b47b2b9c41..c9c2dd24e7 100644 --- a/dlls/kernel32/tests/file.c +++ b/dlls/kernel32/tests/file.c @@ -5140,6 +5140,70 @@ static void test_post_completion(void) CloseHandle( port ); }
+#define TEST_OVERLAPPED_READ_SIZE 4096 + +static void test_overlapped_read(void) +{ + DECLSPEC_ALIGN(TEST_OVERLAPPED_READ_SIZE) static unsigned char buffer[TEST_OVERLAPPED_READ_SIZE]; + static const char prefix[] = "pfx"; + char temp_path[MAX_PATH]; + char file_name[MAX_PATH]; + DWORD bytes_count; + OVERLAPPED ov; + HANDLE hfile; + DWORD err; + DWORD ret; + + ret = GetTempPathA(MAX_PATH, temp_path); + ok(ret, "Unexpect error %u.\n", GetLastError()); + ret = GetTempFileNameA(temp_path, prefix, 0, file_name); + ok(ret, "Unexpected error %u.\n", GetLastError()); + + hfile = CreateFileA(file_name, GENERIC_WRITE, 0, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL); + ok(hfile != INVALID_HANDLE_VALUE, "Failed to create file, GetLastError() %u.\n", GetLastError()); + memset(buffer, 0x55, sizeof(buffer)); + ret = WriteFile(hfile, buffer, TEST_OVERLAPPED_READ_SIZE, &bytes_count, NULL); + ok(ret && bytes_count == TEST_OVERLAPPED_READ_SIZE, + "Unexpected WriteFile result, ret %#x, bytes_count %u, GetLastError() %u.\n", + ret, bytes_count, GetLastError()); + CloseHandle(hfile); + + hfile = CreateFileA(file_name, GENERIC_READ, FILE_SHARE_READ, + NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, NULL); + ok(hfile != INVALID_HANDLE_VALUE, "Failed to create file, GetLastError() %u.\n", GetLastError()); + + memset(&ov, 0, sizeof(ov)); + + bytes_count = 0xffffffff; + ret = ReadFile(hfile, buffer, TEST_OVERLAPPED_READ_SIZE, &bytes_count, &ov); + todo_wine ok(!ret && GetLastError() == ERROR_IO_PENDING, + "Unexpected ReadFile result, ret %#x, GetLastError() %u.\n", ret, GetLastError()); + todo_wine ok(!bytes_count, "Unexpected read size %u.\n", bytes_count); + ret = GetOverlappedResult(hfile, &ov, &bytes_count, TRUE); + ok(ret, "Unexpected error %u.\n", GetLastError()); + ok(bytes_count == TEST_OVERLAPPED_READ_SIZE, "Unexpected read size %u.\n", bytes_count); + + S(U(ov)).Offset = bytes_count; + ret = ReadFile(hfile, buffer, TEST_OVERLAPPED_READ_SIZE, &bytes_count, &ov); + err = GetLastError(); + /* Win8+ return ERROR_IO_PENDING like stated in MSDN, while older ones + * return ERROR_HANDLE_EOF right away. */ + ok(!ret && (err == ERROR_HANDLE_EOF || err == ERROR_IO_PENDING), + "Unexpected ReadFile result, ret %#x, GetLastError() %u.\n", ret, GetLastError()); + if (err == ERROR_IO_PENDING) + { + ret = GetOverlappedResult(hfile, &ov, &bytes_count, TRUE); + ok(!ret && GetLastError() == ERROR_HANDLE_EOF, "Unexpected result %#x, GetLasttError() %u.\n", + ret, GetLastError()); + } + ok(!bytes_count, "Unexpected read size %u.\n", bytes_count); + + CloseHandle(hfile); + ret = DeleteFileA(file_name); + ok(ret, "Unexpected error %u.\n", GetLastError()); +} + START_TEST(file) { char temp_path[MAX_PATH]; @@ -5209,4 +5273,5 @@ START_TEST(file) test_SetFileInformationByHandle(); test_GetFileAttributesExW(); test_post_completion(); + test_overlapped_read(); }
Signed-off-by: Paul Gofman gofmanp@gmail.com --- dlls/ntdll/tests/file.c | 43 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 8391570e91..7b355697f7 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -598,8 +598,11 @@ static void delete_file_test(void) pRtlFreeUnicodeString( &nameW ); }
+#define TEST_OVERLAPPED_READ_SIZE 4096 + static void read_file_test(void) { + DECLSPEC_ALIGN(TEST_OVERLAPPED_READ_SIZE) static unsigned char aligned_buffer[TEST_OVERLAPPED_READ_SIZE]; const char text[] = "foobar"; HANDLE handle; IO_STATUS_BLOCK iosb; @@ -711,7 +714,45 @@ static void read_file_test(void)
CloseHandle( handle );
- CloseHandle( event ); + if (!(handle = create_temp_file(FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING))) + return; + + apc_count = 0; + offset.QuadPart = 0; + U(iosb).Status = 0xdeadbabe; + iosb.Information = 0xdeadbeef; + offset.QuadPart = 0; + ResetEvent(event); + status = pNtWriteFile(handle, event, apc, &apc_count, &iosb, + aligned_buffer, sizeof(aligned_buffer), &offset, NULL); + ok(status == STATUS_END_OF_FILE || status == STATUS_PENDING || status == STATUS_SUCCESS, + "Wrong status %x.\n", status); + ok(U(iosb).Status == STATUS_SUCCESS, "Wrong status %x.\n", U(iosb).Status); + ok(iosb.Information == sizeof(aligned_buffer), "Wrong info %lu.\n", iosb.Information); + ok(is_signaled(event), "event is not signaled.\n"); + ok(!apc_count, "apc was called.\n"); + SleepEx(1, TRUE); /* alertable sleep */ + ok(apc_count == 1, "apc was not called.\n"); + + apc_count = 0; + offset.QuadPart = 0; + U(iosb).Status = 0xdeadbabe; + iosb.Information = 0xdeadbeef; + offset.QuadPart = 0; + ResetEvent(event); + status = pNtReadFile(handle, event, apc, &apc_count, &iosb, + aligned_buffer, sizeof(aligned_buffer), &offset, NULL); + todo_wine ok(status == STATUS_PENDING, "Wrong status %x.\n", status); + WaitForSingleObject(event, 1000); + ok(U(iosb).Status == STATUS_SUCCESS, "Wrong status %x.\n", U(iosb).Status); + ok(iosb.Information == sizeof(aligned_buffer), "Wrong info %lu.\n", iosb.Information); + ok(is_signaled(event), "event is not signaled.\n"); + ok(!apc_count, "apc was called.\n"); + SleepEx(1, TRUE); /* alertable sleep */ + ok(apc_count == 1, "apc was not called.\n"); + + CloseHandle(handle); + CloseHandle(event); }
static void append_file_test(void)
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=31954 Signed-off-by: Paul Gofman gofmanp@gmail.com --- dlls/kernel32/tests/file.c | 4 ++-- dlls/ntdll/file.c | 3 ++- dlls/ntdll/tests/file.c | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c index c9c2dd24e7..18cd18d154 100644 --- a/dlls/kernel32/tests/file.c +++ b/dlls/kernel32/tests/file.c @@ -5177,9 +5177,9 @@ static void test_overlapped_read(void)
bytes_count = 0xffffffff; ret = ReadFile(hfile, buffer, TEST_OVERLAPPED_READ_SIZE, &bytes_count, &ov); - todo_wine ok(!ret && GetLastError() == ERROR_IO_PENDING, + ok(!ret && GetLastError() == ERROR_IO_PENDING, "Unexpected ReadFile result, ret %#x, GetLastError() %u.\n", ret, GetLastError()); - todo_wine ok(!bytes_count, "Unexpected read size %u.\n", bytes_count); + ok(!bytes_count, "Unexpected read size %u.\n", bytes_count); ret = GetOverlappedResult(hfile, &ov, &bytes_count, TRUE); ok(ret, "Unexpected error %u.\n", GetLastError()); ok(bytes_count == TEST_OVERLAPPED_READ_SIZE, "Unexpected read size %u.\n", bytes_count); diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index a43fe71108..1cf3ae2d05 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -1014,7 +1014,8 @@ err: }
if (send_completion) NTDLL_AddCompletion( hFile, cvalue, status, total ); - + if (async_read && (options & FILE_NO_INTERMEDIATE_BUFFERING) && status == STATUS_SUCCESS) + return STATUS_PENDING; return status; }
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 7b355697f7..e210a6e280 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -742,7 +742,7 @@ static void read_file_test(void) ResetEvent(event); status = pNtReadFile(handle, event, apc, &apc_count, &iosb, aligned_buffer, sizeof(aligned_buffer), &offset, NULL); - todo_wine ok(status == STATUS_PENDING, "Wrong status %x.\n", status); + ok(status == STATUS_PENDING, "Wrong status %x.\n", status); WaitForSingleObject(event, 1000); ok(U(iosb).Status == STATUS_SUCCESS, "Wrong status %x.\n", U(iosb).Status); ok(iosb.Information == sizeof(aligned_buffer), "Wrong info %lu.\n", iosb.Information);