Author: tfaber
Date: Fri May 1 12:50:12 2015
New Revision: 67493
URL:
http://svn.reactos.org/svn/reactos?rev=67493&view=rev
Log:
[KMTESTS:IO]
- Also test write operations in IoReadWrite
- Add some nonzero success statuses
CORE-9624
Modified:
trunk/rostests/kmtests/ntos_io/IoReadWrite.h
trunk/rostests/kmtests/ntos_io/IoReadWrite_drv.c
trunk/rostests/kmtests/ntos_io/IoReadWrite_user.c
Modified: trunk/rostests/kmtests/ntos_io/IoReadWrite.h
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_io/IoReadWri…
==============================================================================
--- trunk/rostests/kmtests/ntos_io/IoReadWrite.h [iso-8859-1] (original)
+++ trunk/rostests/kmtests/ntos_io/IoReadWrite.h [iso-8859-1] Fri May 1 12:50:12 2015
@@ -11,6 +11,10 @@
#define TEST_FILE_SIZE 17
#define KEY_SUCCEED 0x00
+#define KEY_SUCCESS_WAIT1 0x01
+
+#define KEY_INFO_EXISTS 0x41
+
#define KEY_FAIL_MISALIGNED 0x81
#define KEY_FAIL_OVERFLOW 0x82
#define KEY_FAIL_PARTIAL 0x83
@@ -28,7 +32,8 @@
#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) == KEY_INFO_EXISTS ? KEY_FAIL_MISALIGNED : \
+ (key) == KEY_SUCCESS_WAIT1 ? KEY_INFO_EXISTS : \
(key) + 1 )
#define KEY_ERROR(key) (((key) & 0xc0) == 0xc0)
static
@@ -40,6 +45,11 @@
{
case KEY_SUCCEED:
return STATUS_SUCCESS;
+ case KEY_SUCCESS_WAIT1:
+ return STATUS_WAIT_1;
+
+ case KEY_INFO_EXISTS:
+ return STATUS_OBJECT_NAME_EXISTS;
case KEY_FAIL_MISALIGNED:
return STATUS_DATATYPE_MISALIGNMENT;
Modified: trunk/rostests/kmtests/ntos_io/IoReadWrite_drv.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_io/IoReadWri…
==============================================================================
--- trunk/rostests/kmtests/ntos_io/IoReadWrite_drv.c [iso-8859-1] (original)
+++ trunk/rostests/kmtests/ntos_io/IoReadWrite_drv.c [iso-8859-1] Fri May 1 12:50:12
2015
@@ -43,7 +43,9 @@
UNREFERENCED_PARAMETER(RegistryPath);
*DeviceName = L"IoReadWrite";
- *Flags = TESTENTRY_NO_EXCLUSIVE_DEVICE | TESTENTRY_BUFFERED_IO_DEVICE;
+ *Flags = TESTENTRY_NO_EXCLUSIVE_DEVICE |
+ TESTENTRY_BUFFERED_IO_DEVICE |
+ TESTENTRY_NO_READONLY_DEVICE;
TestFastIoDispatch.FastIoRead = TestFastIoRead;
TestFastIoDispatch.FastIoWrite = TestFastIoWrite;
@@ -52,7 +54,7 @@
KmtRegisterIrpHandler(IRP_MJ_CREATE, NULL, TestIrpHandler);
KmtRegisterIrpHandler(IRP_MJ_CLEANUP, NULL, TestIrpHandler);
KmtRegisterIrpHandler(IRP_MJ_READ, NULL, TestIrpHandler);
- //KmtRegisterIrpHandler(IRP_MJ_WRITE, NULL, TestIrpHandler);
+ KmtRegisterIrpHandler(IRP_MJ_WRITE, NULL, TestIrpHandler);
return Status;
}
@@ -188,6 +190,28 @@
}
static
+NTSTATUS
+TestCommonWrite(
+ _In_ PVOID Buffer,
+ _In_ ULONG Length,
+ _In_ LONGLONG FileOffset,
+ _In_ ULONG LockKey,
+ _Out_ PIO_STATUS_BLOCK IoStatus)
+{
+ ULONG i;
+ PUCHAR BufferBytes = Buffer;
+
+ for (i = 0; i < Length; i++)
+ ok(BufferBytes[i] == KEY_GET_DATA(LockKey), "Buffer[%lu] = 0x%x, expected
0x%x\n", i, BufferBytes[i], 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
TestFastIoWrite(
@@ -200,9 +224,38 @@
_Out_ PIO_STATUS_BLOCK IoStatus,
_In_ PDEVICE_OBJECT DeviceObject)
{
+ PTEST_FCB Fcb;
+ NTSTATUS Status;
+
+ //trace("FastIoWrite: %p %lx %p -> %I64d+%lu\n", FileObject, LockKey,
Buffer, FileOffset->QuadPart, Length);
+ 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");
+
TestLastFastWriteKey = LockKey;
- UNIMPLEMENTED;
- return FALSE;
+ 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 = TestCommonWrite(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
@@ -291,10 +344,21 @@
}
else if (IoStack->MajorFunction == IRP_MJ_WRITE)
{
+ //trace("IRP_MJ_WRITE: %p %lx %I64d+%lu -> %p\n",
IoStack->FileObject, IoStack->Parameters.Write.Key,
IoStack->Parameters.Write.ByteOffset.QuadPart, IoStack->Parameters.Write.Length,
Irp->AssociatedIrp.SystemBuffer);
ok_eq_pointer(DeviceObject, TestDeviceObject);
ok_eq_pointer(IoStack->FileObject, TestFileObject);
- UNIMPLEMENTED;
- Status = STATUS_NOT_IMPLEMENTED;
+ Fcb = IoStack->FileObject->FsContext;
+ if (Fcb->Cached)
+ ok_eq_hex(IoStack->Parameters.Write.Key, TestLastFastWriteKey);
+ ok(Irp->AssociatedIrp.SystemBuffer == NULL ||
+ (ULONG_PTR)Irp->AssociatedIrp.SystemBuffer > MM_USER_PROBE_ADDRESS,
+ "Buffer is %p\n",
+ Irp->AssociatedIrp.SystemBuffer);
+ Status = TestCommonWrite(Irp->AssociatedIrp.SystemBuffer,
+ IoStack->Parameters.Write.Length,
+ IoStack->Parameters.Write.ByteOffset.QuadPart,
+ IoStack->Parameters.Write.Key,
+ &Irp->IoStatus);
}
if (Status == STATUS_PENDING)
Modified: trunk/rostests/kmtests/ntos_io/IoReadWrite_user.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_io/IoReadWri…
==============================================================================
--- trunk/rostests/kmtests/ntos_io/IoReadWrite_user.c [iso-8859-1] (original)
+++ trunk/rostests/kmtests/ntos_io/IoReadWrite_user.c [iso-8859-1] Fri May 1 12:50:12
2015
@@ -32,7 +32,7 @@
for (StatusKey = KEY_SUCCEED ; StatusKey != 0xff; StatusKey = KEY_NEXT(StatusKey))
{
- trace("\tSTATUS KEY: %lx\n", StatusKey);
+ //trace("\tSTATUS KEY: %lx\n", StatusKey);
ResetEvent(EventHandle);
RtlFillMemory(&IoStatus, sizeof(IoStatus), 0x55);
Key = BaseKey | StatusKey | KEY_DATA(0x11);
@@ -158,6 +158,140 @@
else
{
ok_eq_uint(Buffer[0], 0x55);
+ }
+ }
+}
+
+static
+VOID
+TestWrite(
+ _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 = NtWriteFile(FileHandle,
+ EventHandle,
+ NULL,
+ NULL,
+ &IoStatus,
+ NULL,
+ 0,
+ &Offset,
+ &Key);
+ WaitStatus = WaitForSingleObject(EventHandle, 0);
+ ok_eq_hex(Status, TestGetReturnStatus(StatusKey));
+ if (!KEY_ERROR(StatusKey))
+ {
+ ok_eq_ulong(WaitStatus, WAIT_OBJECT_0);
+ ok_eq_hex(IoStatus.Status, TestGetReturnStatus(StatusKey));
+ ok_eq_ulongptr(IoStatus.Information, 0);
+ }
+ 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 = NtWriteFile(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 = NtWriteFile(FileHandle,
+ EventHandle,
+ NULL,
+ NULL,
+ &IoStatus,
+ Buffer,
+ 0,
+ &Offset,
+ &Key);
+ WaitStatus = WaitForSingleObject(EventHandle, 0);
+ ok_eq_hex(Status, TestGetReturnStatus(StatusKey));
+ if (!KEY_ERROR(StatusKey))
+ {
+ ok_eq_ulong(WaitStatus, WAIT_OBJECT_0);
+ ok_eq_hex(IoStatus.Status, TestGetReturnStatus(StatusKey));
+ ok_eq_ulongptr(IoStatus.Information, 0);
+ }
+ else
+ {
+ ok_eq_ulong(WaitStatus, WAIT_TIMEOUT);
+ ok_eq_hex(IoStatus.Status, 0x55555555);
+ ok_eq_ulongptr(IoStatus.Information, (ULONG_PTR)0x5555555555555555);
+ }
+
+ ResetEvent(EventHandle);
+ RtlFillMemory(&IoStatus, sizeof(IoStatus), 0x55);
+ RtlFillMemory(Buffer, sizeof(Buffer), 0x44);
+ Key = BaseKey | StatusKey | KEY_DATA(0x44);
+ Offset.QuadPart = 0;
+ Status = NtWriteFile(FileHandle,
+ EventHandle,
+ NULL,
+ NULL,
+ &IoStatus,
+ Buffer,
+ sizeof(Buffer),
+ &Offset,
+ &Key);
+ WaitStatus = WaitForSingleObject(EventHandle, 0);
+ ok_eq_hex(Status, TestGetReturnStatus(StatusKey));
+ if (!KEY_ERROR(StatusKey))
+ {
+ ok_eq_ulong(WaitStatus, WAIT_OBJECT_0);
+ ok_eq_hex(IoStatus.Status, TestGetReturnStatus(StatusKey));
+ ok_eq_ulongptr(IoStatus.Information, sizeof(Buffer));
+ }
+ else
+ {
+ ok_eq_ulong(WaitStatus, WAIT_TIMEOUT);
+ ok_eq_hex(IoStatus.Status, 0x55555555);
+ ok_eq_ulongptr(IoStatus.Information, (ULONG_PTR)0x5555555555555555);
}
}
}
@@ -192,14 +326,23 @@
{
ok_eq_hex(IoStatus.Status, STATUS_SUCCESS);
ok_eq_ulongptr(IoStatus.Information, FILE_OPENED);
- trace("Non-Cached, no FastIo, direct return\n");
+ trace("Non-Cached read, no FastIo, direct return\n");
TestRead(FileHandle, FALSE, FALSE, FALSE);
- trace("Non-Cached, allow FastIo, direct return\n");
+ trace("Non-Cached read, allow FastIo, direct return\n");
TestRead(FileHandle, FALSE, TRUE, FALSE);
- trace("Non-Cached, no FastIo, pending return\n");
+ trace("Non-Cached read, no FastIo, pending return\n");
TestRead(FileHandle, FALSE, FALSE, TRUE);
- trace("Non-Cached, allow FastIo, pending return\n");
+ trace("Non-Cached read, allow FastIo, pending return\n");
TestRead(FileHandle, FALSE, TRUE, TRUE);
+
+ trace("Non-Cached write, no FastIo, direct return\n");
+ TestWrite(FileHandle, FALSE, FALSE, FALSE);
+ trace("Non-Cached write, allow FastIo, direct return\n");
+ TestWrite(FileHandle, FALSE, TRUE, FALSE);
+ trace("Non-Cached write, no FastIo, pending return\n");
+ TestWrite(FileHandle, FALSE, FALSE, TRUE);
+ trace("Non-Cached write, allow FastIo, pending return\n");
+ TestWrite(FileHandle, FALSE, TRUE, TRUE);
NtClose(FileHandle);
}
@@ -221,14 +364,23 @@
{
ok_eq_hex(IoStatus.Status, STATUS_SUCCESS);
ok_eq_ulongptr(IoStatus.Information, FILE_OPENED);
- trace("Cached, no FastIo, direct return\n");
+ trace("Cached read, no FastIo, direct return\n");
TestRead(FileHandle, TRUE, FALSE, FALSE);
- trace("Cached, allow FastIo, direct return\n");
+ trace("Cached read, allow FastIo, direct return\n");
TestRead(FileHandle, TRUE, TRUE, FALSE);
- trace("Cached, no FastIo, pending return\n");
+ trace("Cached read, no FastIo, pending return\n");
TestRead(FileHandle, TRUE, FALSE, TRUE);
- trace("Cached, allow FastIo, pending return\n");
+ trace("Cached read, allow FastIo, pending return\n");
TestRead(FileHandle, TRUE, TRUE, TRUE);
+
+ trace("Cached write, no FastIo, direct return\n");
+ TestWrite(FileHandle, TRUE, FALSE, FALSE);
+ trace("Cached write, allow FastIo, direct return\n");
+ TestWrite(FileHandle, TRUE, TRUE, FALSE);
+ trace("Cached write, no FastIo, pending return\n");
+ TestWrite(FileHandle, TRUE, FALSE, TRUE);
+ trace("Cached write, allow FastIo, pending return\n");
+ TestWrite(FileHandle, TRUE, TRUE, TRUE);
NtClose(FileHandle);
}