Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289/* * 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@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;
NTSTATUSTestEntry( _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;}
VOIDTestUnload( _In_ PDRIVER_OBJECT DriverObject){ PAGED_CODE();}
static volatile long gNoLinks = FALSE;
staticNTSTATUSTestIrpHandler( _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 && !gNoLinks) || (IoStack->Flags == SL_STOP_ON_SYMLINK && gNoLinks), "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 = ExAllocatePoolZero(NonPagedPool, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, 'FwrI'); Reparse = (PREPARSE_DATA_BUFFER)Irp->Tail.Overlay.AuxiliaryBuffer;
if (!Reparse) { Status = STATUS_INSUFFICIENT_RESOURCES; goto Finish; }
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') { PREPARSE_DATA_BUFFER Reparse;
if (IoStack->Flags & SL_STOP_ON_SYMLINK) { Status = STATUS_STOPPED_ON_SYMLINK; goto Finish; }
Irp->Tail.Overlay.AuxiliaryBuffer = ExAllocatePoolZero(NonPagedPool, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, 'FwrI'); Reparse = (PREPARSE_DATA_BUFFER)Irp->Tail.Overlay.AuxiliaryBuffer;
if (!Reparse) { Status = STATUS_INSUFFICIENT_RESOURCES; goto Finish; }
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 = ExAllocatePoolZero(NonPagedPool, sizeof(*Fcb), 'FwrI'); if (!Fcb) { Status = STATUS_INSUFFICIENT_RESOURCES; goto Finish; }
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; }
Finish: 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");
staticNTSTATUSTestIoCreateFile( IN PUNICODE_STRING Path){ 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 | (gNoLinks ? 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); }
IntStatus = ObCloseHandle(Handle, KernelMode); ok_eq_hex(IntStatus, STATUS_SUCCESS); }
return Status;}
staticNTSTATUSTestMessageHandler( 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_DISABLE_SYMLINK: { if (InterlockedExchange(&gNoLinks, TRUE) == TRUE) { Status = STATUS_UNSUCCESSFUL; }
break; } case IOCTL_CALL_CREATE: { 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);
RtlFreeUnicodeString(&PathW);
break; } default: return STATUS_NOT_SUPPORTED; }
return Status;}