ntdll: Don't require full-page reads in NtReadFileScatter.

Signed-off-by: Andrew Eikum <aeikum@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Andrew Eikum 2017-12-06 15:08:00 -06:00 committed by Alexandre Julliard
parent 64edbfa6fe
commit f87a2f0e4c
2 changed files with 31 additions and 4 deletions

View File

@ -4353,7 +4353,7 @@ static void test_WriteFileGather(void)
FILE_SEGMENT_ELEMENT fse[2]; FILE_SEGMENT_ELEMENT fse[2];
OVERLAPPED ovl, *povl = NULL; OVERLAPPED ovl, *povl = NULL;
SYSTEM_INFO si; SYSTEM_INFO si;
LPVOID wbuf = NULL, rbuf1, rbuf2; char *wbuf = NULL, *rbuf1, *rbuf2;
BOOL br; BOOL br;
evt = CreateEventW( NULL, TRUE, FALSE, NULL ); evt = CreateEventW( NULL, TRUE, FALSE, NULL );
@ -4492,6 +4492,34 @@ static void test_WriteFileGather(void)
ok( memcmp( rbuf2, rbuf1, si.dwPageSize ) == 0, ok( memcmp( rbuf2, rbuf1, si.dwPageSize ) == 0,
"data should not have been read into buffer\n" ); "data should not have been read into buffer\n" );
ResetEvent( evt );
/* partial page read */
memset( &ovl, 0, sizeof(ovl) );
ovl.hEvent = evt;
memset( fse, 0, sizeof(fse) );
fse[0].Buffer = rbuf1;
memset( rbuf1, 0, si.dwPageSize );
SetLastError( 0xdeadbeef );
br = ReadFileScatter( hfile, fse, si.dwPageSize / 2, NULL, &ovl );
ok( br == FALSE, "ReadFileScatter should be asynchronous\n" );
ok( GetLastError() == ERROR_IO_PENDING, "ReadFileScatter failed err %u\n", GetLastError() );
ret = GetQueuedCompletionStatus( hiocp2, &size, &key, &povl, 1000 );
ok( ret, "GetQueuedCompletionStatus failed err %u\n", GetLastError() );
ok( povl == &ovl, "wrong ovl %p\n", povl );
tx = 0;
br = GetOverlappedResult( hfile, &ovl, &tx, TRUE );
ok( br == TRUE, "GetOverlappedResult failed: %u\n", GetLastError() );
ok( tx == si.dwPageSize / 2, "got unexpected bytes transferred: %u\n", tx );
ok( memcmp( rbuf1, wbuf, si.dwPageSize / 2 ) == 0,
"invalid data was read into buffer\n" );
memset( rbuf2, 0, si.dwPageSize );
ok( memcmp( rbuf1 + si.dwPageSize / 2, rbuf2, si.dwPageSize - si.dwPageSize / 2 ) == 0,
"invalid data was read into buffer\n" );
CloseHandle( hfile ); CloseHandle( hfile );
CloseHandle( hiocp1 ); CloseHandle( hiocp1 );
CloseHandle( hiocp2 ); CloseHandle( hiocp2 );

View File

@ -1041,7 +1041,6 @@ NTSTATUS WINAPI NtReadFileScatter( HANDLE file, HANDLE event, PIO_APC_ROUTINE ap
TRACE( "(%p,%p,%p,%p,%p,%p,0x%08x,%p,%p),partial stub!\n", TRACE( "(%p,%p,%p,%p,%p,%p,0x%08x,%p,%p),partial stub!\n",
file, event, apc, apc_user, io_status, segments, length, offset, key); file, event, apc, apc_user, io_status, segments, length, offset, key);
if (length % page_size) return STATUS_INVALID_PARAMETER;
if (!io_status) return STATUS_ACCESS_VIOLATION; if (!io_status) return STATUS_ACCESS_VIOLATION;
status = server_get_unix_fd( file, FILE_READ_DATA, &unix_handle, status = server_get_unix_fd( file, FILE_READ_DATA, &unix_handle,
@ -1060,9 +1059,9 @@ NTSTATUS WINAPI NtReadFileScatter( HANDLE file, HANDLE event, PIO_APC_ROUTINE ap
{ {
if (offset && offset->QuadPart != FILE_USE_FILE_POINTER_POSITION) if (offset && offset->QuadPart != FILE_USE_FILE_POINTER_POSITION)
result = pread( unix_handle, (char *)segments->Buffer + pos, result = pread( unix_handle, (char *)segments->Buffer + pos,
page_size - pos, offset->QuadPart + total ); min( length - pos, page_size - pos ), offset->QuadPart + total );
else else
result = read( unix_handle, (char *)segments->Buffer + pos, page_size - pos ); result = read( unix_handle, (char *)segments->Buffer + pos, min( length - pos, page_size - pos ) );
if (result == -1) if (result == -1)
{ {