From 3e16da2604f75f4ef8d0ed53fd274c7968c1a99e Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Sun, 21 Apr 2013 19:00:10 +0000 Subject: [PATCH] [KMTESTS] - Add a kernel32 test (I know right) to check how FindFirstFile* modifies wildcards ROSTESTS-104 #resolve svn path=/trunk/; revision=58813 --- rostests/kmtests/CMakeLists.txt | 2 + rostests/kmtests/kernel32/CMakeLists.txt | 16 +++ rostests/kmtests/kernel32/FindFile.h | 13 +++ rostests/kmtests/kernel32/FindFile_drv.c | 123 ++++++++++++++++++++++ rostests/kmtests/kernel32/FindFile_user.c | 94 +++++++++++++++++ rostests/kmtests/kmtest/testlist.c | 2 + 6 files changed, 250 insertions(+) create mode 100644 rostests/kmtests/kernel32/CMakeLists.txt create mode 100644 rostests/kmtests/kernel32/FindFile.h create mode 100644 rostests/kmtests/kernel32/FindFile_drv.c create mode 100644 rostests/kmtests/kernel32/FindFile_user.c diff --git a/rostests/kmtests/CMakeLists.txt b/rostests/kmtests/CMakeLists.txt index 19e4e2cc125..b503992796b 100644 --- a/rostests/kmtests/CMakeLists.txt +++ b/rostests/kmtests/CMakeLists.txt @@ -5,6 +5,7 @@ include_directories( # subdirectories containing special-purpose drivers # add_subdirectory(example) +add_subdirectory(kernel32) add_subdirectory(ntos_io) list(APPEND COMMON_SOURCE @@ -87,6 +88,7 @@ list(APPEND KMTEST_SOURCE kmtest/testlist.c example/Example_user.c + kernel32/FindFile_user.c ntos_io/IoDeviceObject_user.c ${COMMON_SOURCE} diff --git a/rostests/kmtests/kernel32/CMakeLists.txt b/rostests/kmtests/kernel32/CMakeLists.txt new file mode 100644 index 00000000000..852955f4b2d --- /dev/null +++ b/rostests/kmtests/kernel32/CMakeLists.txt @@ -0,0 +1,16 @@ +include_directories( + ../include) + +list(APPEND FINDFILE_DRV_SOURCE + ../kmtest_drv/kmtest_standalone.c + FindFile_drv.c) + +add_library(findfile_drv SHARED ${FINDFILE_DRV_SOURCE}) + +set_module_type(findfile_drv kernelmodedriver) +target_link_libraries(findfile_drv kmtest_printf ${PSEH_LIB}) +add_importlibs(findfile_drv ntoskrnl hal) +add_target_compile_definitions(findfile_drv KMT_STANDALONE_DRIVER) +#add_pch(findfile_drv ../include/kmt_test.h) + +add_cd_file(TARGET findfile_drv DESTINATION reactos/bin FOR all) diff --git a/rostests/kmtests/kernel32/FindFile.h b/rostests/kmtests/kernel32/FindFile.h new file mode 100644 index 00000000000..7b7799e1298 --- /dev/null +++ b/rostests/kmtests/kernel32/FindFile.h @@ -0,0 +1,13 @@ +/* + * PROJECT: ReactOS kernel-mode tests + * LICENSE: GPLv2+ - See COPYING in the top level directory + * PURPOSE: FindFirstFile wildcard substitution test declarations + * PROGRAMMER: Thomas Faber + */ + +#ifndef _KMTEST_FINDFILE_H_ +#define _KMTEST_FINDFILE_H_ + +#define IOCTL_EXPECT 1 + +#endif /* !defined _KMTEST_FINDFILE_H_ */ diff --git a/rostests/kmtests/kernel32/FindFile_drv.c b/rostests/kmtests/kernel32/FindFile_drv.c new file mode 100644 index 00000000000..76a3765b9cb --- /dev/null +++ b/rostests/kmtests/kernel32/FindFile_drv.c @@ -0,0 +1,123 @@ +/* + * PROJECT: ReactOS kernel-mode tests + * LICENSE: GPLv2+ - See COPYING in the top level directory + * PURPOSE: Test driver for FindFirstFile's wildcard substitution + * PROGRAMMER: Thomas Faber + */ + +#include + +#define NDEBUG +#include + +#include "FindFile.h" + +static KMT_MESSAGE_HANDLER TestMessageHandler; +static KMT_IRP_HANDLER TestIrpHandler; + +static UNICODE_STRING ExpectedExpression = RTL_CONSTANT_STRING(L""); +static WCHAR ExpressionBuffer[MAX_PATH]; + +NTSTATUS +TestEntry( + IN PDRIVER_OBJECT DriverObject, + IN PCUNICODE_STRING RegistryPath, + OUT PCWSTR *DeviceName, + IN OUT INT *Flags) +{ + NTSTATUS Status = STATUS_SUCCESS; + + PAGED_CODE(); + + UNREFERENCED_PARAMETER(RegistryPath); + + *DeviceName = L"FindFile"; + *Flags = TESTENTRY_NO_EXCLUSIVE_DEVICE; + + KmtRegisterIrpHandler(IRP_MJ_DIRECTORY_CONTROL, NULL, TestIrpHandler); + KmtRegisterMessageHandler(0, NULL, TestMessageHandler); + + return Status; +} + +VOID +TestUnload( + IN PDRIVER_OBJECT DriverObject) +{ + PAGED_CODE(); +} + +static +NTSTATUS +TestMessageHandler( + IN PDEVICE_OBJECT DeviceObject, + IN ULONG ControlCode, + IN PVOID Buffer OPTIONAL, + IN SIZE_T InLength, + IN OUT PSIZE_T OutLength) +{ + NTSTATUS Status = STATUS_SUCCESS; + + PAGED_CODE(); + + switch (ControlCode) + { + case IOCTL_EXPECT: + { + C_ASSERT(sizeof(ExpressionBuffer) <= UNICODE_STRING_MAX_BYTES); + DPRINT("IOCTL_EXPECT, InLength = %lu\n", InLength); + if (InLength > sizeof(ExpressionBuffer)) + return STATUS_BUFFER_OVERFLOW; + + if (InLength % sizeof(WCHAR) != 0) + return STATUS_INVALID_PARAMETER; + + RtlInitEmptyUnicodeString(&ExpectedExpression, ExpressionBuffer, sizeof(ExpressionBuffer)); + RtlCopyMemory(ExpressionBuffer, Buffer, InLength); + ExpectedExpression.Length = (USHORT)InLength; + DPRINT("IOCTL_EXPECT: %wZ\n", &ExpectedExpression); + + break; + } + default: + return STATUS_NOT_SUPPORTED; + } + + return Status; +} + +static +NTSTATUS +TestIrpHandler( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PIO_STACK_LOCATION IoStackLocation) +{ + NTSTATUS Status = STATUS_NOT_SUPPORTED; + + PAGED_CODE(); + + DPRINT("IRP %x/%x\n", IoStackLocation->MajorFunction, IoStackLocation->MinorFunction); + ASSERT(IoStackLocation->MajorFunction == IRP_MJ_DIRECTORY_CONTROL); + + ok(IoStackLocation->MinorFunction == IRP_MN_QUERY_DIRECTORY, "Minor function: %u\n", IoStackLocation->MinorFunction); + if (IoStackLocation->MinorFunction == IRP_MN_QUERY_DIRECTORY) + { + ok(IoStackLocation->Parameters.QueryDirectory.FileInformationClass == FileBothDirectoryInformation, + "FileInformationClass: %d\n", IoStackLocation->Parameters.QueryDirectory.FileInformationClass); + if (IoStackLocation->Parameters.QueryDirectory.FileInformationClass == FileBothDirectoryInformation) + { + ok(RtlEqualUnicodeString(IoStackLocation->Parameters.QueryDirectory.FileName, &ExpectedExpression, FALSE), + "Expression is '%wZ', expected '%wZ'\n", IoStackLocation->Parameters.QueryDirectory.FileName, &ExpectedExpression); + RtlZeroMemory(Irp->UserBuffer, IoStackLocation->Parameters.QueryDirectory.Length); + Status = STATUS_SUCCESS; + } + } + + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return Status; +} diff --git a/rostests/kmtests/kernel32/FindFile_user.c b/rostests/kmtests/kernel32/FindFile_user.c new file mode 100644 index 00000000000..08c412b4083 --- /dev/null +++ b/rostests/kmtests/kernel32/FindFile_user.c @@ -0,0 +1,94 @@ +/* + * PROJECT: ReactOS kernel-mode tests + * LICENSE: GPLv2+ - See COPYING in the top level directory + * PURPOSE: Test for FindFirstFile's wildcard substitution + * PROGRAMMER: Thomas Faber + */ + +#include + +#include "FindFile.h" + +START_TEST(FindFile) +{ + HANDLE FindHandle; + WIN32_FIND_DATAW FindData; + struct + { + PCWSTR Expression; + PCWSTR ExpectedExpression; + } Tests[] = + { + { L"Hello", L"Hello" }, + + { L"*", L"*" }, + { L"a*", L"a*" }, + { L"*a", L"*a" }, + { L"a*a", L"a*a" }, + { L"**", L"**" }, + { L"*a*", L"*a*" }, + { L"a*a*a", L"a*a*a" }, + + { L"*.*", L"*" }, + { L"a*.*", L"a<\"*" }, + { L"*.*a", L"<\"*a" }, + { L"a*.*a", L"a<\"*a" }, + { L"*.**.*", L"<\"*<\"*" }, + { L"*.*a*.*", L"<\"*a<\"*" }, + { L"a*.*a*.*a", L"a<\"*a<\"*a" }, + + { L".*", L"\"*" }, + { L"a.*", L"a\"*" }, + { L".*a", L"\"*a" }, + { L"a.*a", L"a\"*a" }, + { L".*.*", L"\"<\"*" }, + { L".*a.*", L"\"*a\"*" }, + { L"a.*a.*a", L"a\"*a\"*a" }, + + { L"*.", L"<" }, + { L"a*.", L"a<" }, + { L"*.a", L"<.a" }, + { L"a*.a", L"a<.a" }, + { L"*.*.", L"*" }, + { L"*.a*.", L"<.a<" }, + { L"a*.a*.a", L"a<.a<.a" }, + + { L"?", L">" }, + { L"a?", L"a>" }, + { L"?a", L">a" }, + { L"a?a", L"a>a" }, + { L"??", L">>" }, + { L"?a?", L">a>" }, + { L"a?a?a", L"a>a>a" }, + + { L"f*.", L"f<" }, + { L"f.*", L"f\"*" }, + { L"f*.*", L"f<\"*" }, + { L"f*.f*", L"f<.f*" }, + { L"f*f.*", L"f*f\"*" }, + { L"f*.*f", L"f<\"*f" }, + + /* TODO: add more. Have fun */ + }; + const INT TestCount = sizeof(Tests) / sizeof(Tests[0]); + INT i; + WCHAR ExpressionBuffer[MAX_PATH]; + + KmtLoadDriver(L"FindFile", FALSE); + KmtOpenDriver(); + + for (i = 0; i < TestCount; i++) + { + trace("[%d] '%ls', '%ls'\n", i, Tests[i].Expression, Tests[i].ExpectedExpression); + KmtSendWStringToDriver(IOCTL_EXPECT, Tests[i].ExpectedExpression); + wcscpy(ExpressionBuffer, L"\\\\.\\Global\\GLOBALROOT\\Device\\Kmtest-FindFile\\"); + wcscat(ExpressionBuffer, Tests[i].Expression); + FindHandle = FindFirstFileW(ExpressionBuffer, &FindData); + ok(FindHandle != NULL && FindHandle != INVALID_HANDLE_VALUE, "Handle: %p, error=%lu\n", (PVOID)FindHandle, GetLastError()); + if (FindHandle != INVALID_HANDLE_VALUE) + FindClose(FindHandle); + } + + KmtCloseDriver(); + KmtUnloadDriver(); +} diff --git a/rostests/kmtests/kmtest/testlist.c b/rostests/kmtests/kmtest/testlist.c index eb01375917d..44d234b2d47 100644 --- a/rostests/kmtests/kmtest/testlist.c +++ b/rostests/kmtests/kmtest/testlist.c @@ -8,6 +8,7 @@ #include KMT_TESTFUNC Test_Example; +KMT_TESTFUNC Test_FindFile; KMT_TESTFUNC Test_IoDeviceObject; KMT_TESTFUNC Test_RtlAvlTree; KMT_TESTFUNC Test_RtlException; @@ -19,6 +20,7 @@ KMT_TESTFUNC Test_RtlUnicodeString; const KMT_TEST TestList[] = { { "Example", Test_Example }, + { "FindFile", Test_FindFile }, { "IoDeviceObject", Test_IoDeviceObject }, { "RtlAvlTree", Test_RtlAvlTree }, { "RtlException", Test_RtlException }, -- 2.17.1