[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
This commit is contained in:
Thomas Faber 2015-11-12 12:55:26 +00:00
parent 607f4f62b8
commit 8160fdc383
3 changed files with 181 additions and 0 deletions

View file

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

View file

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

View file

@ -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 <thomas.faber@reactos.org>
*/
#include <kmt_test.h>
/* 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();
}