From: Thomas Faber Date: Thu, 12 Nov 2015 12:55:26 +0000 (+0000) Subject: [KMTESTS:IO] X-Git-Tag: ReactOS-0.4.0~183 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=8160fdc38341f6db4227da5524fec91e02a882d5;hp=607f4f62b86e9f7b4b35af56943782102c0fa6d6 [KMTESTS:IO] - Add a test verifying that opening a file using different parent directories still yields handles to the same file CORE-10483 svn path=/trunk/; revision=69877 --- diff --git a/rostests/kmtests/CMakeLists.txt b/rostests/kmtests/CMakeLists.txt index e2adcd01848..864371c35cf 100644 --- a/rostests/kmtests/CMakeLists.txt +++ b/rostests/kmtests/CMakeLists.txt @@ -53,6 +53,7 @@ list(APPEND KMTEST_DRV_SOURCE ntos_io/IoCreateFile.c ntos_io/IoDeviceInterface.c ntos_io/IoEvent.c + ntos_io/IoFilesystem.c ntos_io/IoInterrupt.c ntos_io/IoIrp.c ntos_io/IoMdl.c diff --git a/rostests/kmtests/kmtest_drv/testlist.c b/rostests/kmtests/kmtest_drv/testlist.c index d2605325d42..e2cbcbd5ebe 100644 --- a/rostests/kmtests/kmtest_drv/testlist.c +++ b/rostests/kmtests/kmtest_drv/testlist.c @@ -26,6 +26,7 @@ KMT_TESTFUNC Test_FsRtlTunnel; KMT_TESTFUNC Test_IoCreateFile; KMT_TESTFUNC Test_IoDeviceInterface; KMT_TESTFUNC Test_IoEvent; +KMT_TESTFUNC Test_IoFilesystem; KMT_TESTFUNC Test_IoInterrupt; KMT_TESTFUNC Test_IoIrp; KMT_TESTFUNC Test_IoMdl; @@ -90,6 +91,7 @@ const KMT_TEST TestList[] = { "IoCreateFile", Test_IoCreateFile }, { "IoDeviceInterface", Test_IoDeviceInterface }, { "IoEvent", Test_IoEvent }, + { "IoFilesystem", Test_IoFilesystem }, { "IoInterrupt", Test_IoInterrupt }, { "IoIrp", Test_IoIrp }, { "IoMdl", Test_IoMdl }, diff --git a/rostests/kmtests/ntos_io/IoFilesystem.c b/rostests/kmtests/ntos_io/IoFilesystem.c new file mode 100644 index 00000000000..9537c6ca5a2 --- /dev/null +++ b/rostests/kmtests/ntos_io/IoFilesystem.c @@ -0,0 +1,178 @@ +/* + * PROJECT: ReactOS kernel-mode tests + * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory + * PURPOSE: Kernel-Mode Test Suite File System test + * PROGRAMMER: Thomas Faber + */ + +#include + +/* FIXME: Test this stuff on non-FAT volumes */ + +static +VOID +TestSharedCacheMap(VOID) +{ + NTSTATUS Status; + struct + { + PCWSTR ParentPath; + PCWSTR RelativePath; + } Tests[] = + { + { 0, L"\\SystemRoot\\system32\\drivers\\etc\\hosts" }, + { L"\\SystemRoot", L"system32\\drivers\\etc\\hosts" }, + { L"\\SystemRoot\\system32", L"drivers\\etc\\hosts" }, + { L"\\SystemRoot\\system32\\drivers", L"etc\\hosts" }, + { L"\\SystemRoot\\system32\\drivers\\etc", L"hosts" }, + }; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatus; + UNICODE_STRING ParentPath; + UNICODE_STRING RelativePath; + HANDLE ParentHandle[RTL_NUMBER_OF(Tests)] = { NULL }; + HANDLE FileHandle[RTL_NUMBER_OF(Tests)] = { NULL }; + PFILE_OBJECT FileObject[RTL_NUMBER_OF(Tests)] = { NULL }; + PFILE_OBJECT SystemRootObject = NULL; + UCHAR Buffer[32]; + HANDLE EventHandle; + LARGE_INTEGER FileOffset; + ULONG i; + + /* We need an event for ZwReadFile */ + InitializeObjectAttributes(&ObjectAttributes, + NULL, + OBJ_KERNEL_HANDLE, + NULL, + NULL); + Status = ZwCreateEvent(&EventHandle, + SYNCHRONIZE, + &ObjectAttributes, + NotificationEvent, + FALSE); + if (skip(NT_SUCCESS(Status), "No event\n")) + goto Cleanup; + + /* Open all test files and get their FILE_OBJECT pointers */ + for (i = 0; i < RTL_NUMBER_OF(Tests); i++) + { + if (Tests[i].ParentPath) + { + RtlInitUnicodeString(&ParentPath, Tests[i].ParentPath); + InitializeObjectAttributes(&ObjectAttributes, + &ParentPath, + OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = ZwOpenFile(&ParentHandle[i], + GENERIC_READ, + &ObjectAttributes, + &IoStatus, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + 0); + ok_eq_hex(Status, STATUS_SUCCESS); + if (skip(NT_SUCCESS(Status), "No parent handle %lu\n", i)) + goto Cleanup; + } + + RtlInitUnicodeString(&RelativePath, Tests[i].RelativePath); + InitializeObjectAttributes(&ObjectAttributes, + &RelativePath, + OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, + ParentHandle[i], + NULL); + Status = ZwOpenFile(&FileHandle[i], + FILE_ALL_ACCESS, + &ObjectAttributes, + &IoStatus, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + 0); + ok_eq_hex(Status, STATUS_SUCCESS); + if (skip(NT_SUCCESS(Status), "No file handle %lu\n", i)) + goto Cleanup; + + Status = ObReferenceObjectByHandle(FileHandle[i], + FILE_ALL_ACCESS, + *IoFileObjectType, + KernelMode, + (PVOID*)&FileObject[i], + NULL); + ok_eq_hex(Status, STATUS_SUCCESS); + if (skip(NT_SUCCESS(Status), "No file object %lu\n", i)) + goto Cleanup; + } + + /* Also get a file object for the SystemRoot directory */ + Status = ObReferenceObjectByHandle(ParentHandle[1], + GENERIC_READ, + *IoFileObjectType, + KernelMode, + (PVOID*)&SystemRootObject, + NULL); + ok_eq_hex(Status, STATUS_SUCCESS); + if (skip(NT_SUCCESS(Status), "No SystemRoot object\n")) + goto Cleanup; + + /* Before read, caching is not initialized */ + ok_eq_pointer(SystemRootObject->SectionObjectPointer, NULL); + for (i = 0; i < RTL_NUMBER_OF(Tests); i++) + { + ok(FileObject[i]->SectionObjectPointer != NULL, "FileObject[%lu]->SectionObjectPointer = NULL\n", i); + ok(FileObject[i]->SectionObjectPointer == FileObject[0]->SectionObjectPointer, + "FileObject[%lu]->SectionObjectPointer = %p, expected %p\n", + i, FileObject[i]->SectionObjectPointer, FileObject[0]->SectionObjectPointer); + } + if (!skip(FileObject[0]->SectionObjectPointer != NULL, "No section object pointers\n")) + ok_eq_pointer(FileObject[0]->SectionObjectPointer->SharedCacheMap, NULL); + + /* Perform a read on one handle to initialize caching */ + FileOffset.QuadPart = 0; + Status = ZwReadFile(FileHandle[0], + EventHandle, + NULL, + NULL, + &IoStatus, + Buffer, + sizeof(Buffer), + &FileOffset, + NULL); + if (Status == STATUS_PENDING) + { + Status = ZwWaitForSingleObject(EventHandle, FALSE, NULL); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = IoStatus.Status; + } + ok_eq_hex(Status, STATUS_SUCCESS); + + /* Now we see a SharedCacheMap for the file */ + ok_eq_pointer(SystemRootObject->SectionObjectPointer, NULL); + for (i = 0; i < RTL_NUMBER_OF(Tests); i++) + { + ok(FileObject[i]->SectionObjectPointer != NULL, "FileObject[%lu]->SectionObjectPointer = NULL\n", i); + ok(FileObject[i]->SectionObjectPointer == FileObject[0]->SectionObjectPointer, + "FileObject[%lu]->SectionObjectPointer = %p, expected %p\n", + i, FileObject[i]->SectionObjectPointer, FileObject[0]->SectionObjectPointer); + } + if (!skip(FileObject[0]->SectionObjectPointer != NULL, "No section object pointers\n")) + ok(FileObject[0]->SectionObjectPointer->SharedCacheMap != NULL, "SharedCacheMap is NULL\n"); + +Cleanup: + if (SystemRootObject) + ObDereferenceObject(SystemRootObject); + if (EventHandle) + ObCloseHandle(EventHandle, KernelMode); + for (i = 0; i < RTL_NUMBER_OF(Tests); i++) + { + if (FileObject[i]) + ObDereferenceObject(FileObject[i]); + if (FileHandle[i]) + ObCloseHandle(FileHandle[i], KernelMode); + if (ParentHandle[i]) + ObCloseHandle(ParentHandle[i], KernelMode); + } +} + +START_TEST(IoFilesystem) +{ + TestSharedCacheMap(); +}