[KMTEST]
authorJérôme Gardou <jerome.gardou@reactos.org>
Tue, 2 Dec 2014 18:06:48 +0000 (18:06 +0000)
committerJérôme Gardou <jerome.gardou@reactos.org>
Tue, 2 Dec 2014 18:06:48 +0000 (18:06 +0000)
 - Add some tests for tcpip.sys TDI capabilities (for now, TDI_PROVIDER_INFO)

svn path=/trunk/; revision=65546

rostests/kmtests/CMakeLists.txt
rostests/kmtests/kmtest/testlist.c
rostests/kmtests/tcpip/CMakeLists.txt [new file with mode: 0644]
rostests/kmtests/tcpip/TcpIp_drv.c [new file with mode: 0644]
rostests/kmtests/tcpip/TcpIp_user.c [new file with mode: 0644]
rostests/kmtests/tcpip/tcpip.h [new file with mode: 0644]
rostests/kmtests/tcpip/tdi.c [new file with mode: 0644]

index 969ba8b..feabf54 100644 (file)
@@ -7,6 +7,7 @@ include_directories(include)
 add_subdirectory(example)
 add_subdirectory(kernel32)
 add_subdirectory(ntos_io)
+add_subdirectory(tcpip)
 
 list(APPEND COMMON_SOURCE
     example/GuardedMemory.c
@@ -108,6 +109,7 @@ list(APPEND KMTEST_SOURCE
     example/Example_user.c
     kernel32/FindFile_user.c
     ntos_io/IoDeviceObject_user.c
+    tcpip/TcpIp_user.c
     ${COMMON_SOURCE}
 
     kmtest/kmtest.rc)
@@ -129,7 +131,8 @@ add_dependencies(kmtest_drivers
     kmtest_drv
     example_drv
     iodeviceobject_drv
-    iohelper_drv)
+    iohelper_drv
+    tcpip_test_drv)
 
 add_custom_target(kmtest_all)
 add_dependencies(kmtest_all kmtest_drivers kmtest)
index c12fa11..22c7d8c 100644 (file)
@@ -17,6 +17,8 @@ KMT_TESTFUNC Test_RtlMemory;
 KMT_TESTFUNC Test_RtlRegistry;
 KMT_TESTFUNC Test_RtlSplayTree;
 KMT_TESTFUNC Test_RtlUnicodeString;
+KMT_TESTFUNC Test_TcpIpIoctl;
+KMT_TESTFUNC Test_TcpIpTdi;
 
 /* tests with a leading '-' will not be listed */
 const KMT_TEST TestList[] =
@@ -31,5 +33,6 @@ const KMT_TEST TestList[] =
     { "RtlRegistry",        Test_RtlRegistry },
     { "RtlSplayTree",       Test_RtlSplayTree },
     { "RtlUnicodeString",   Test_RtlUnicodeString },
+    { "TcpIpTdi",           Test_TcpIpTdi },
     { NULL,                 NULL },
 };
