- Add some tests for tcpip.sys TDI capabilities (for now, TDI_PROVIDER_INFO)

svn path=/trunk/; revision=65546
This commit is contained in:
Jérôme Gardou 2014-12-02 18:06:48 +00:00
parent 6ef8833b55
commit a928f15f42
7 changed files with 407 additions and 1 deletions

View 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)

View 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 },
};

View file

@ -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)

View file

@ -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);
}

View file

@ -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();
}

View file

@ -0,0 +1,2 @@
#define IOCTL_TEST_TDI 1

View file

@ -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;
}