Author: pschweitzer
Date: Tue Sep 22 22:31:08 2015
New Revision: 69322
URL:
http://svn.reactos.org/svn/reactos?rev=69322&view=rev
Log:
[KMTESTS:IO]
Extend the IoCreateFile tests with two parts tests.
First part properly checks for opening/reparse handling on mount points (and ideally on
symlinks, see below).
The other part checks for proper handling of the IO_STOP_ON_SYMLINK parameter.
Regarding symlink, I'm clearly not convinced that what I did is correct (hence the
failure on both W2K3 & ROS). It seems to me that symlink resolution is up to the FSD
and not to IO which only handles mount point traversal.
If someone (Alex?) can confirm/infirm and give more insight, that's more than
welcome.
Added:
trunk/rostests/kmtests/ntos_io/IoCreateFile.h (with props)
trunk/rostests/kmtests/ntos_io/IoCreateFile_drv.c (with props)
trunk/rostests/kmtests/ntos_io/IoCreateFile_user.c (with props)
Modified:
trunk/rostests/kmtests/CMakeLists.txt
trunk/rostests/kmtests/kmtest/testlist.c
trunk/rostests/kmtests/ntos_io/CMakeLists.txt
Modified: trunk/rostests/kmtests/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/CMakeLists.txt?re…
==============================================================================
--- trunk/rostests/kmtests/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/rostests/kmtests/CMakeLists.txt [iso-8859-1] Tue Sep 22 22:31:08 2015
@@ -111,6 +111,7 @@
example/Example_user.c
kernel32/FindFile_user.c
+ ntos_io/IoCreateFile_user.c
ntos_io/IoDeviceObject_user.c
ntos_io/IoReadWrite_user.c
tcpip/TcpIp_user.c
@@ -134,6 +135,7 @@
add_dependencies(kmtest_drivers
kmtest_drv
example_drv
+ iocreatefile_drv
iodeviceobject_drv
iohelper_drv
ioreadwrite_drv
Modified: trunk/rostests/kmtests/kmtest/testlist.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/kmtest/testlist.c…
==============================================================================
--- trunk/rostests/kmtests/kmtest/testlist.c [iso-8859-1] (original)
+++ trunk/rostests/kmtests/kmtest/testlist.c [iso-8859-1] Tue Sep 22 22:31:08 2015
@@ -9,6 +9,7 @@
KMT_TESTFUNC Test_Example;
KMT_TESTFUNC Test_FindFile;
+KMT_TESTFUNC Test_IoCreateFile;
KMT_TESTFUNC Test_IoDeviceObject;
KMT_TESTFUNC Test_IoReadWrite;
KMT_TESTFUNC Test_RtlAvlTree;
@@ -27,6 +28,7 @@
{
{ "-Example", Test_Example },
{ "FindFile", Test_FindFile },
+ { "IoCreateFile", Test_IoCreateFile },
{ "IoDeviceObject", Test_IoDeviceObject },
{ "IoReadWrite", Test_IoReadWrite },
{ "RtlAvlTree", Test_RtlAvlTree },
Modified: trunk/rostests/kmtests/ntos_io/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_io/CMakeList…
==============================================================================
--- trunk/rostests/kmtests/ntos_io/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/rostests/kmtests/ntos_io/CMakeLists.txt [iso-8859-1] Tue Sep 22 22:31:08 2015
@@ -1,5 +1,20 @@
include_directories(../include)
+
+#
+# IoCreateFile
+#
+list(APPEND IOCREATEFILE_DRV_SOURCE
+ ../kmtest_drv/kmtest_standalone.c
+ IoCreateFile_drv.c)
+
+add_library(iocreatefile_drv SHARED ${IOCREATEFILE_DRV_SOURCE})
+set_module_type(iocreatefile_drv kernelmodedriver)
+target_link_libraries(iocreatefile_drv kmtest_printf ${PSEH_LIB})
+add_importlibs(iocreatefile_drv ntoskrnl hal)
+add_target_compile_definitions(iocreatefile_drv KMT_STANDALONE_DRIVER)
+#add_pch(iocreatefile_drv ../include/kmt_test.h)
+add_cd_file(TARGET iocreatefile_drv DESTINATION reactos/bin FOR all)
#
# IoDeviceObject
Added: trunk/rostests/kmtests/ntos_io/IoCreateFile.h
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_io/IoCreateF…
==============================================================================
--- trunk/rostests/kmtests/ntos_io/IoCreateFile.h (added)
+++ trunk/rostests/kmtests/ntos_io/IoCreateFile.h [iso-8859-1] Tue Sep 22 22:31:08 2015
@@ -0,0 +1,14 @@
+/*
+ * PROJECT: ReactOS kernel-mode tests
+ * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
+ * PURPOSE: IoCreateFile test declarations
+ * PROGRAMMER: Pierre Schweitzer <pierre(a)reactos.org>
+ */
+
+#ifndef _KMTEST_IOCREATEFILE_H_
+#define _KMTEST_IOCREATEFILE_H_
+
+#define IOCTL_CREATE_SYMLINK 1
+#define IOCTL_CREATE_NO_SYMLINK 2
+
+#endif /* !defined _KMTEST_IOCREATEFILE_H_ */
Propchange: trunk/rostests/kmtests/ntos_io/IoCreateFile.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/rostests/kmtests/ntos_io/IoCreateFile_drv.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_io/IoCreateF…
==============================================================================
--- trunk/rostests/kmtests/ntos_io/IoCreateFile_drv.c (added)
+++ trunk/rostests/kmtests/ntos_io/IoCreateFile_drv.c [iso-8859-1] Tue Sep 22 22:31:08
2015
@@ -0,0 +1,270 @@
+/*
+ * PROJECT: ReactOS kernel-mode tests
+ * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
+ * PURPOSE: Test driver for reparse point operations
+ * PROGRAMMER: Pierre Schweitzer <pierre(a)reactos.org>
+ */
+
+#include <kmt_test.h>
+
+#define NDEBUG
+#include <debug.h>
+
+#include "IoCreateFile.h"
+
+typedef struct _TEST_FCB
+{
+ FSRTL_ADVANCED_FCB_HEADER Header;
+ SECTION_OBJECT_POINTERS SectionObjectPointers;
+ FAST_MUTEX HeaderMutex;
+} TEST_FCB, *PTEST_FCB;
+
+static KMT_IRP_HANDLER TestIrpHandler;
+static KMT_MESSAGE_HANDLER TestMessageHandler;
+
+static PFILE_OBJECT TestFileObject;
+static PDEVICE_OBJECT TestDeviceObject;
+
+NTSTATUS
+TestEntry(
+ _In_ PDRIVER_OBJECT DriverObject,
+ _In_ PCUNICODE_STRING RegistryPath,
+ _Out_ PCWSTR *DeviceName,
+ _Inout_ INT *Flags)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(RegistryPath);
+
+ *DeviceName = L"IoCreateFile";
+ *Flags = TESTENTRY_NO_EXCLUSIVE_DEVICE |
+ TESTENTRY_BUFFERED_IO_DEVICE |
+ TESTENTRY_NO_READONLY_DEVICE;
+
+ KmtRegisterIrpHandler(IRP_MJ_CREATE, NULL, TestIrpHandler);
+ KmtRegisterIrpHandler(IRP_MJ_CLEANUP, NULL, TestIrpHandler);
+ KmtRegisterMessageHandler(0, NULL, TestMessageHandler);
+
+ return Status;
+}
+
+VOID
+TestUnload(
+ _In_ PDRIVER_OBJECT DriverObject)
+{
+ PAGED_CODE();
+}
+
+static
+NTSTATUS
+TestIrpHandler(
+ _In_ PDEVICE_OBJECT DeviceObject,
+ _In_ PIRP Irp,
+ _In_ PIO_STACK_LOCATION IoStack)
+{
+ NTSTATUS Status;
+ PTEST_FCB Fcb;
+ CACHE_UNINITIALIZE_EVENT CacheUninitEvent;
+
+ PAGED_CODE();
+
+ DPRINT("IRP %x/%x\n", IoStack->MajorFunction,
IoStack->MinorFunction);
+ ASSERT(IoStack->MajorFunction == IRP_MJ_CREATE ||
+ IoStack->MajorFunction == IRP_MJ_CLEANUP);
+
+ Status = STATUS_NOT_SUPPORTED;
+ Irp->IoStatus.Information = 0;
+
+ if (IoStack->MajorFunction == IRP_MJ_CREATE)
+ {
+ ok((IoStack->Parameters.Create.Options & FILE_OPEN_REPARSE_POINT) == 0,
"FILE_OPEN_REPARSE_POINT set\n");
+ ok((IoStack->Flags == 0) || (IoStack->Flags == SL_STOP_ON_SYMLINK),
"IoStack->Flags = %lx\n", IoStack->Flags);
+
+ if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR))
+ {
+ TestDeviceObject = DeviceObject;
+ TestFileObject = IoStack->FileObject;
+ }
+ if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR)
&&
+ IoStack->FileObject->FileName.Buffer[1] == 'M')
+ {
+ PREPARSE_DATA_BUFFER Reparse;
+
+ Irp->Tail.Overlay.AuxiliaryBuffer = ExAllocatePoolWithTag(NonPagedPool,
MAXIMUM_REPARSE_DATA_BUFFER_SIZE, 'FwrI');
+ Reparse = (PREPARSE_DATA_BUFFER)Irp->Tail.Overlay.AuxiliaryBuffer;
+
+ RtlZeroMemory(Reparse, MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
+ Reparse->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
+ Reparse->ReparseDataLength = 12 + sizeof(L"\\??\\C:\\Documents and
Settings");
+ Reparse->MountPointReparseBuffer.SubstituteNameLength =
sizeof(L"\\??\\C:\\Documents and Settings") - sizeof(UNICODE_NULL);
+ Reparse->MountPointReparseBuffer.PrintNameOffset =
sizeof(L"\\??\\C:\\Documents and Settings");
+ RtlCopyMemory(Reparse->MountPointReparseBuffer.PathBuffer,
L"\\??\\C:\\Documents and Settings", sizeof(L"\\??\\C:\\Documents and
Settings"));
+ Irp->IoStatus.Information = IO_REPARSE_TAG_MOUNT_POINT;
+ Status = STATUS_REPARSE;
+ }
+ else if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR)
&&
+ IoStack->FileObject->FileName.Buffer[1] == 'S')
+ {
+ if (IoStack->Flags & SL_STOP_ON_SYMLINK)
+ {
+ Status = STATUS_STOPPED_ON_SYMLINK;
+ }
+ else
+ {
+ PREPARSE_DATA_BUFFER Reparse;
+
+ Irp->Tail.Overlay.AuxiliaryBuffer =
ExAllocatePoolWithTag(NonPagedPool, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, 'FwrI');
+ Reparse = (PREPARSE_DATA_BUFFER)Irp->Tail.Overlay.AuxiliaryBuffer;
+
+ RtlZeroMemory(Reparse, MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
+ Reparse->ReparseTag = IO_REPARSE_TAG_SYMLINK;
+ Reparse->ReparseDataLength = 12 + sizeof(L"\\??\\C:\\Documents
and Settings");
+ Reparse->SymbolicLinkReparseBuffer.SubstituteNameLength =
sizeof(L"\\??\\C:\\Documents and Settings") - sizeof(UNICODE_NULL);
+ Reparse->SymbolicLinkReparseBuffer.PrintNameOffset =
sizeof(L"\\??\\C:\\Documents and Settings");
+ RtlCopyMemory(Reparse->SymbolicLinkReparseBuffer.PathBuffer,
L"\\??\\C:\\Documents and Settings", sizeof(L"\\??\\C:\\Documents and
Settings"));
+ Irp->IoStatus.Information = IO_REPARSE_TAG_SYMLINK;
+ Status = STATUS_REPARSE;
+ }
+ }
+ else
+ {
+ Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Fcb), 'FwrI');
+ RtlZeroMemory(Fcb, sizeof(*Fcb));
+ ExInitializeFastMutex(&Fcb->HeaderMutex);
+ FsRtlSetupAdvancedHeader(&Fcb->Header, &Fcb->HeaderMutex);
+ Fcb->Header.AllocationSize.QuadPart = 0;
+ Fcb->Header.FileSize.QuadPart = 0;
+ Fcb->Header.ValidDataLength.QuadPart = 0;
+ IoStack->FileObject->FsContext = Fcb;
+ IoStack->FileObject->SectionObjectPointer =
&Fcb->SectionObjectPointers;
+
+ Irp->IoStatus.Information = FILE_OPENED;
+ Status = STATUS_SUCCESS;
+ }
+ }
+ else if (IoStack->MajorFunction == IRP_MJ_CLEANUP)
+ {
+ KeInitializeEvent(&CacheUninitEvent.Event, NotificationEvent, FALSE);
+ CcUninitializeCacheMap(IoStack->FileObject, NULL, &CacheUninitEvent);
+ KeWaitForSingleObject(&CacheUninitEvent.Event, Executive, KernelMode, FALSE,
NULL);
+ Fcb = IoStack->FileObject->FsContext;
+ ExFreePoolWithTag(Fcb, 'FwrI');
+ IoStack->FileObject->FsContext = NULL;
+ Status = STATUS_SUCCESS;
+ }
+
+ if (Status == STATUS_PENDING)
+ {
+ IoMarkIrpPending(Irp);
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ Status = STATUS_PENDING;
+ }
+ else
+ {
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ }
+
+ return Status;
+}
+
+static UNICODE_STRING FileObjectFileName =
RTL_CONSTANT_STRING(L"\\NonSymlinked");
+static UNICODE_STRING DocumentsAndSettings = RTL_CONSTANT_STRING(L"\\Documents and
Settings");
+
+static
+NTSTATUS
+TestIoCreateFile(
+ IN PUNICODE_STRING Path,
+ IN BOOLEAN NoLinks)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ HANDLE Handle;
+ NTSTATUS Status;
+ PFILE_OBJECT FileObject;
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ Path,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL);
+ Status = IoCreateFile(&Handle,
+ GENERIC_READ,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_OPEN,
+ FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_ALERT,
+ NULL,
+ 0,
+ CreateFileTypeNone,
+ NULL,
+ IO_NO_PARAMETER_CHECKING | (NoLinks ? IO_STOP_ON_SYMLINK :
0));
+ if (NT_SUCCESS(Status))
+ {
+ NTSTATUS IntStatus;
+
+ IntStatus = ObReferenceObjectByHandle(Handle,
+ FILE_READ_DATA,
+ *IoFileObjectType,
+ KernelMode,
+ (PVOID *)&FileObject,
+ NULL);
+ ok_eq_hex(IntStatus, STATUS_SUCCESS);
+ if (NT_SUCCESS(IntStatus))
+ {
+ ok(RtlCompareUnicodeString(&FileObjectFileName,
&FileObject->FileName, TRUE) == 0 ||
+ RtlCompareUnicodeString(&DocumentsAndSettings,
&FileObject->FileName, TRUE) == 0,
+ "Expected: %wZ or %wZ. Opened: %wZ\n", &FileObjectFileName,
&DocumentsAndSettings, &FileObject->FileName);
+ ObDereferenceObject(FileObject);
+ }
+ NtClose(Handle);
+ }
+
+ return Status;
+}
+
+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_CREATE_SYMLINK:
+ case IOCTL_CREATE_NO_SYMLINK:
+ {
+ ANSI_STRING Path;
+ UNICODE_STRING PathW;
+
+ ok(Buffer != NULL, "Buffer is NULL\n");
+ Path.Length = Path.MaximumLength = (USHORT)InLength;
+ Path.Buffer = Buffer;
+
+ Status = RtlAnsiStringToUnicodeString(&PathW, &Path, TRUE);
+ ok_eq_hex(Status, STATUS_SUCCESS);
+
+ Status = TestIoCreateFile(&PathW, (ControlCode ==
IOCTL_CREATE_NO_SYMLINK));
+
+ RtlFreeUnicodeString(&PathW);
+
+ break;
+ }
+ default:
+ return STATUS_NOT_SUPPORTED;
+ }
+
+ return Status;
+}
Propchange: trunk/rostests/kmtests/ntos_io/IoCreateFile_drv.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/rostests/kmtests/ntos_io/IoCreateFile_user.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_io/IoCreateF…
==============================================================================
--- trunk/rostests/kmtests/ntos_io/IoCreateFile_user.c (added)
+++ trunk/rostests/kmtests/ntos_io/IoCreateFile_user.c [iso-8859-1] Tue Sep 22 22:31:08
2015
@@ -0,0 +1,40 @@
+/*
+ * PROJECT: ReactOS kernel-mode tests
+ * LICENSE: GPLv2+ - See COPYING in the top level directory
+ * PURPOSE: Kernel-Mode Test Suite Reparse points test user-mode part
+ * PROGRAMMER: Pierre Schweitzer <pierre(a)reactos.org>
+ */
+
+#include <kmt_test.h>
+#include "IoCreateFile.h"
+
+static CHAR MountedPointFileName[] =
"\\Device\\Kmtest-IoCreateFile\\MountedPoint";
+static CHAR SymlinkedFileName[] = "\\Device\\Kmtest-IoCreateFile\\Symlinked";
+static CHAR NonSymlinkedFileName[] =
"\\Device\\Kmtest-IoCreateFile\\NonSymlinked";
+
+START_TEST(IoCreateFile)
+{
+ DWORD Error;
+
+ KmtRunKernelTest("IoCreateFile");
+
+ KmtLoadDriver(L"IoCreateFile", FALSE);
+ KmtOpenDriver();
+
+ Error = KmtSendStringToDriver(IOCTL_CREATE_SYMLINK, NonSymlinkedFileName);
+ ok(Error == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lx\n", Error);
+ Error = KmtSendStringToDriver(IOCTL_CREATE_SYMLINK, SymlinkedFileName);
+ ok(Error == ERROR_CANT_ACCESS_FILE, "Expected ERROR_CANT_ACCESS_FILE, got
%lx\n", Error); /* FIXME */
+ Error = KmtSendStringToDriver(IOCTL_CREATE_SYMLINK, MountedPointFileName);
+ ok(Error == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lx\n", Error);
+
+ Error = KmtSendStringToDriver(IOCTL_CREATE_NO_SYMLINK, NonSymlinkedFileName);
+ ok(Error == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lx\n", Error);
+ Error = KmtSendStringToDriver(IOCTL_CREATE_NO_SYMLINK, SymlinkedFileName);
+ ok(Error == ERROR_MR_MID_NOT_FOUND, "Expected ERROR_MR_MID_NOT_FOUND, got
%lx\n", Error);
+ Error = KmtSendStringToDriver(IOCTL_CREATE_NO_SYMLINK, MountedPointFileName);
+ ok(Error == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lx\n", Error);
+
+ KmtCloseDriver();
+ KmtUnloadDriver();
+}
Propchange: trunk/rostests/kmtests/ntos_io/IoCreateFile_user.c
------------------------------------------------------------------------------
svn:eol-style = native