diff --git a/rostests/kmtests/tcpip/CMakeLists.txt b/rostests/kmtests/tcpip/CMakeLists.txt
new file mode 100644 (file)
index 0000000..2995dcc
--- /dev/null
@@ -0,0 +1,15 @@
+
+include_directories(../include)
+
+list(APPEND TCPIP_TEST_DRV_SOURCE
+    ../kmtest_drv/kmtest_standalone.c
+    tdi.c
+    TcpIp_drv.c)
+
+add_library(tcpip_drv SHARED ${TCPIP_TEST_DRV_SOURCE})
+set_module_type(tcpip_drv kernelmodedriver)
+target_link_libraries(tcpip_drv kmtest_printf ${PSEH_LIB})
+add_importlibs(tcpip_drv ntoskrnl hal)
+add_target_compile_definitions(tcpip_drv KMT_STANDALONE_DRIVER)
+#add_pch(example_drv ../include/kmt_test.h)
+add_cd_file(TARGET tcpip_drv DESTINATION reactos/bin FOR all)
diff --git a/rostests/kmtests/tcpip/TcpIp_drv.c b/rostests/kmtests/tcpip/TcpIp_drv.c
new file mode 100644 (file)
index 0000000..6877e52
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * PROJECT:         ReactOS kernel-mode tests
+ * LICENSE:         GPLv2+ - See COPYING in the top level directory
+ * PURPOSE:         Kernel-Mode Test Suite for tcpip.sys
+ * PROGRAMMER:      Jérôme Gardou <jerome.gardou@reactos.org>
+ */
+
+#include <kmt_test.h>
+#include "tcpip.h"
+
+extern KMT_MESSAGE_HANDLER TestTdi;
+
+static struct
+{
+    ULONG ControlCode;
+    PKMT_MESSAGE_HANDLER Handler;
+} MessageHandlers[] =
+{
+    { IOCTL_TEST_TDI, TestTdi },
+};
+
+NTSTATUS
+TestEntry(
+    _In_ PDRIVER_OBJECT DriverObject,
+    _In_ PCUNICODE_STRING RegistryPath,
+    _Out_ PCWSTR *DeviceName,
+    _Inout_ INT *Flags)
+{
+    ULONG i;
+
+    PAGED_CODE();
+
+    UNREFERENCED_PARAMETER(DriverObject);
+    UNREFERENCED_PARAMETER(RegistryPath);
+    UNREFERENCED_PARAMETER(Flags);
+
+    *DeviceName = L"TcpIp";
+
+    for (i = 0; i < (sizeof(MessageHandlers) / sizeof(MessageHandlers[0])); i++)
+        KmtRegisterMessageHandler(MessageHandlers[i].ControlCode, NULL, MessageHandlers[i].Handler);
+
+    trace("TcpIp test driver loaded.\n");
+
+    return STATUS_SUCCESS;
+}
+
+VOID
+TestUnload(
+    _In_ PDRIVER_OBJECT DriverObject)
+{
+    PAGED_CODE();
+
+    UNREFERENCED_PARAMETER(DriverObject);
+}
+
diff --git a/rostests/kmtests/tcpip/TcpIp_user.c b/rostests/kmtests/tcpip/TcpIp_user.c
new file mode 100644 (file)
index 0000000..2b5da02
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * PROJECT:         ReactOS kernel-mode tests
+ * LICENSE:         GPLv2+ - See COPYING in the top level directory
+ * PURPOSE:         User mode part of the TcpIp.sys test suite
+ * PROGRAMMER:      Jérôme Gardou <jerome.gardou@reactos.org>
+ */
+
+#include <kmt_test.h>
+
+#include "tcpip.h"
+
+static
+void
+LoadTcpIpTestDriver(void)
+{
+    /* Start the special-purpose driver */
+    KmtLoadDriver(L"TcpIp", FALSE);
+    KmtOpenDriver();
+}
+
+static
+void
+UnloadTcpIpTestDriver(void)
+{
+    /* Stop the driver. */
+    KmtCloseDriver();
+    KmtUnloadDriver();
+}
+
+START_TEST(TcpIpTdi)
+{
+    LoadTcpIpTestDriver();
+
+    ok(KmtSendToDriver(IOCTL_TEST_TDI) == ERROR_SUCCESS, "\n");
+
+    UnloadTcpIpTestDriver();
+}
diff --git a/rostests/kmtests/tcpip/tcpip.h b/rostests/kmtests/tcpip/tcpip.h
new file mode 100644 (file)
index 0000000..45a5c50
--- /dev/null
@@ -0,0 +1,2 @@
+
+#define IOCTL_TEST_TDI      1
diff --git a/rostests/kmtests/tcpip/tdi.c b/rostests/kmtests/tcpip/tdi.c
new file mode 100644 (file)
index 0000000..d2f5b8a
--- /dev/null
@@ -0,0 +1,291 @@
+/*
+ * PROJECT:         ReactOS kernel-mode tests
+ * LICENSE:         LGPLv2+ - See COPYING.LIB in the top level directory
+ * PURPOSE:         Kernel-Mode Test Suite for TCPIP.sys
+ * PROGRAMMER:      Jérôme Gardou <jerome.gardou@reactos.org>
+ */
+
+#include <kmt_test.h>
+#include <tdikrnl.h>
+
+static
+NTAPI
+NTSTATUS
+IrpCompletionRoutine(
+    _In_ PDEVICE_OBJECT    DeviceObject,
+    _In_ PIRP              Irp,
+    _In_ PVOID             Context)
+{
+    UNREFERENCED_PARAMETER(DeviceObject);
+    UNREFERENCED_PARAMETER(Irp);
+
+    KeSetEvent((PKEVENT)Context, IO_NETWORK_INCREMENT, FALSE);
+
+    return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+static
+VOID
+TestProviderInfo(void)
+{
+    struct
+    {
+        UNICODE_STRING DeviceName;
+        NTSTATUS CreateStatus, IrpStatus;
+        TDI_PROVIDER_INFO ExpectedInfo;
+    } TestData[] =
+    {
+        {
+            RTL_CONSTANT_STRING(L"\\Device\\Tcp"),
+            STATUS_SUCCESS, STATUS_SUCCESS,
+            {
+                0x0002,             // Version
+                0x3FFFFFFF,         // MaxSendSize
+                0,                  // MaxConnectionUserData
+                65515,              // MaxDatagramSize
+                TDI_SERVICE_CONNECTION_MODE |
+                    TDI_SERVICE_ORDERLY_RELEASE |
+                    TDI_SERVICE_CONNECTIONLESS_MODE |
+                    TDI_SERVICE_ERROR_FREE_DELIVERY |
+                    TDI_SERVICE_BROADCAST_SUPPORTED |
+                    TDI_SERVICE_DELAYED_ACCEPTANCE |
+                    TDI_SERVICE_EXPEDITED_DATA |
+                    TDI_SERVICE_NO_ZERO_LENGTH |
+                    TDI_SERVICE_DGRAM_CONNECTION |
+                    TDI_SERVICE_FORCE_ACCESS_CHECK |
+                    TDI_SERVICE_DIRECT_ACCEPT |
+                    TDI_SERVICE_ADDRESS_SECURITY |
+                    TDI_SERVICE_NO_PUSH,                  // ServiceFlags
+                1,                  // MinimumLookaheadData
+                65535,              // MaximumLookaheadData
+                0,                  // NumberOfResources
+                {{0}}               // StartTime
+            }
+        },
+        {
+            RTL_CONSTANT_STRING(L"\\Device\\Udp"),
+            STATUS_SUCCESS, STATUS_SUCCESS,
+            {
+                0x0002,             // Version
+                0x3FFFFFFF,         // MaxSendSize
+                0,                  // MaxConnectionUserData
+                65507,              // MaxDatagramSize
+                TDI_SERVICE_CONNECTION_MODE |
+                    TDI_SERVICE_ORDERLY_RELEASE |
+                    TDI_SERVICE_CONNECTIONLESS_MODE |
+                    TDI_SERVICE_ERROR_FREE_DELIVERY |
+                    TDI_SERVICE_BROADCAST_SUPPORTED |
+                    TDI_SERVICE_DELAYED_ACCEPTANCE |
+                    TDI_SERVICE_EXPEDITED_DATA |
+                    TDI_SERVICE_NO_ZERO_LENGTH |
+                    TDI_SERVICE_DGRAM_CONNECTION |
+                    TDI_SERVICE_FORCE_ACCESS_CHECK |
+                    TDI_SERVICE_DIRECT_ACCEPT |
+                    TDI_SERVICE_ADDRESS_SECURITY,   // ServiceFlags
+                1,                  // MinimumLookaheadData
+                65535,              // MaximumLookaheadData
+                0,                  // NumberOfResources
+                {{0}}               // StartTime
+            }
+        },
+        {
+            RTL_CONSTANT_STRING(L"\\Device\\Ip"),
+            STATUS_SUCCESS, STATUS_NOT_IMPLEMENTED,
+        },
+        {
+            RTL_CONSTANT_STRING(L"\\Device\\RawIp"),
+            STATUS_SUCCESS, STATUS_SUCCESS,
+            {
+                0x0002,             // Version
+                0x3FFFFFFF,         // MaxSendSize
+                0,                  // MaxConnectionUserData
+                65515,              // MaxDatagramSize
+                TDI_SERVICE_CONNECTION_MODE |
+                    TDI_SERVICE_ORDERLY_RELEASE |
+                    TDI_SERVICE_CONNECTIONLESS_MODE |
+                    TDI_SERVICE_ERROR_FREE_DELIVERY |
+                    TDI_SERVICE_BROADCAST_SUPPORTED |
+                    TDI_SERVICE_DELAYED_ACCEPTANCE |
+                    TDI_SERVICE_EXPEDITED_DATA |
+                    TDI_SERVICE_NO_ZERO_LENGTH |
+                    TDI_SERVICE_DGRAM_CONNECTION |
+                    TDI_SERVICE_FORCE_ACCESS_CHECK |
+                    TDI_SERVICE_DIRECT_ACCEPT |
+                    TDI_SERVICE_ADDRESS_SECURITY,   // ServiceFlags
+                1,                  // MinimumLookaheadData
+                65535,              // MaximumLookaheadData
+                0,                  // NumberOfResources
+                {{0}}               // StartTime
+            }
+        },
+        {
+            RTL_CONSTANT_STRING(L"\\Device\\IPMULTICAST"),
+            STATUS_OBJECT_NAME_NOT_FOUND,
+        },
+    };
+    ULONG i;
+
+    for (i = 0; i < (sizeof(TestData) / sizeof(TestData[0])); i++)
+    {
+        IO_STATUS_BLOCK StatusBlock;
+        NTSTATUS Status;
+        FILE_OBJECT* FileObject;
+        DEVICE_OBJECT* DeviceObject;
+        PIRP Irp;
+        KEVENT Event;
+        PMDL Mdl;
+        TDI_PROVIDER_INFO* ProviderInfo;
+        HANDLE FileHandle;
+        OBJECT_ATTRIBUTES ObjectAttributes;
+
+        trace("Testing device %wZ\n", &TestData[i].DeviceName);
+
+        InitializeObjectAttributes(
+            &ObjectAttributes,
+            &TestData[i].DeviceName,
+            OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
+            NULL,
+            NULL);
+
+        Status = ZwCreateFile(
+            &FileHandle,
+            FILE_READ_DATA | FILE_WRITE_DATA,
+            &ObjectAttributes,
+            &StatusBlock,
+            NULL,
+            FILE_ATTRIBUTE_NORMAL,
+            FILE_SHARE_READ | FILE_SHARE_WRITE,
+            FILE_OPEN,
+            0,
+            NULL,
+            0);
+        ok_eq_hex(Status, TestData[i].CreateStatus);
+        if (!NT_SUCCESS(Status))
+            continue;
+
+        Status = ObReferenceObjectByHandle(
+            FileHandle,
+            GENERIC_READ,
+            *IoFileObjectType,
+            KernelMode,
+            (PVOID*)&FileObject,
+            NULL);
+        ok_eq_hex(Status, STATUS_SUCCESS);
+        if (!NT_SUCCESS(Status))
+            return;
+
+        DeviceObject = IoGetRelatedDeviceObject(FileObject);
+        ok(DeviceObject != NULL, "Device object is NULL!\n");
+        if (!DeviceObject)
+        {
+            ObDereferenceObject(FileObject);
+            return;
+        }
+
+        ProviderInfo = ExAllocatePoolWithTag(NonPagedPool, sizeof(*ProviderInfo), 'tseT');
+        ok(ProviderInfo != NULL, "Ran out of memory.\n");
+        if (!ProviderInfo)
+        {
+            ObDereferenceObject(FileObject);
+            return;
+        }
+
+        Mdl = IoAllocateMdl(ProviderInfo, sizeof(*ProviderInfo), FALSE, FALSE, NULL);
+        ok(Mdl != NULL, "Could not allocate the MDL!\n");
+        if (!Mdl)
+        {
+            ExFreePoolWithTag(ProviderInfo, 'tseT');
+            ObDereferenceObject(FileObject);
+            return;
+        }
+
+        MmBuildMdlForNonPagedPool(Mdl);
+
+        /* Build the IRP */
+        KeInitializeEvent(&Event, NotificationEvent, FALSE);
+        Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
+        ok(Irp != NULL, "TdiBuildInternalDeviceControlIrp returned NULL!\n");
+        if (!Irp)
+        {
+            IoFreeMdl(Mdl);
+            ExFreePoolWithTag(ProviderInfo, 'tseT');
+            ObDereferenceObject(FileObject);
+            return;
+        }
+
+        TdiBuildQueryInformation(
+            Irp,
+            DeviceObject,
+            FileObject,
+            NULL,
+            NULL,
+            TDI_QUERY_PROVIDER_INFO,
+            Mdl);
+
+        IoSetCompletionRoutine(Irp, IrpCompletionRoutine, &Event, TRUE, TRUE, TRUE);
+
+        Status = IoCallDriver(DeviceObject, Irp);
+        if (Status == STATUS_PENDING)
+        {
+            KeWaitForSingleObject(
+                &Event,
+                Executive,
+                KernelMode,
+                FALSE,
+                NULL);
+            Status = StatusBlock.Status;
+        }
+        ok_eq_hex(Status, TestData[i].IrpStatus);
+
+        IoFreeIrp(Irp);
+        IoFreeMdl(Mdl);
+        ObDereferenceObject(FileObject);
+
+        if (!NT_SUCCESS(Status))
+        {
+            ExFreePoolWithTag(ProviderInfo, 'tseT');
+            continue;
+        }
+
+        ok_eq_hex(ProviderInfo->Version, TestData[i].ExpectedInfo.Version);
+        ok_eq_ulong(ProviderInfo->MaxSendSize, TestData[i].ExpectedInfo.MaxSendSize);
+        ok_eq_ulong(ProviderInfo->MaxConnectionUserData, TestData[i].ExpectedInfo.MaxConnectionUserData);
+        ok_eq_ulong(ProviderInfo->MaxDatagramSize, TestData[i].ExpectedInfo.MaxDatagramSize);
+        ok_eq_hex(ProviderInfo->ServiceFlags, TestData[i].ExpectedInfo.ServiceFlags);
+        ok_eq_ulong(ProviderInfo->MinimumLookaheadData, TestData[i].ExpectedInfo.MinimumLookaheadData);
+        ok_eq_ulong(ProviderInfo->MaximumLookaheadData, TestData[i].ExpectedInfo.MaximumLookaheadData);
+        ok_eq_ulong(ProviderInfo->NumberOfResources, TestData[i].ExpectedInfo.NumberOfResources);
+
+        ExFreePoolWithTag(ProviderInfo, 'tseT');
+    }
+}
+
+static KSTART_ROUTINE RunTest;
+static
+VOID
+NTAPI
+RunTest(
+    _In_ PVOID Context)
+{
+    UNREFERENCED_PARAMETER(Context);
+
+    TestProviderInfo();
+}
+
+KMT_MESSAGE_HANDLER TestTdi;
+NTSTATUS
+TestTdi(
+    _In_ PDEVICE_OBJECT DeviceObject,
+    _In_ ULONG ControlCode,
+    _In_opt_ PVOID Buffer,
+    _In_ SIZE_T InLength,
+    _Inout_ PSIZE_T OutLength
+)
+{
+    PKTHREAD Thread;
+
+    Thread = KmtStartThread(RunTest, NULL);
+    KmtFinishThread(Thread, NULL);
+
+    return STATUS_SUCCESS;
+}