Author: tfaber Date: Fri May 1 11:03:21 2015 New Revision: 67487
URL: http://svn.reactos.org/svn/reactos?rev=67487&view=rev Log: [KMTESTS:IO] - Add a test for the interaction between NtReadFile and a file system driver CORE-9624
Added: trunk/rostests/kmtests/ntos_io/IoReadWrite.h (with props) trunk/rostests/kmtests/ntos_io/IoReadWrite_drv.c (with props) trunk/rostests/kmtests/ntos_io/IoReadWrite_user.c (with props) Modified: trunk/rostests/kmtests/CMakeLists.txt trunk/rostests/kmtests/include/kmt_platform.h trunk/rostests/kmtests/kmtest/testlist.c trunk/rostests/kmtests/ntos_io/CMakeLists.txt
Modified: trunk/rostests/kmtests/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/CMakeLists.txt?rev... ============================================================================== --- trunk/rostests/kmtests/CMakeLists.txt [iso-8859-1] (original) +++ trunk/rostests/kmtests/CMakeLists.txt [iso-8859-1] Fri May 1 11:03:21 2015 @@ -109,6 +109,7 @@ example/Example_user.c kernel32/FindFile_user.c ntos_io/IoDeviceObject_user.c + ntos_io/IoReadWrite_user.c tcpip/TcpIp_user.c ${COMMON_SOURCE}
@@ -132,6 +133,7 @@ example_drv iodeviceobject_drv iohelper_drv + ioreadwrite_drv tcpip_drv)
add_custom_target(kmtest_all)
Modified: trunk/rostests/kmtests/include/kmt_platform.h URL: http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/include/kmt_platfo... ============================================================================== --- trunk/rostests/kmtests/include/kmt_platform.h [iso-8859-1] (original) +++ trunk/rostests/kmtests/include/kmt_platform.h [iso-8859-1] Fri May 1 11:03:21 2015 @@ -34,6 +34,7 @@ #include <winreg.h> #include <winsvc.h> #include <ndk/cmfuncs.h> +#include <ndk/iofuncs.h> #include <ndk/obfuncs.h> #include <ndk/rtlfuncs.h> #include <ndk/mmfuncs.h>
Modified: trunk/rostests/kmtests/kmtest/testlist.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/kmtest/testlist.c?... ============================================================================== --- trunk/rostests/kmtests/kmtest/testlist.c [iso-8859-1] (original) +++ trunk/rostests/kmtests/kmtest/testlist.c [iso-8859-1] Fri May 1 11:03:21 2015 @@ -10,6 +10,7 @@ KMT_TESTFUNC Test_Example; KMT_TESTFUNC Test_FindFile; KMT_TESTFUNC Test_IoDeviceObject; +KMT_TESTFUNC Test_IoReadWrite; KMT_TESTFUNC Test_RtlAvlTree; KMT_TESTFUNC Test_RtlException; KMT_TESTFUNC Test_RtlIntSafe; @@ -27,6 +28,7 @@ { "-Example", Test_Example }, { "FindFile", Test_FindFile }, { "IoDeviceObject", Test_IoDeviceObject }, + { "IoReadWrite", Test_IoReadWrite }, { "RtlAvlTree", Test_RtlAvlTree }, { "RtlException", Test_RtlException }, { "RtlIntSafe", Test_RtlIntSafe },
Modified: trunk/rostests/kmtests/ntos_io/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_io/CMakeLists... ============================================================================== --- trunk/rostests/kmtests/ntos_io/CMakeLists.txt [iso-8859-1] (original) +++ trunk/rostests/kmtests/ntos_io/CMakeLists.txt [iso-8859-1] Fri May 1 11:03:21 2015 @@ -30,3 +30,18 @@ add_target_compile_definitions(iohelper_drv KMT_STANDALONE_DRIVER) #add_pch(iohelper_drv ../include/kmt_test.h) add_cd_file(TARGET iohelper_drv DESTINATION reactos/bin FOR all) + +# +# IoReadWrite +# +list(APPEND IOREADWRITE_DRV_SOURCE + ../kmtest_drv/kmtest_standalone.c + IoReadWrite_drv.c) + +add_library(ioreadwrite_drv SHARED ${IOREADWRITE_DRV_SOURCE}) +set_module_type(ioreadwrite_drv kernelmodedriver) +target_link_libraries(ioreadwrite_drv kmtest_printf ${PSEH_LIB}) +add_importlibs(ioreadwrite_drv ntoskrnl hal) +add_target_compile_definitions(ioreadwrite_drv KMT_STANDALONE_DRIVER) +#add_pch(ioreadwrite_drv ../include/kmt_test.h) +add_cd_file(TARGET ioreadwrite_drv DESTINATION reactos/bin FOR all)
Added: trunk/rostests/kmtests/ntos_io/IoReadWrite.h URL: http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_io/IoReadWrit... ============================================================================== --- trunk/rostests/kmtests/ntos_io/IoReadWrite.h (added) +++ trunk/rostests/kmtests/ntos_io/IoReadWrite.h [iso-8859-1] Fri May 1 11:03:21 2015 @@ -0,0 +1,81 @@ +/* + * PROJECT: ReactOS kernel-mode tests + * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory + * PURPOSE: Read/Write operations test declarations + * PROGRAMMER: Thomas Faber thomas.faber@reactos.org + */ + +#ifndef _KMTEST_IOREADFILE_H_ +#define _KMTEST_IOREADFILE_H_ + +#define TEST_FILE_SIZE 17 + +#define KEY_SUCCEED 0x00 +#define KEY_FAIL_MISALIGNED 0x81 +#define KEY_FAIL_OVERFLOW 0x82 +#define KEY_FAIL_PARTIAL 0x83 +#define KEY_FAIL_BUSY 0x84 +#define KEY_FAIL_VERIFY_REQUIRED 0x85 + +#define KEY_FAIL_UNSUCCESSFUL 0xc1 +#define KEY_FAIL_NOT_IMPLEMENTED 0xc2 +#define KEY_FAIL_ACCESS_VIOLATION 0xc3 +#define KEY_FAIL_IN_PAGE_ERROR 0xc4 +#define KEY_FAIL_EOF 0xc5 +#define KEY_FAIL_ACCESS_DENIED 0xc6 +#define KEY_FAIL_MISALIGNED_ERROR 0xc7 +#define KEY_RESULT_MASK 0xff + +#define KEY_NEXT(key) ( (key) == KEY_FAIL_MISALIGNED_ERROR ? 0xff : \ + (key) == KEY_FAIL_VERIFY_REQUIRED ? KEY_FAIL_UNSUCCESSFUL : \ + (key) == KEY_SUCCEED ? KEY_FAIL_MISALIGNED : \ + (key) + 1 ) +#define KEY_ERROR(key) (((key) & 0xc0) == 0xc0) +static +NTSTATUS +TestGetReturnStatus( + _In_ ULONG LockKey) +{ + switch (LockKey & KEY_RESULT_MASK) + { + case KEY_SUCCEED: + return STATUS_SUCCESS; + + case KEY_FAIL_MISALIGNED: + return STATUS_DATATYPE_MISALIGNMENT; + case KEY_FAIL_OVERFLOW: + return STATUS_BUFFER_OVERFLOW; + case KEY_FAIL_PARTIAL: + return STATUS_PARTIAL_COPY; + case KEY_FAIL_BUSY: + return STATUS_DEVICE_BUSY; + case KEY_FAIL_VERIFY_REQUIRED: + return STATUS_VERIFY_REQUIRED; + + case KEY_FAIL_UNSUCCESSFUL: + return STATUS_UNSUCCESSFUL; + case KEY_FAIL_NOT_IMPLEMENTED: + return STATUS_NOT_IMPLEMENTED; + case KEY_FAIL_ACCESS_VIOLATION: + return STATUS_ACCESS_VIOLATION; + case KEY_FAIL_IN_PAGE_ERROR: + return STATUS_IN_PAGE_ERROR; + case KEY_FAIL_EOF: + return STATUS_END_OF_FILE; + case KEY_FAIL_ACCESS_DENIED: + return STATUS_ACCESS_DENIED; + case KEY_FAIL_MISALIGNED_ERROR: + return STATUS_DATATYPE_MISALIGNMENT_ERROR; + default: + ok(0, "Key = %lx\n", LockKey); + return STATUS_INVALID_PARAMETER; + } +} + +#define KEY_USE_FASTIO 0x100 +#define KEY_RETURN_PENDING 0x200 + +#define KEY_DATA(c) (((c) & 0xff) << 24) +#define KEY_GET_DATA(key) ((key) >> 24) + +#endif /* !defined _KMTEST_IOREADFILE_H_ */
Propchange: trunk/rostests/kmtests/ntos_io/IoReadWrite.h ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/rostests/kmtests/ntos_io/IoReadWrite_drv.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_io/IoReadWrit... ============================================================================== --- trunk/rostests/kmtests/ntos_io/IoReadWrite_drv.c (added) +++ trunk/rostests/kmtests/ntos_io/IoReadWrite_drv.c [iso-8859-1] Fri May 1 11:03:21 2015 @@ -0,0 +1,312 @@ +/* + * PROJECT: ReactOS kernel-mode tests + * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory + * PURPOSE: Test driver for Read/Write operations + * PROGRAMMER: Thomas Faber thomas.faber@reactos.org + */ + +#include <kmt_test.h> +#include "IoReadWrite.h" + +#define NDEBUG +#include <debug.h> + +typedef struct _TEST_FCB +{ + FSRTL_ADVANCED_FCB_HEADER Header; + SECTION_OBJECT_POINTERS SectionObjectPointers; + FAST_MUTEX HeaderMutex; + BOOLEAN Cached; +} TEST_FCB, *PTEST_FCB; + +static KMT_IRP_HANDLER TestIrpHandler; +static FAST_IO_READ TestFastIoRead; +static FAST_IO_WRITE TestFastIoWrite; + +static FAST_IO_DISPATCH TestFastIoDispatch; +static ULONG TestLastFastReadKey; +static ULONG TestLastFastWriteKey; +static PFILE_OBJECT TestFileObject; +static PDEVICE_OBJECT TestDeviceObject; + +NTSTATUS +TestEntry( + _In_ PDRIVER_OBJECT DriverObject, + _In_ PCUNICODE_STRING RegistryPath, + _Out_ PCWSTR *DeviceName, + _Inout_ INT *Flags) +{ + NTSTATUS Status = STATUS_SUCCESS; + + PAGED_CODE(); + + UNREFERENCED_PARAMETER(RegistryPath); + + *DeviceName = L"IoReadWrite"; + *Flags = TESTENTRY_NO_EXCLUSIVE_DEVICE | TESTENTRY_BUFFERED_IO_DEVICE; + + TestFastIoDispatch.FastIoRead = TestFastIoRead; + TestFastIoDispatch.FastIoWrite = TestFastIoWrite; + DriverObject->FastIoDispatch = &TestFastIoDispatch; + + KmtRegisterIrpHandler(IRP_MJ_CREATE, NULL, TestIrpHandler); + KmtRegisterIrpHandler(IRP_MJ_CLEANUP, NULL, TestIrpHandler); + KmtRegisterIrpHandler(IRP_MJ_READ, NULL, TestIrpHandler); + //KmtRegisterIrpHandler(IRP_MJ_WRITE, NULL, TestIrpHandler); + + return Status; +} + +VOID +TestUnload( + _In_ PDRIVER_OBJECT DriverObject) +{ + PAGED_CODE(); +} + +static +BOOLEAN +NTAPI +TestAcquireForLazyWrite( + _In_ PVOID Context, + _In_ BOOLEAN Wait) +{ + ok_eq_pointer(Context, NULL); + ok(0, "Unexpected call to AcquireForLazyWrite\n"); + return TRUE; +} + +static +VOID +NTAPI +TestReleaseFromLazyWrite( + _In_ PVOID Context) +{ + ok_eq_pointer(Context, NULL); + ok(0, "Unexpected call to ReleaseFromLazyWrite\n"); +} + +static +BOOLEAN +NTAPI +TestAcquireForReadAhead( + _In_ PVOID Context, + _In_ BOOLEAN Wait) +{ + ok_eq_pointer(Context, NULL); + ok(0, "Unexpected call to AcquireForReadAhead\n"); + return TRUE; +} + +static +VOID +NTAPI +TestReleaseFromReadAhead( + _In_ PVOID Context) +{ + ok_eq_pointer(Context, NULL); + ok(0, "Unexpected call to ReleaseFromReadAhead\n"); +} + +static +NTSTATUS +TestCommonRead( + _In_ PVOID Buffer, + _In_ ULONG Length, + _In_ LONGLONG FileOffset, + _In_ ULONG LockKey, + _Out_ PIO_STATUS_BLOCK IoStatus) +{ + if (FileOffset >= TEST_FILE_SIZE) + { + trace("FileOffset %I64d > file size\n", FileOffset); + IoStatus->Status = STATUS_END_OF_FILE; + IoStatus->Information = 0; + } + else if (Length == 0 || Buffer == NULL) + { + IoStatus->Status = STATUS_BUFFER_OVERFLOW; + IoStatus->Information = TEST_FILE_SIZE - FileOffset; + } + else + { + Length = min(Length, TEST_FILE_SIZE - FileOffset); + RtlFillMemory(Buffer, Length, KEY_GET_DATA(LockKey)); + IoStatus->Status = TestGetReturnStatus(LockKey); + IoStatus->Information = Length; + } + if (LockKey & KEY_RETURN_PENDING) + return STATUS_PENDING; + return IoStatus->Status; +} + +static +BOOLEAN +NTAPI +TestFastIoRead( + _In_ PFILE_OBJECT FileObject, + _In_ PLARGE_INTEGER FileOffset, + _In_ ULONG Length, + _In_ BOOLEAN Wait, + _In_ ULONG LockKey, + _Out_ PVOID Buffer, + _Out_ PIO_STATUS_BLOCK IoStatus, + _In_ PDEVICE_OBJECT DeviceObject) +{ + PTEST_FCB Fcb; + NTSTATUS Status; + + //trace("FastIoRead: %p %lx %I64d+%lu -> %p\n", FileObject, LockKey, FileOffset->QuadPart, Length, Buffer); + ok_eq_pointer(FileObject, TestFileObject); + ok_bool_true(Wait, "Wait is"); + ok_eq_pointer(DeviceObject, TestDeviceObject); + Fcb = FileObject->FsContext; + ok_bool_true(Fcb->Cached, "Cached is"); + + TestLastFastReadKey = LockKey; + ok((ULONG_PTR)Buffer < MM_USER_PROBE_ADDRESS, "Buffer is %p\n", Buffer); + ok((ULONG_PTR)FileOffset > MM_USER_PROBE_ADDRESS, "FileOffset is %p\n", FileOffset); + ok((ULONG_PTR)IoStatus > MM_USER_PROBE_ADDRESS, "IoStatus is %p\n", IoStatus); + _SEH2_TRY + { + Status = TestCommonRead(Buffer, Length, FileOffset->QuadPart, LockKey, IoStatus); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + IoStatus->Status = _SEH2_GetExceptionCode(); + return FALSE; + } + _SEH2_END; + + if (Status == STATUS_PENDING) + return FALSE; + + if (LockKey & KEY_USE_FASTIO) + return TRUE; + else + return FALSE; +} + +static +BOOLEAN +NTAPI +TestFastIoWrite( + _In_ PFILE_OBJECT FileObject, + _In_ PLARGE_INTEGER FileOffset, + _In_ ULONG Length, + _In_ BOOLEAN Wait, + _In_ ULONG LockKey, + _In_ PVOID Buffer, + _Out_ PIO_STATUS_BLOCK IoStatus, + _In_ PDEVICE_OBJECT DeviceObject) +{ + UNIMPLEMENTED; + return FALSE; +} + +static +NTSTATUS +TestIrpHandler( + _In_ PDEVICE_OBJECT DeviceObject, + _In_ PIRP Irp, + _In_ PIO_STACK_LOCATION IoStack) +{ + NTSTATUS Status; + PTEST_FCB Fcb; + CACHE_MANAGER_CALLBACKS Callbacks; + CACHE_UNINITIALIZE_EVENT CacheUninitEvent; + + PAGED_CODE(); + + DPRINT("IRP %x/%x\n", IoStack->MajorFunction, IoStack->MinorFunction); + ASSERT(IoStack->MajorFunction == IRP_MJ_CREATE || + IoStack->MajorFunction == IRP_MJ_CLEANUP || + IoStack->MajorFunction == IRP_MJ_READ || + IoStack->MajorFunction == IRP_MJ_WRITE); + + Status = STATUS_NOT_SUPPORTED; + Irp->IoStatus.Information = 0; + + if (IoStack->MajorFunction == IRP_MJ_CREATE) + { + if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR)) + { + TestDeviceObject = DeviceObject; + TestFileObject = IoStack->FileObject; + } + Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Fcb), 'FwrI'); + RtlZeroMemory(Fcb, sizeof(*Fcb)); + ExInitializeFastMutex(&Fcb->HeaderMutex); + FsRtlSetupAdvancedHeader(&Fcb->Header, &Fcb->HeaderMutex); + Fcb->Header.AllocationSize.QuadPart = TEST_FILE_SIZE; + Fcb->Header.FileSize.QuadPart = TEST_FILE_SIZE; + Fcb->Header.ValidDataLength.QuadPart = TEST_FILE_SIZE; + IoStack->FileObject->FsContext = Fcb; + IoStack->FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers; + if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR) && + IoStack->FileObject->FileName.Buffer[1] != 'N') + { + Fcb->Cached = TRUE; + Callbacks.AcquireForLazyWrite = TestAcquireForLazyWrite; + Callbacks.ReleaseFromLazyWrite = TestReleaseFromLazyWrite; + Callbacks.AcquireForReadAhead = TestAcquireForReadAhead; + Callbacks.ReleaseFromReadAhead = TestReleaseFromReadAhead; + CcInitializeCacheMap(IoStack->FileObject, + (PCC_FILE_SIZES)&Fcb->Header.AllocationSize, + FALSE, + &Callbacks, + NULL); + } + Irp->IoStatus.Information = FILE_OPENED; + Status = STATUS_SUCCESS; + } + else if (IoStack->MajorFunction == IRP_MJ_CLEANUP) + { + KeInitializeEvent(&CacheUninitEvent.Event, NotificationEvent, FALSE); + CcUninitializeCacheMap(IoStack->FileObject, NULL, &CacheUninitEvent); + KeWaitForSingleObject(&CacheUninitEvent.Event, Executive, KernelMode, FALSE, NULL); + Fcb = IoStack->FileObject->FsContext; + ExFreePoolWithTag(Fcb, 'FwrI'); + IoStack->FileObject->FsContext = NULL; + Status = STATUS_SUCCESS; + } + else if (IoStack->MajorFunction == IRP_MJ_READ) + { + //trace("IRP_MJ_READ: %p %lx %I64d+%lu -> %p\n", IoStack->FileObject, IoStack->Parameters.Read.Key, IoStack->Parameters.Read.ByteOffset.QuadPart, IoStack->Parameters.Read.Length, Irp->AssociatedIrp.SystemBuffer); + ok_eq_pointer(DeviceObject, TestDeviceObject); + ok_eq_pointer(IoStack->FileObject, TestFileObject); + Fcb = IoStack->FileObject->FsContext; + if (Fcb->Cached) + ok_eq_hex(IoStack->Parameters.Read.Key, TestLastFastReadKey); + ok(Irp->AssociatedIrp.SystemBuffer == NULL || + (ULONG_PTR)Irp->AssociatedIrp.SystemBuffer > MM_USER_PROBE_ADDRESS, + "Buffer is %p\n", + Irp->AssociatedIrp.SystemBuffer); + Status = TestCommonRead(Irp->AssociatedIrp.SystemBuffer, + IoStack->Parameters.Read.Length, + IoStack->Parameters.Read.ByteOffset.QuadPart, + IoStack->Parameters.Read.Key, + &Irp->IoStatus); + } + else if (IoStack->MajorFunction == IRP_MJ_WRITE) + { + ok_eq_pointer(DeviceObject, TestDeviceObject); + ok_eq_pointer(IoStack->FileObject, TestFileObject); + UNIMPLEMENTED; + Status = STATUS_NOT_IMPLEMENTED; + } + + if (Status == STATUS_PENDING) + { + IoMarkIrpPending(Irp); + IoCompleteRequest(Irp, IO_NO_INCREMENT); + Status = STATUS_PENDING; + } + else + { + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + } + + return Status; +}
Propchange: trunk/rostests/kmtests/ntos_io/IoReadWrite_drv.c ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/rostests/kmtests/ntos_io/IoReadWrite_user.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_io/IoReadWrit... ============================================================================== --- trunk/rostests/kmtests/ntos_io/IoReadWrite_user.c (added) +++ trunk/rostests/kmtests/ntos_io/IoReadWrite_user.c [iso-8859-1] Fri May 1 11:03:21 2015 @@ -0,0 +1,237 @@ +/* + * PROJECT: ReactOS kernel-mode tests + * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory + * PURPOSE: Test for Read/Write operations + * PROGRAMMER: Thomas Faber thomas.faber@reactos.org + */ + +#include <kmt_test.h> +#include "IoReadWrite.h" + +static +VOID +TestRead( + _In_ HANDLE FileHandle, + _In_ BOOLEAN Cached, + _In_ BOOLEAN UseFastIo, + _In_ BOOLEAN ReturnPending) +{ + NTSTATUS Status; + IO_STATUS_BLOCK IoStatus; + HANDLE EventHandle; + UCHAR Buffer[32]; + LARGE_INTEGER Offset; + ULONG BaseKey, StatusKey, Key; + DWORD WaitStatus; + + BaseKey = (UseFastIo ? KEY_USE_FASTIO : 0) | + (ReturnPending ? KEY_RETURN_PENDING : 0); + + EventHandle = CreateEventW(NULL, TRUE, FALSE, NULL); + ok(EventHandle != NULL, "CreateEvent failed with %lu\n", GetLastError()); + + for (StatusKey = KEY_SUCCEED ; StatusKey != 0xff; StatusKey = KEY_NEXT(StatusKey)) + { + trace("\tSTATUS KEY: %lx\n", StatusKey); + ResetEvent(EventHandle); + RtlFillMemory(&IoStatus, sizeof(IoStatus), 0x55); + Key = BaseKey | StatusKey | KEY_DATA(0x11); + Offset.QuadPart = 0; + Status = NtReadFile(FileHandle, + EventHandle, + NULL, + NULL, + &IoStatus, + NULL, + 0, + &Offset, + &Key); + WaitStatus = WaitForSingleObject(EventHandle, 0); + if (ReturnPending) + ok_eq_hex(Status, STATUS_ACCESS_VIOLATION); + else + ok_eq_hex(Status, STATUS_BUFFER_OVERFLOW); + if (Cached && UseFastIo && !ReturnPending) + { + ok_eq_ulong(WaitStatus, WAIT_OBJECT_0); + ok_eq_hex(IoStatus.Status, STATUS_BUFFER_OVERFLOW); + ok_eq_ulongptr(IoStatus.Information, TEST_FILE_SIZE); + } + else + { + ok_eq_ulong(WaitStatus, WAIT_TIMEOUT); + ok_eq_hex(IoStatus.Status, 0x55555555); + ok_eq_ulongptr(IoStatus.Information, (ULONG_PTR)0x5555555555555555); + } + + KmtStartSeh() + ResetEvent(EventHandle); + RtlFillMemory(&IoStatus, sizeof(IoStatus), 0x55); + Key = BaseKey | StatusKey | KEY_DATA(0x22); + Offset.QuadPart = 0; + Status = NtReadFile(FileHandle, + EventHandle, + NULL, + NULL, + &IoStatus, + NULL, + sizeof(Buffer), + &Offset, + &Key); + WaitStatus = WaitForSingleObject(EventHandle, 0); + ok_eq_ulong(WaitStatus, WAIT_TIMEOUT); + ok_eq_hex(Status, STATUS_ACCESS_VIOLATION); + ok_eq_hex(IoStatus.Status, 0x55555555); + ok_eq_ulongptr(IoStatus.Information, (ULONG_PTR)0x5555555555555555); + KmtEndSeh(STATUS_SUCCESS); + + ResetEvent(EventHandle); + RtlFillMemory(&IoStatus, sizeof(IoStatus), 0x55); + RtlFillMemory(Buffer, sizeof(Buffer), 0x55); + Key = BaseKey | StatusKey | KEY_DATA(0x33); + Offset.QuadPart = 0; + Status = NtReadFile(FileHandle, + EventHandle, + NULL, + NULL, + &IoStatus, + Buffer, + 0, + &Offset, + &Key); + WaitStatus = WaitForSingleObject(EventHandle, 0); + if (ReturnPending) + ok_eq_hex(Status, STATUS_ACCESS_VIOLATION); + else + ok_eq_hex(Status, STATUS_BUFFER_OVERFLOW); + if (Cached && UseFastIo && !ReturnPending) + { + ok_eq_ulong(WaitStatus, WAIT_OBJECT_0); + ok_eq_hex(IoStatus.Status, STATUS_BUFFER_OVERFLOW); + ok_eq_ulongptr(IoStatus.Information, TEST_FILE_SIZE); + } + else + { + ok_eq_ulong(WaitStatus, WAIT_TIMEOUT); + ok_eq_hex(IoStatus.Status, 0x55555555); + ok_eq_ulongptr(IoStatus.Information, (ULONG_PTR)0x5555555555555555); + } + ok_eq_uint(Buffer[0], 0x55); + + ResetEvent(EventHandle); + RtlFillMemory(&IoStatus, sizeof(IoStatus), 0x55); + RtlFillMemory(Buffer, sizeof(Buffer), 0x55); + Key = BaseKey | StatusKey | KEY_DATA(0x44); + Offset.QuadPart = 0; + Status = NtReadFile(FileHandle, + EventHandle, + NULL, + NULL, + &IoStatus, + Buffer, + sizeof(Buffer), + &Offset, + &Key); + WaitStatus = WaitForSingleObject(EventHandle, 0); + ok_eq_hex(Status, TestGetReturnStatus(StatusKey)); + if ((Cached && UseFastIo && !ReturnPending && + (StatusKey == KEY_SUCCEED || StatusKey == KEY_FAIL_OVERFLOW || StatusKey == KEY_FAIL_EOF)) || + !KEY_ERROR(StatusKey)) + { + ok_eq_ulong(WaitStatus, WAIT_OBJECT_0); + ok_eq_hex(IoStatus.Status, TestGetReturnStatus(StatusKey)); + ok_eq_ulongptr(IoStatus.Information, TEST_FILE_SIZE); + } + else + { + ok_eq_ulong(WaitStatus, WAIT_TIMEOUT); + ok_eq_hex(IoStatus.Status, 0x55555555); + ok_eq_ulongptr(IoStatus.Information, (ULONG_PTR)0x5555555555555555); + } + if ((StatusKey != KEY_FAIL_VERIFY_REQUIRED && !KEY_ERROR(StatusKey)) || + Cached) + { + ok_eq_uint(Buffer[0], 0x44); + ok_eq_uint(Buffer[TEST_FILE_SIZE - 1], 0x44); + ok_eq_uint(Buffer[TEST_FILE_SIZE], 0x55); + } + else + { + ok_eq_uint(Buffer[0], 0x55); + } + } +} + +START_TEST(IoReadWrite) +{ + HANDLE FileHandle; + UNICODE_STRING CachedFileName = RTL_CONSTANT_STRING(L"\Device\Kmtest-IoReadWrite\Cached"); + UNICODE_STRING NonCachedFileName = RTL_CONSTANT_STRING(L"\Device\Kmtest-IoReadWrite\NonCached"); + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatus; + NTSTATUS Status; + + KmtLoadDriver(L"IoReadWrite", FALSE); + KmtOpenDriver(); + + RtlFillMemory(&IoStatus, sizeof(IoStatus), 0x55); + InitializeObjectAttributes(&ObjectAttributes, + &NonCachedFileName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenFile(&FileHandle, + FILE_ALL_ACCESS, + &ObjectAttributes, + &IoStatus, + 0, + FILE_NON_DIRECTORY_FILE | + FILE_SYNCHRONOUS_IO_NONALERT); + ok_eq_hex(Status, STATUS_SUCCESS); + if (!skip(NT_SUCCESS(Status), "No file\n")) + { + ok_eq_hex(IoStatus.Status, STATUS_SUCCESS); + ok_eq_ulongptr(IoStatus.Information, FILE_OPENED); + trace("Non-Cached, no FastIo, direct return\n"); + TestRead(FileHandle, FALSE, FALSE, FALSE); + trace("Non-Cached, allow FastIo, direct return\n"); + TestRead(FileHandle, FALSE, TRUE, FALSE); + trace("Non-Cached, no FastIo, pending return\n"); + TestRead(FileHandle, FALSE, FALSE, TRUE); + trace("Non-Cached, allow FastIo, pending return\n"); + TestRead(FileHandle, FALSE, TRUE, TRUE); + NtClose(FileHandle); + } + + RtlFillMemory(&IoStatus, sizeof(IoStatus), 0x55); + InitializeObjectAttributes(&ObjectAttributes, + &CachedFileName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenFile(&FileHandle, + FILE_ALL_ACCESS, + &ObjectAttributes, + &IoStatus, + 0, + FILE_NON_DIRECTORY_FILE | + FILE_SYNCHRONOUS_IO_NONALERT); + ok_eq_hex(Status, STATUS_SUCCESS); + if (!skip(NT_SUCCESS(Status), "No file\n")) + { + ok_eq_hex(IoStatus.Status, STATUS_SUCCESS); + ok_eq_ulongptr(IoStatus.Information, FILE_OPENED); + trace("Cached, no FastIo, direct return\n"); + TestRead(FileHandle, TRUE, FALSE, FALSE); + trace("Cached, allow FastIo, direct return\n"); + TestRead(FileHandle, TRUE, TRUE, FALSE); + trace("Cached, no FastIo, pending return\n"); + TestRead(FileHandle, TRUE, FALSE, TRUE); + trace("Cached, allow FastIo, pending return\n"); + TestRead(FileHandle, TRUE, TRUE, TRUE); + NtClose(FileHandle); + } + + KmtCloseDriver(); + KmtUnloadDriver(); +}
Propchange: trunk/rostests/kmtests/ntos_io/IoReadWrite_user.c ------------------------------------------------------------------------------ svn:eol-style = native