mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
Start to implement fltmgr tests [WIP] (#52)
[FLTMGR] - Partially implement registering contexts - Add a misc file which contains stubs of the APIs needed in the test suite - Export some APIs needed by the test suite [KMTESTS] - Create a File System Mini-filter wrapper to host drivers for the filter manager tests - Add a test file which will be used for testing that mini-filters load correctly - Add a test file which will be used to write tests for IRP_MJ_CREATE requests
This commit is contained in:
parent
5d0a122ff6
commit
9d15fb9279
16 changed files with 1139 additions and 8 deletions
|
@ -1,2 +1,2 @@
|
||||||
#add_subdirectory(fltmgr)
|
add_subdirectory(fltmgr)
|
||||||
add_subdirectory(mountmgr)
|
add_subdirectory(mountmgr)
|
||||||
|
|
|
@ -5,6 +5,7 @@ list(APPEND SOURCE
|
||||||
Interface.c
|
Interface.c
|
||||||
Lib.c
|
Lib.c
|
||||||
Messaging.c
|
Messaging.c
|
||||||
|
Misc.c
|
||||||
Object.c
|
Object.c
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/fltmgr.def
|
${CMAKE_CURRENT_BINARY_DIR}/fltmgr.def
|
||||||
fltmgr.h)
|
fltmgr.h)
|
||||||
|
|
|
@ -27,7 +27,7 @@ static
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
SetupContextHeader(
|
SetupContextHeader(
|
||||||
_In_ PFLT_FILTER Filter,
|
_In_ PFLT_FILTER Filter,
|
||||||
_In_ PFLT_CONTEXT_REGISTRATION ContextPtr,
|
_In_ PCFLT_CONTEXT_REGISTRATION ContextPtr,
|
||||||
_Out_ PALLOCATE_CONTEXT_HEADER ContextHeader
|
_Out_ PALLOCATE_CONTEXT_HEADER ContextHeader
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -43,9 +43,102 @@ NTSTATUS
|
||||||
FltpRegisterContexts(_In_ PFLT_FILTER Filter,
|
FltpRegisterContexts(_In_ PFLT_FILTER Filter,
|
||||||
_In_ const FLT_CONTEXT_REGISTRATION *Context)
|
_In_ const FLT_CONTEXT_REGISTRATION *Context)
|
||||||
{
|
{
|
||||||
UNREFERENCED_PARAMETER(Filter);
|
PCFLT_CONTEXT_REGISTRATION ContextPtr;
|
||||||
UNREFERENCED_PARAMETER(Context);
|
PALLOCATE_CONTEXT_HEADER ContextHeader, Prev;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
PVOID Buffer;
|
||||||
|
ULONG BufferSize = 0;
|
||||||
|
USHORT i;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* Loop through all entries in the context registration array */
|
||||||
|
ContextPtr = Context;
|
||||||
|
while (ContextPtr)
|
||||||
|
{
|
||||||
|
/* Bail if we found the terminator */
|
||||||
|
if (ContextPtr->ContextType == FLT_CONTEXT_END)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Make sure we have a valid context */
|
||||||
|
if (IsContextTypeValid(ContextPtr->ContextType))
|
||||||
|
{
|
||||||
|
/* Each context is backed by a crtl struct. Reserve space for it */
|
||||||
|
BufferSize += sizeof(STREAM_LIST_CTRL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move to the next entry */
|
||||||
|
ContextPtr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bail if we found no valid registration requests */
|
||||||
|
if (BufferSize == 0)
|
||||||
|
{
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate the pool that'll hold the context crtl structs */
|
||||||
|
Buffer = ExAllocatePoolWithTag(NonPagedPool, BufferSize, FM_TAG_CONTEXT_REGISTA);
|
||||||
|
if (!Buffer) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
RtlZeroMemory(Buffer, BufferSize);
|
||||||
|
|
||||||
|
/* Setup our loop data */
|
||||||
|
ContextHeader = Buffer;
|
||||||
|
Prev = NULL;
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_CONTEXT_TYPES; i++)
|
||||||
|
{
|
||||||
|
ContextPtr = (PFLT_CONTEXT_REGISTRATION)Context;
|
||||||
|
while (ContextPtr)
|
||||||
|
{
|
||||||
|
/* We don't support variable sized contents yet */
|
||||||
|
FLT_ASSERT(ContextPtr->Size != FLT_VARIABLE_SIZED_CONTEXTS);
|
||||||
|
|
||||||
|
/* Bail if we found the terminator */
|
||||||
|
if (ContextPtr->ContextType == FLT_CONTEXT_END)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Size and pooltag are only checked when ContextAllocateCallback is null */
|
||||||
|
if (ContextPtr->ContextAllocateCallback == FALSE && ContextPtr->PoolTag == FALSE)
|
||||||
|
{
|
||||||
|
Status = STATUS_FLT_INVALID_CONTEXT_REGISTRATION;
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure we have a valid context */
|
||||||
|
if (IsContextTypeValid(ContextPtr->ContextType))
|
||||||
|
{
|
||||||
|
Status = SetupContextHeader(Filter, ContextPtr, ContextHeader);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
if (Prev)
|
||||||
|
{
|
||||||
|
Prev->Next = ContextHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
Filter->SupportedContexts[i] = ContextHeader;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Prev = ContextHeader;
|
||||||
|
|
||||||
|
/* Move to the next entry */
|
||||||
|
ContextPtr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Quit:
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
Filter->SupportedContextsListHead = Buffer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ExFreePoolWithTag(Buffer, FM_TAG_CONTEXT_REGISTA);
|
||||||
|
//FIXME: Cleanup anything that SetupContextHeader may have allocated
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,7 +165,7 @@ IsContextTypeValid(_In_ FLT_CONTEXT_TYPE ContextType)
|
||||||
static
|
static
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
SetupContextHeader(_In_ PFLT_FILTER Filter,
|
SetupContextHeader(_In_ PFLT_FILTER Filter,
|
||||||
_In_ PFLT_CONTEXT_REGISTRATION ContextPtr,
|
_In_ PCFLT_CONTEXT_REGISTRATION ContextPtr,
|
||||||
_Out_ PALLOCATE_CONTEXT_HEADER ContextHeader)
|
_Out_ PALLOCATE_CONTEXT_HEADER ContextHeader)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -17,6 +17,18 @@
|
||||||
|
|
||||||
/* DATA *********************************************************************/
|
/* DATA *********************************************************************/
|
||||||
|
|
||||||
|
#define VALID_FAST_IO_DISPATCH_HANDLER(_FastIoDispatchPtr, _FieldName) \
|
||||||
|
(((_FastIoDispatchPtr) != NULL) && \
|
||||||
|
(((_FastIoDispatchPtr)->SizeOfFastIoDispatch) >= \
|
||||||
|
(FIELD_OFFSET(FAST_IO_DISPATCH, _FieldName) + sizeof(void *))) && \
|
||||||
|
((_FastIoDispatchPtr)->_FieldName != NULL))
|
||||||
|
|
||||||
|
#define IS_MY_DEVICE_OBJECT(_devObj) \
|
||||||
|
(((_devObj) != NULL) && \
|
||||||
|
((_devObj)->DriverObject == Dispatcher::DriverObject) && \
|
||||||
|
((_devObj)->DeviceExtension != NULL))
|
||||||
|
|
||||||
|
|
||||||
DRIVER_INITIALIZE DriverEntry;
|
DRIVER_INITIALIZE DriverEntry;
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
|
|
|
@ -125,7 +125,7 @@ FltCreateCommunicationPort(_In_ PFLT_FILTER Filter,
|
||||||
FltObjectDereference(Filter);
|
FltObjectDereference(Filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
_IRQL_requires_max_(PASSIVE_LEVEL)
|
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||||
|
|
56
drivers/filters/fltmgr/Misc.c
Normal file
56
drivers/filters/fltmgr/Misc.c
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: Filesystem Filter Manager
|
||||||
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
|
* FILE: drivers/filters/fltmgr/Misc.c
|
||||||
|
* PURPOSE: Uncataloged functions
|
||||||
|
* PROGRAMMERS: Ged Murphy (gedmurphy@reactos.org)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
|
#include "fltmgr.h"
|
||||||
|
#include "fltmgrint.h"
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* DATA *********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* EXPORTED FUNCTIONS ******************************************************/
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
FLTAPI
|
||||||
|
FltBuildDefaultSecurityDescriptor(
|
||||||
|
_Outptr_ PSECURITY_DESCRIPTOR *SecurityDescriptor,
|
||||||
|
_In_ ACCESS_MASK DesiredAccess
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER(SecurityDescriptor);
|
||||||
|
UNREFERENCED_PARAMETER(DesiredAccess);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FLTAPI
|
||||||
|
FltFreeSecurityDescriptor(
|
||||||
|
_In_ PSECURITY_DESCRIPTOR SecurityDescriptor
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER(SecurityDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
FLTAPI
|
||||||
|
FltGetDiskDeviceObject(
|
||||||
|
_In_ PFLT_VOLUME Volume,
|
||||||
|
_Outptr_ PDEVICE_OBJECT *DiskDeviceObject
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER(Volume);
|
||||||
|
UNREFERENCED_PARAMETER(DiskDeviceObject);
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -2,4 +2,9 @@
|
||||||
@ stdcall FltRegisterFilter(ptr ptr ptr)
|
@ stdcall FltRegisterFilter(ptr ptr ptr)
|
||||||
@ stdcall FltUnregisterFilter(ptr)
|
@ stdcall FltUnregisterFilter(ptr)
|
||||||
@ stdcall FltCloseCommunicationPort(ptr)
|
@ stdcall FltCloseCommunicationPort(ptr)
|
||||||
|
@ stdcall FltStartFiltering(ptr)
|
||||||
|
@ stdcall FltCreateCommunicationPort(ptr ptr ptr ptr ptr ptr ptr long)
|
||||||
|
@ stdcall FltBuildDefaultSecurityDescriptor(ptr long)
|
||||||
|
@ stdcall FltFreeSecurityDescriptor(ptr)
|
||||||
|
@ stdcall FltGetDiskDeviceObject(ptr ptr)
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ include_directories(include)
|
||||||
# subdirectories containing special-purpose drivers
|
# subdirectories containing special-purpose drivers
|
||||||
#
|
#
|
||||||
add_subdirectory(example)
|
add_subdirectory(example)
|
||||||
|
add_subdirectory(fltmgr)
|
||||||
add_subdirectory(hidparse)
|
add_subdirectory(hidparse)
|
||||||
add_subdirectory(kernel32)
|
add_subdirectory(kernel32)
|
||||||
add_subdirectory(ntos_cc)
|
add_subdirectory(ntos_cc)
|
||||||
|
|
3
modules/rostests/kmtests/fltmgr/CMakeLists.txt
Normal file
3
modules/rostests/kmtests/fltmgr/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
|
||||||
|
add_subdirectory(fltmgr_load)
|
||||||
|
add_subdirectory(fltmgr_create)
|
14
modules/rostests/kmtests/fltmgr/fltmgr_create/CMakeLists.txt
Normal file
14
modules/rostests/kmtests/fltmgr/fltmgr_create/CMakeLists.txt
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
include_directories(../../include)
|
||||||
|
|
||||||
|
list(APPEND FLTMGR_TEST_DRV_SOURCE
|
||||||
|
../../kmtest_drv/kmtest_fsminifilter.c
|
||||||
|
fltmgr_create.c)
|
||||||
|
|
||||||
|
add_library(fltmgr_create SHARED ${FLTMGR_TEST_DRV_SOURCE})
|
||||||
|
set_module_type(fltmgr_create kernelmodedriver)
|
||||||
|
target_link_libraries(fltmgr_create kmtest_printf ${PSEH_LIB})
|
||||||
|
add_importlibs(fltmgr_create fltmgr ntoskrnl hal)
|
||||||
|
add_target_compile_definitions(fltmgr_create KMT_STANDALONE_DRIVER KMT_FILTER_DRIVER NTDDI_VERSION=NTDDI_WS03SP1)
|
||||||
|
#add_pch(example_drv ../include/kmt_test.h)
|
||||||
|
add_rostests_file(TARGET fltmgr_create)
|
147
modules/rostests/kmtests/fltmgr/fltmgr_create/fltmgr_create.c
Normal file
147
modules/rostests/kmtests/fltmgr/fltmgr_create/fltmgr_create.c
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS kernel-mode tests - Filter Manager
|
||||||
|
* LICENSE: GPLv2+ - See COPYING in the top level directory
|
||||||
|
* PURPOSE: Tests for checking the create operations
|
||||||
|
* PROGRAMMER: Ged Murphy <gedmurphy@reactos.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <kmt_test.h>
|
||||||
|
#include <fltkernel.h>
|
||||||
|
|
||||||
|
//#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
/* prototypes */
|
||||||
|
static
|
||||||
|
FLT_PREOP_CALLBACK_STATUS
|
||||||
|
FLTAPI
|
||||||
|
TestFilterPreOperation(
|
||||||
|
_Inout_ PFLT_CALLBACK_DATA Data,
|
||||||
|
_In_ PCFLT_RELATED_OBJECTS FltObjects,
|
||||||
|
_Outptr_result_maybenull_ PVOID *CompletionContext
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
FLT_POSTOP_CALLBACK_STATUS
|
||||||
|
FLTAPI
|
||||||
|
TestFilterPostOperation(
|
||||||
|
_Inout_ PFLT_CALLBACK_DATA Data,
|
||||||
|
_In_ PCFLT_RELATED_OBJECTS FltObjects,
|
||||||
|
_In_opt_ PVOID CompletionContext,
|
||||||
|
_In_ FLT_POST_OPERATION_FLAGS Flags
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/* Globals */
|
||||||
|
static PDRIVER_OBJECT TestDriverObject;
|
||||||
|
|
||||||
|
|
||||||
|
CONST FLT_OPERATION_REGISTRATION Callbacks[] =
|
||||||
|
{
|
||||||
|
{ IRP_MJ_CREATE,
|
||||||
|
0,
|
||||||
|
TestFilterPreOperation,
|
||||||
|
TestFilterPostOperation },
|
||||||
|
|
||||||
|
{ IRP_MJ_OPERATION_END }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
UNREFERENCED_PARAMETER(Flags);
|
||||||
|
|
||||||
|
DPRINT("Entry!\n");
|
||||||
|
|
||||||
|
ok_irql(PASSIVE_LEVEL);
|
||||||
|
TestDriverObject = DriverObject;
|
||||||
|
|
||||||
|
*DeviceName = L"fltmgr_create";
|
||||||
|
|
||||||
|
trace("Hi, this is the filter manager create test driver\n");
|
||||||
|
|
||||||
|
(VOID)KmtFilterRegisterCallbacks(Callbacks);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
TestFilterUnload(
|
||||||
|
IN ULONG Flags)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
DPRINT("Unload!\n");
|
||||||
|
|
||||||
|
ok_irql(PASSIVE_LEVEL);
|
||||||
|
|
||||||
|
trace("Unloading filter manager test driver\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
TestQueryTeardown(
|
||||||
|
_In_ PCFLT_RELATED_OBJECTS FltObjects,
|
||||||
|
_In_ FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags)
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER(FltObjects);
|
||||||
|
UNREFERENCED_PARAMETER(Flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
TestInstanceSetup(
|
||||||
|
_In_ PCFLT_RELATED_OBJECTS FltObjects,
|
||||||
|
_In_ FLT_INSTANCE_SETUP_FLAGS Flags,
|
||||||
|
_In_ DEVICE_TYPE VolumeDeviceType,
|
||||||
|
_In_ FLT_FILESYSTEM_TYPE VolumeFilesystemType,
|
||||||
|
_In_ PUNICODE_STRING VolumeName,
|
||||||
|
_In_ ULONG SectorSize,
|
||||||
|
_In_ ULONG ReportedSectorSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
trace("Received an attach request for VolumeType 0x%X, FileSystemType %d\n",
|
||||||
|
VolumeDeviceType,
|
||||||
|
VolumeFilesystemType);
|
||||||
|
|
||||||
|
return STATUS_FLT_DO_NOT_ATTACH;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
FLT_PREOP_CALLBACK_STATUS
|
||||||
|
FLTAPI
|
||||||
|
TestFilterPreOperation(
|
||||||
|
_Inout_ PFLT_CALLBACK_DATA Data,
|
||||||
|
_In_ PCFLT_RELATED_OBJECTS FltObjects,
|
||||||
|
_Outptr_result_maybenull_ PVOID *CompletionContext)
|
||||||
|
{
|
||||||
|
PFLT_IO_PARAMETER_BLOCK Iopb = Data->Iopb;
|
||||||
|
|
||||||
|
ok_eq_hex(Iopb->MajorFunction, IRP_MJ_CREATE);
|
||||||
|
|
||||||
|
return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
FLT_POSTOP_CALLBACK_STATUS
|
||||||
|
FLTAPI
|
||||||
|
TestFilterPostOperation(
|
||||||
|
_Inout_ PFLT_CALLBACK_DATA Data,
|
||||||
|
_In_ PCFLT_RELATED_OBJECTS FltObjects,
|
||||||
|
_In_opt_ PVOID CompletionContext,
|
||||||
|
_In_ FLT_POST_OPERATION_FLAGS Flags)
|
||||||
|
{
|
||||||
|
PFLT_IO_PARAMETER_BLOCK Iopb = Data->Iopb;
|
||||||
|
|
||||||
|
ok_eq_hex(Iopb->MajorFunction, IRP_MJ_CREATE);
|
||||||
|
|
||||||
|
return FLT_POSTOP_FINISHED_PROCESSING;
|
||||||
|
}
|
14
modules/rostests/kmtests/fltmgr/fltmgr_load/CMakeLists.txt
Normal file
14
modules/rostests/kmtests/fltmgr/fltmgr_load/CMakeLists.txt
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
include_directories(../../include)
|
||||||
|
|
||||||
|
list(APPEND FLTMGR_TEST_DRV_SOURCE
|
||||||
|
../../kmtest_drv/kmtest_fsminifilter.c
|
||||||
|
fltmgr_load.c)
|
||||||
|
|
||||||
|
add_library(fltmgr_load SHARED ${FLTMGR_TEST_DRV_SOURCE})
|
||||||
|
set_module_type(fltmgr_load kernelmodedriver)
|
||||||
|
target_link_libraries(fltmgr_load kmtest_printf ${PSEH_LIB})
|
||||||
|
add_importlibs(fltmgr_load fltmgr ntoskrnl hal)
|
||||||
|
add_target_compile_definitions(fltmgr_load KMT_STANDALONE_DRIVER KMT_FILTER_DRIVER NTDDI_VERSION=NTDDI_WS03SP1)
|
||||||
|
#add_pch(example_drv ../include/kmt_test.h)
|
||||||
|
add_rostests_file(TARGET fltmgr_load)
|
234
modules/rostests/kmtests/fltmgr/fltmgr_load/fltmgr_load.c
Normal file
234
modules/rostests/kmtests/fltmgr/fltmgr_load/fltmgr_load.c
Normal file
|
@ -0,0 +1,234 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS kernel-mode tests - Filter Manager
|
||||||
|
* LICENSE: GPLv2+ - See COPYING in the top level directory
|
||||||
|
* PURPOSE: Tests for checking filters load correctly
|
||||||
|
* PROGRAMMER: Ged Murphy <gedmurphy@reactos.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <kmt_test.h>
|
||||||
|
#include <fltkernel.h>
|
||||||
|
|
||||||
|
//#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
/* prototypes */
|
||||||
|
NTSTATUS
|
||||||
|
FLTAPI
|
||||||
|
TestClientConnect(
|
||||||
|
_In_ PFLT_PORT ClientPort,
|
||||||
|
_In_opt_ PVOID ServerPortCookie,
|
||||||
|
_In_reads_bytes_opt_(SizeOfContext) PVOID ConnectionContext,
|
||||||
|
_In_ ULONG SizeOfContext,
|
||||||
|
_Outptr_result_maybenull_ PVOID *ConnectionPortCookie
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FLTAPI
|
||||||
|
TestClientDisconnect(
|
||||||
|
_In_opt_ PVOID ConnectionCookie
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
FLTAPI
|
||||||
|
TestMessageHandler(
|
||||||
|
_In_opt_ PVOID ConnectionCookie,
|
||||||
|
_In_reads_bytes_opt_(InputBufferLength) PVOID InputBuffer,
|
||||||
|
_In_ ULONG InputBufferLength,
|
||||||
|
_Out_writes_bytes_to_opt_(OutputBufferLength, *ReturnOutputBufferLength) PVOID OutputBuffer,
|
||||||
|
_In_ ULONG OutputBufferLength,
|
||||||
|
_Out_ PULONG ReturnOutputBufferLength
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/* Globals */
|
||||||
|
static PDRIVER_OBJECT TestDriverObject;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name TestEntry
|
||||||
|
*
|
||||||
|
* Test entry point.
|
||||||
|
* This is called by DriverEntry as early as possible, but with ResultBuffer
|
||||||
|
* initialized, so that test macros work correctly
|
||||||
|
*
|
||||||
|
* @param DriverObject
|
||||||
|
* Driver Object.
|
||||||
|
* This is guaranteed not to have been touched by DriverEntry before
|
||||||
|
* the call to TestEntry
|
||||||
|
* @param RegistryPath
|
||||||
|
* Driver Registry Path
|
||||||
|
* This is guaranteed not to have been touched by DriverEntry before
|
||||||
|
* the call to TestEntry
|
||||||
|
* @param DeviceName
|
||||||
|
* Pointer to receive a test-specific name for the device to create
|
||||||
|
* @param Flags
|
||||||
|
* Pointer to a flags variable instructing DriverEntry how to proceed.
|
||||||
|
* See the KMT_TESTENTRY_FLAGS enumeration for possible values
|
||||||
|
* Initialized to zero on entry
|
||||||
|
*
|
||||||
|
* @return Status.
|
||||||
|
* DriverEntry will fail if this is a failure status
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
UNREFERENCED_PARAMETER(Flags);
|
||||||
|
|
||||||
|
DPRINT("Entry!\n");
|
||||||
|
|
||||||
|
ok_irql(PASSIVE_LEVEL);
|
||||||
|
TestDriverObject = DriverObject;
|
||||||
|
|
||||||
|
*DeviceName = L"fltmgr_load";
|
||||||
|
|
||||||
|
trace("Hi, this is the filter manager load test driver\n");
|
||||||
|
|
||||||
|
KmtFilterRegisterComms(TestClientConnect, TestClientDisconnect, TestMessageHandler, 1);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name TestUnload
|
||||||
|
*
|
||||||
|
* Test unload routine.
|
||||||
|
* This is called by the driver's Unload routine as early as possible, with
|
||||||
|
* ResultBuffer and the test device object still valid, so that test macros
|
||||||
|
* work correctly
|
||||||
|
*
|
||||||
|
* @param DriverObject
|
||||||
|
* Driver Object.
|
||||||
|
* This is guaranteed not to have been touched by Unload before the call
|
||||||
|
* to TestEntry
|
||||||
|
*
|
||||||
|
* @return Status
|
||||||
|
*/
|
||||||
|
VOID
|
||||||
|
TestFilterUnload(
|
||||||
|
IN ULONG Flags)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
DPRINT("Unload!\n");
|
||||||
|
|
||||||
|
ok_irql(PASSIVE_LEVEL);
|
||||||
|
|
||||||
|
trace("Unloading filter manager load test driver\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name TestInstanceSetup
|
||||||
|
*
|
||||||
|
* Test volume attach routine.
|
||||||
|
* This is called by the driver's InstanceSetupCallback routine in response to
|
||||||
|
* a new volume attaching.
|
||||||
|
*
|
||||||
|
* @param FltObjects
|
||||||
|
* Filter Object Pointers
|
||||||
|
* Pointer to an FLT_RELATED_OBJECTS structure that contains opaque pointers
|
||||||
|
* for the objects related to the current operation
|
||||||
|
* @param Flags
|
||||||
|
* Bitmask of flags that indicate why the instance is being attached
|
||||||
|
* @param VolumeDeviceType
|
||||||
|
* Device type of the file system volume
|
||||||
|
* @param VolumeFilesystemType
|
||||||
|
* File system type of the volume
|
||||||
|
* @param VolumeName
|
||||||
|
* Unicode string containing the name of the volume.
|
||||||
|
* The string is only valid within the context of this function
|
||||||
|
* @param SectorSize
|
||||||
|
* Adjusts the sector size to a minimum of 0x200, which is more reliable
|
||||||
|
* @param ReportedSectorSize
|
||||||
|
* Sector size of the volume as reported by the filter manager
|
||||||
|
*
|
||||||
|
* @return Status.
|
||||||
|
* Return STATUS_SUCCESS to attach or STATUS_FLT_DO_NOT_ATTACH to ignore
|
||||||
|
*/
|
||||||
|
NTSTATUS
|
||||||
|
TestInstanceSetup(
|
||||||
|
_In_ PCFLT_RELATED_OBJECTS FltObjects,
|
||||||
|
_In_ FLT_INSTANCE_SETUP_FLAGS Flags,
|
||||||
|
_In_ DEVICE_TYPE VolumeDeviceType,
|
||||||
|
_In_ FLT_FILESYSTEM_TYPE VolumeFilesystemType,
|
||||||
|
_In_ PUNICODE_STRING VolumeName,
|
||||||
|
_In_ ULONG SectorSize,
|
||||||
|
_In_ ULONG ReportedSectorSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
trace("Received an attach request for VolumeType 0x%X, FileSystemType %d\n",
|
||||||
|
VolumeDeviceType,
|
||||||
|
VolumeFilesystemType);
|
||||||
|
|
||||||
|
/* We're not interested in attaching to any volumes in this test */
|
||||||
|
return STATUS_FLT_DO_NOT_ATTACH;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name TestQueryTeardown
|
||||||
|
*
|
||||||
|
* Test volume attach routine.
|
||||||
|
* This is called by the driver's InstanceSetupCallback routine in response to
|
||||||
|
* a new volume attaching.
|
||||||
|
*
|
||||||
|
* @param FltObjects
|
||||||
|
* Filter Object Pointers
|
||||||
|
* Pointer to an FLT_RELATED_OBJECTS structure that contains opaque pointers
|
||||||
|
* for the objects related to the current operation
|
||||||
|
* @param Flags
|
||||||
|
* Flag that indicates why the minifilter driver instance is being torn down
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
VOID
|
||||||
|
TestQueryTeardown(
|
||||||
|
_In_ PCFLT_RELATED_OBJECTS FltObjects,
|
||||||
|
_In_ FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags)
|
||||||
|
{
|
||||||
|
trace("Received a teardown request, Flags %lu\n", Flags);
|
||||||
|
|
||||||
|
UNREFERENCED_PARAMETER(FltObjects);
|
||||||
|
UNREFERENCED_PARAMETER(Flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
FLTAPI
|
||||||
|
TestClientConnect(
|
||||||
|
_In_ PFLT_PORT ClientPort,
|
||||||
|
_In_opt_ PVOID ServerPortCookie,
|
||||||
|
_In_reads_bytes_opt_(SizeOfContext) PVOID ConnectionContext,
|
||||||
|
_In_ ULONG SizeOfContext,
|
||||||
|
_Outptr_result_maybenull_ PVOID *ConnectionPortCookie)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FLTAPI
|
||||||
|
TestClientDisconnect(
|
||||||
|
_In_opt_ PVOID ConnectionCookie)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
FLTAPI
|
||||||
|
TestMessageHandler(
|
||||||
|
_In_opt_ PVOID ConnectionCookie,
|
||||||
|
_In_reads_bytes_opt_(InputBufferLength) PVOID InputBuffer,
|
||||||
|
_In_ ULONG InputBufferLength,
|
||||||
|
_Out_writes_bytes_to_opt_(OutputBufferLength, *ReturnOutputBufferLength) PVOID OutputBuffer,
|
||||||
|
_In_ ULONG OutputBufferLength,
|
||||||
|
_Out_ PULONG ReturnOutputBufferLength)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -25,6 +25,9 @@
|
||||||
#include <ndk/obfuncs.h>
|
#include <ndk/obfuncs.h>
|
||||||
#include <ndk/sefuncs.h>
|
#include <ndk/sefuncs.h>
|
||||||
#include <ntstrsafe.h>
|
#include <ntstrsafe.h>
|
||||||
|
#if defined KMT_FILTER_DRIVER
|
||||||
|
#include <fltkernel.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#elif defined KMT_USER_MODE
|
#elif defined KMT_USER_MODE
|
||||||
#define WIN32_NO_STATUS
|
#define WIN32_NO_STATUS
|
||||||
|
|
|
@ -117,6 +117,29 @@ NTSTATUS TestEntry(IN PDRIVER_OBJECT DriverObject, IN PCUNICODE_STRING RegistryP
|
||||||
VOID TestUnload(IN PDRIVER_OBJECT DriverObject);
|
VOID TestUnload(IN PDRIVER_OBJECT DriverObject);
|
||||||
#endif /* defined KMT_STANDALONE_DRIVER */
|
#endif /* defined KMT_STANDALONE_DRIVER */
|
||||||
|
|
||||||
|
#ifdef KMT_FILTER_DRIVER
|
||||||
|
#ifndef KMT_KERNEL_MODE
|
||||||
|
#define KMT_KERNEL_MODE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NTSTATUS KmtFilterRegisterCallbacks(_In_ CONST FLT_OPERATION_REGISTRATION *OperationRegistration);
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
TESTENTRY_NO_REGISTER_FILTER = 1,
|
||||||
|
TESTENTRY_NO_CREATE_COMMS_PORT = 2,
|
||||||
|
TESTENTRY_NO_START_FILTERING = 4,
|
||||||
|
} KMT_MINIFILTER_FLAGS;
|
||||||
|
|
||||||
|
VOID TestFilterUnload(_In_ ULONG Flags);
|
||||||
|
NTSTATUS TestInstanceSetup(_In_ PCFLT_RELATED_OBJECTS FltObjects, _In_ FLT_INSTANCE_SETUP_FLAGS Flags, _In_ DEVICE_TYPE VolumeDeviceType, _In_ FLT_FILESYSTEM_TYPE VolumeFilesystemType, _In_ PUNICODE_STRING VolumeName, _In_ ULONG RealSectorSize, _In_ ULONG SectorSize);
|
||||||
|
VOID TestQueryTeardown(_In_ PCFLT_RELATED_OBJECTS FltObjects, _In_ FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags);
|
||||||
|
|
||||||
|
NTSTATUS KmtFilterRegisterComms(_In_ PFLT_CONNECT_NOTIFY ConnectNotifyCallback, _In_ PFLT_DISCONNECT_NOTIFY DisconnectNotifyCallback, _In_opt_ PFLT_MESSAGE_NOTIFY MessageNotifyCallback, _In_ LONG MaxClientConnections);
|
||||||
|
|
||||||
|
#endif/* defined KMT_FILTER_DRIVER */
|
||||||
|
|
||||||
|
|
||||||
#ifdef KMT_KERNEL_MODE
|
#ifdef KMT_KERNEL_MODE
|
||||||
/* Device Extension layout */
|
/* Device Extension layout */
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|
525
modules/rostests/kmtests/kmtest_drv/kmtest_fsminifilter.c
Normal file
525
modules/rostests/kmtests/kmtest_drv/kmtest_fsminifilter.c
Normal file
|
@ -0,0 +1,525 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS kernel-mode tests - Filter Manager
|
||||||
|
* LICENSE: GPLv2+ - See COPYING in the top level directory
|
||||||
|
* PURPOSE: FS Mini-filter wrapper to host the filter manager tests
|
||||||
|
* PROGRAMMER: Ged Murphy <ged.murphy@reactos.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ntifs.h>
|
||||||
|
#include <ndk/ketypes.h>
|
||||||
|
#include <fltkernel.h>
|
||||||
|
|
||||||
|
#define KMT_DEFINE_TEST_FUNCTIONS
|
||||||
|
#include <kmt_test.h>
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <kmt_public.h>
|
||||||
|
|
||||||
|
#define KMTEST_FILTER_POOL_TAG 'fTMK'
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _FILTER_DATA
|
||||||
|
{
|
||||||
|
PDRIVER_OBJECT DriverObject;
|
||||||
|
FLT_REGISTRATION FilterRegistration;
|
||||||
|
PFLT_FILTER Filter;
|
||||||
|
PFLT_PORT ServerPort;
|
||||||
|
|
||||||
|
} FILTER_DATA, *PFILTER_DATA;
|
||||||
|
|
||||||
|
|
||||||
|
/* Prototypes */
|
||||||
|
DRIVER_INITIALIZE DriverEntry;
|
||||||
|
|
||||||
|
/* Globals */
|
||||||
|
static PDRIVER_OBJECT TestDriverObject;
|
||||||
|
static FILTER_DATA FilterData;
|
||||||
|
static PFLT_OPERATION_REGISTRATION Callbacks = NULL;
|
||||||
|
static PFLT_CONTEXT_REGISTRATION Contexts = NULL;
|
||||||
|
|
||||||
|
static PFLT_CONNECT_NOTIFY FilterConnect = NULL;
|
||||||
|
static PFLT_DISCONNECT_NOTIFY FilterDisconnect = NULL;
|
||||||
|
static PFLT_MESSAGE_NOTIFY FilterMessage = NULL;
|
||||||
|
static LONG MaxConnections = 0;
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
FLTAPI
|
||||||
|
FilterUnload(
|
||||||
|
_In_ FLT_FILTER_UNLOAD_FLAGS Flags
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
FLTAPI
|
||||||
|
FilterInstanceSetup(
|
||||||
|
_In_ PCFLT_RELATED_OBJECTS FltObjects,
|
||||||
|
_In_ FLT_INSTANCE_SETUP_FLAGS Flags,
|
||||||
|
_In_ DEVICE_TYPE VolumeDeviceType,
|
||||||
|
_In_ FLT_FILESYSTEM_TYPE VolumeFilesystemType
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
FLTAPI
|
||||||
|
FilterQueryTeardown(
|
||||||
|
_In_ PCFLT_RELATED_OBJECTS FltObjects,
|
||||||
|
_In_ FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags
|
||||||
|
);
|
||||||
|
|
||||||
|
FLT_PREOP_CALLBACK_STATUS
|
||||||
|
FLTAPI
|
||||||
|
FilterPreOperation(
|
||||||
|
_Inout_ PFLT_CALLBACK_DATA Data,
|
||||||
|
_In_ PCFLT_RELATED_OBJECTS FltObjects,
|
||||||
|
_Outptr_result_maybenull_ PVOID *CompletionContext
|
||||||
|
);
|
||||||
|
|
||||||
|
FLT_POSTOP_CALLBACK_STATUS
|
||||||
|
FLTAPI
|
||||||
|
FilterPostOperation(
|
||||||
|
_Inout_ PFLT_CALLBACK_DATA Data,
|
||||||
|
_In_ PCFLT_RELATED_OBJECTS FltObjects,
|
||||||
|
_In_opt_ PVOID CompletionContext,
|
||||||
|
_In_ FLT_POST_OPERATION_FLAGS Flags
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
FLT_REGISTRATION FilterRegistration =
|
||||||
|
{
|
||||||
|
sizeof(FLT_REGISTRATION), // Size
|
||||||
|
FLT_REGISTRATION_VERSION, // Version
|
||||||
|
0, // Flags
|
||||||
|
NULL, // ContextRegistration
|
||||||
|
NULL, // OperationRegistration
|
||||||
|
FilterUnload, // FilterUnloadCallback
|
||||||
|
FilterInstanceSetup, // InstanceSetupCallback
|
||||||
|
FilterQueryTeardown, // InstanceQueryTeardownCallback
|
||||||
|
NULL, // InstanceTeardownStartCallback
|
||||||
|
NULL, // InstanceTeardownCompleteCallback
|
||||||
|
NULL, // AmFilterGenerateFileNameCallback
|
||||||
|
NULL, // AmFilterNormalizeNameComponentCallback
|
||||||
|
NULL, // NormalizeContextCleanupCallback
|
||||||
|
#if FLT_MGR_LONGHORN
|
||||||
|
NULL, // TransactionNotificationCallback
|
||||||
|
NULL, // AmFilterNormalizeNameComponentExCallback
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Filter Interface Routines ****************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name DriverEntry
|
||||||
|
*
|
||||||
|
* Driver entry point.
|
||||||
|
*
|
||||||
|
* @param DriverObject
|
||||||
|
* Driver Object
|
||||||
|
* @param RegistryPath
|
||||||
|
* Driver Registry Path
|
||||||
|
*
|
||||||
|
* @return Status
|
||||||
|
*/
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
DriverEntry(
|
||||||
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
|
IN PUNICODE_STRING RegistryPath)
|
||||||
|
{
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
PSECURITY_DESCRIPTOR SecurityDescriptor;
|
||||||
|
UNICODE_STRING DeviceName;
|
||||||
|
WCHAR DeviceNameBuffer[128] = L"\\Device\\Kmtest-";
|
||||||
|
PCWSTR DeviceNameSuffix;
|
||||||
|
INT Flags = 0;
|
||||||
|
PKPRCB Prcb;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
//__debugbreak();
|
||||||
|
DPRINT("DriverEntry\n");
|
||||||
|
|
||||||
|
RtlZeroMemory(&FilterData, sizeof(FILTER_DATA));
|
||||||
|
|
||||||
|
Prcb = KeGetCurrentPrcb();
|
||||||
|
KmtIsCheckedBuild = (Prcb->BuildType & PRCB_BUILD_DEBUG) != 0;
|
||||||
|
KmtIsMultiProcessorBuild = (Prcb->BuildType & PRCB_BUILD_UNIPROCESSOR) == 0;
|
||||||
|
TestDriverObject = DriverObject;
|
||||||
|
|
||||||
|
|
||||||
|
/* call TestEntry */
|
||||||
|
RtlInitUnicodeString(&DeviceName, DeviceNameBuffer);
|
||||||
|
DeviceName.MaximumLength = sizeof DeviceNameBuffer;
|
||||||
|
TestEntry(DriverObject, RegistryPath, &DeviceNameSuffix, &Flags);
|
||||||
|
|
||||||
|
RtlAppendUnicodeToString(&DeviceName, DeviceNameSuffix);
|
||||||
|
|
||||||
|
/* Register with the filter manager */
|
||||||
|
if (!(Flags & TESTENTRY_NO_REGISTER_FILTER))
|
||||||
|
{
|
||||||
|
Status = FltRegisterFilter(DriverObject,
|
||||||
|
&FilterRegistration,
|
||||||
|
&FilterData.Filter);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to register the filter driver %wZ\n", &DeviceName);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(Flags & TESTENTRY_NO_CREATE_COMMS_PORT))
|
||||||
|
{
|
||||||
|
/* Create a security descriptor */
|
||||||
|
Status = FltBuildDefaultSecurityDescriptor(&SecurityDescriptor,
|
||||||
|
FLT_PORT_ALL_ACCESS);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the security descriptor object */
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&DeviceName,
|
||||||
|
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
|
||||||
|
NULL,
|
||||||
|
SecurityDescriptor);
|
||||||
|
|
||||||
|
|
||||||
|
/* Create the usermode communication port */
|
||||||
|
Status = FltCreateCommunicationPort(FilterData.Filter,
|
||||||
|
&FilterData.ServerPort,
|
||||||
|
&ObjectAttributes,
|
||||||
|
NULL,
|
||||||
|
FilterConnect,
|
||||||
|
FilterDisconnect,
|
||||||
|
FilterMessage,
|
||||||
|
MaxConnections);
|
||||||
|
|
||||||
|
/* Free the security descriptor */
|
||||||
|
FltFreeSecurityDescriptor(SecurityDescriptor);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(Flags & TESTENTRY_NO_START_FILTERING))
|
||||||
|
{
|
||||||
|
/* Start filtering the requests */
|
||||||
|
Status = FltStartFiltering(FilterData.Filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
if (FilterData.ServerPort)
|
||||||
|
{
|
||||||
|
FltCloseCommunicationPort(FilterData.ServerPort);
|
||||||
|
}
|
||||||
|
if (FilterData.Filter)
|
||||||
|
{
|
||||||
|
FltUnregisterFilter(FilterData.Filter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name DriverUnload
|
||||||
|
*
|
||||||
|
* Driver cleanup funtion.
|
||||||
|
*
|
||||||
|
* @param Flags
|
||||||
|
* Flags describing the unload request
|
||||||
|
*/
|
||||||
|
NTSTATUS
|
||||||
|
FLTAPI
|
||||||
|
FilterUnload(
|
||||||
|
_In_ FLT_FILTER_UNLOAD_FLAGS Flags)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
UNREFERENCED_PARAMETER(Flags);
|
||||||
|
|
||||||
|
DPRINT("DriverUnload\n");
|
||||||
|
|
||||||
|
TestFilterUnload(Flags);
|
||||||
|
|
||||||
|
/* Close the port and unregister the filter */
|
||||||
|
if (FilterData.ServerPort)
|
||||||
|
{
|
||||||
|
FltCloseCommunicationPort(FilterData.ServerPort);
|
||||||
|
FilterData.ServerPort = NULL;
|
||||||
|
}
|
||||||
|
if (FilterData.Filter)
|
||||||
|
{
|
||||||
|
FltUnregisterFilter(FilterData.Filter);
|
||||||
|
FilterData.Filter = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Callbacks)
|
||||||
|
{
|
||||||
|
ExFreePoolWithTag(Callbacks, KMTEST_FILTER_POOL_TAG);
|
||||||
|
Callbacks = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name FilterInstanceSetup
|
||||||
|
*
|
||||||
|
* Volume attach routine
|
||||||
|
*
|
||||||
|
* @param FltObjects
|
||||||
|
* Filter Object Pointers
|
||||||
|
* Pointer to an FLT_RELATED_OBJECTS structure that contains opaque pointers
|
||||||
|
* for the objects related to the current operation
|
||||||
|
* @param Flags
|
||||||
|
* Bitmask of flags that indicate why the instance is being attached
|
||||||
|
* @param VolumeDeviceType
|
||||||
|
* Device type of the file system volume
|
||||||
|
* @param VolumeFilesystemType
|
||||||
|
* File system type of the volume
|
||||||
|
*
|
||||||
|
* @return Status.
|
||||||
|
* Return STATUS_SUCCESS to attach or STATUS_FLT_DO_NOT_ATTACH to ignore
|
||||||
|
*/
|
||||||
|
NTSTATUS
|
||||||
|
FLTAPI
|
||||||
|
FilterInstanceSetup(
|
||||||
|
_In_ PCFLT_RELATED_OBJECTS FltObjects,
|
||||||
|
_In_ FLT_INSTANCE_SETUP_FLAGS Flags,
|
||||||
|
_In_ DEVICE_TYPE VolumeDeviceType,
|
||||||
|
_In_ FLT_FILESYSTEM_TYPE VolumeFilesystemType)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
UCHAR VolPropBuffer[sizeof(FLT_VOLUME_PROPERTIES) + 512];
|
||||||
|
PFLT_VOLUME_PROPERTIES VolumeProperties = (PFLT_VOLUME_PROPERTIES)VolPropBuffer;
|
||||||
|
#endif
|
||||||
|
PDEVICE_OBJECT DeviceObject = NULL;
|
||||||
|
UNICODE_STRING VolumeName;
|
||||||
|
ULONG ReportedSectorSize = 0;
|
||||||
|
ULONG SectorSize = 0;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
UNREFERENCED_PARAMETER(FltObjects);
|
||||||
|
UNREFERENCED_PARAMETER(Flags);
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&VolumeName, NULL);
|
||||||
|
#if 0 // FltGetVolumeProperties is not yet implemented
|
||||||
|
/* Get the properties of this volume */
|
||||||
|
Status = FltGetVolumeProperties(Volume,
|
||||||
|
VolumeProperties,
|
||||||
|
sizeof(VolPropBuffer),
|
||||||
|
&LengthReturned);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
FLT_ASSERT((VolumeProperties->SectorSize == 0) || (VolumeProperties->SectorSize >= MIN_SECTOR_SIZE));
|
||||||
|
SectorSize = max(VolumeProperties->SectorSize, MIN_SECTOR_SIZE);
|
||||||
|
ReportedSectorSize = VolumeProperties->SectorSize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to get the volume properties : 0x%X", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* Get the storage device object we want a name for */
|
||||||
|
Status = FltGetDiskDeviceObject(FltObjects->Volume, &DeviceObject);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Get the dos device name */
|
||||||
|
Status = IoVolumeDeviceToDosName(DeviceObject, &VolumeName);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("VolumeDeviceType %lu, VolumeFilesystemType %lu, Real SectSize=0x%04x, Reported SectSize=0x%04x, Name=\"%wZ\"",
|
||||||
|
VolumeDeviceType,
|
||||||
|
VolumeFilesystemType,
|
||||||
|
SectorSize,
|
||||||
|
ReportedSectorSize,
|
||||||
|
&VolumeName);
|
||||||
|
|
||||||
|
Status = TestInstanceSetup(FltObjects,
|
||||||
|
Flags,
|
||||||
|
VolumeDeviceType,
|
||||||
|
VolumeFilesystemType,
|
||||||
|
&VolumeName,
|
||||||
|
SectorSize,
|
||||||
|
ReportedSectorSize);
|
||||||
|
|
||||||
|
/* The buffer was allocated by the IoMgr */
|
||||||
|
ExFreePool(VolumeName.Buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name FilterQueryTeardown
|
||||||
|
*
|
||||||
|
* Volume detatch routine
|
||||||
|
*
|
||||||
|
* @param FltObjects
|
||||||
|
* Filter Object Pointers
|
||||||
|
* Pointer to an FLT_RELATED_OBJECTS structure that contains opaque pointers
|
||||||
|
* for the objects related to the current operation
|
||||||
|
* @param Flags
|
||||||
|
* Flag that indicates why the minifilter driver instance is being torn down
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
NTSTATUS
|
||||||
|
FLTAPI
|
||||||
|
FilterQueryTeardown(
|
||||||
|
_In_ PCFLT_RELATED_OBJECTS FltObjects,
|
||||||
|
_In_ FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
TestQueryTeardown(FltObjects, Flags);
|
||||||
|
|
||||||
|
/* We always allow a volume to detach */
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Public Routines **************************************/
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
KmtFilterRegisterCallbacks(
|
||||||
|
_In_ CONST FLT_OPERATION_REGISTRATION *OperationRegistration)
|
||||||
|
{
|
||||||
|
ULONG Count = 0;
|
||||||
|
INT i;
|
||||||
|
|
||||||
|
if (Callbacks)
|
||||||
|
{
|
||||||
|
return STATUS_ALREADY_REGISTERED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Count how many IRPs being registered */
|
||||||
|
for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
|
||||||
|
{
|
||||||
|
if (OperationRegistration[i].MajorFunction == IRP_MJ_OPERATION_END)
|
||||||
|
break;
|
||||||
|
Count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate enough pool to hold a copy of the array */
|
||||||
|
Callbacks = ExAllocatePoolWithTag(NonPagedPool,
|
||||||
|
sizeof(FLT_OPERATION_REGISTRATION) * (Count + 1),
|
||||||
|
KMTEST_FILTER_POOL_TAG);
|
||||||
|
if (Callbacks == NULL)
|
||||||
|
{
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the array, but using the our own pre/post callbacks */
|
||||||
|
for (i = 0; i < Count; i++)
|
||||||
|
{
|
||||||
|
Callbacks[i].MajorFunction = OperationRegistration[i].MajorFunction;
|
||||||
|
Callbacks[i].Flags = OperationRegistration[i].Flags;
|
||||||
|
Callbacks[i].PreOperation = FilterPreOperation;
|
||||||
|
Callbacks[i].PostOperation = FilterPostOperation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Terminate the array */
|
||||||
|
Callbacks[Count].MajorFunction = IRP_MJ_OPERATION_END;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
KmtFilterRegisterContexts(
|
||||||
|
_In_ PFLT_CONTEXT_REGISTRATION ContextRegistration,
|
||||||
|
_In_ PVOID Callback)
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER(ContextRegistration);
|
||||||
|
UNREFERENCED_PARAMETER(Callback);
|
||||||
|
UNREFERENCED_PARAMETER(Contexts);
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
KmtFilterRegisterComms(
|
||||||
|
_In_ PFLT_CONNECT_NOTIFY ConnectNotifyCallback,
|
||||||
|
_In_ PFLT_DISCONNECT_NOTIFY DisconnectNotifyCallback,
|
||||||
|
_In_opt_ PFLT_MESSAGE_NOTIFY MessageNotifyCallback,
|
||||||
|
_In_ LONG MaxClientConnections)
|
||||||
|
{
|
||||||
|
FilterConnect = ConnectNotifyCallback;
|
||||||
|
FilterDisconnect = DisconnectNotifyCallback;
|
||||||
|
FilterMessage = MessageNotifyCallback;
|
||||||
|
MaxConnections = MaxClientConnections;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Private Routines ******************************************/
|
||||||
|
|
||||||
|
FLT_PREOP_CALLBACK_STATUS
|
||||||
|
FLTAPI
|
||||||
|
FilterPreOperation(
|
||||||
|
_Inout_ PFLT_CALLBACK_DATA Data,
|
||||||
|
_In_ PCFLT_RELATED_OBJECTS FltObjects,
|
||||||
|
_Outptr_result_maybenull_ PVOID *CompletionContext)
|
||||||
|
{
|
||||||
|
FLT_PREOP_CALLBACK_STATUS Status;
|
||||||
|
UCHAR MajorFunction;
|
||||||
|
INT i;
|
||||||
|
|
||||||
|
Status = FLT_PREOP_SUCCESS_NO_CALLBACK;
|
||||||
|
MajorFunction = Data->Iopb->MajorFunction;
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(Callbacks) / sizeof(Callbacks[0]); i++)
|
||||||
|
{
|
||||||
|
if (MajorFunction == Callbacks[i].MajorFunction)
|
||||||
|
{
|
||||||
|
// Call their pre-callback
|
||||||
|
Status = Callbacks[i].PreOperation(Data,
|
||||||
|
FltObjects,
|
||||||
|
CompletionContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
FLT_POSTOP_CALLBACK_STATUS
|
||||||
|
FLTAPI
|
||||||
|
FilterPostOperation(
|
||||||
|
_Inout_ PFLT_CALLBACK_DATA Data,
|
||||||
|
_In_ PCFLT_RELATED_OBJECTS FltObjects,
|
||||||
|
_In_opt_ PVOID CompletionContext,
|
||||||
|
_In_ FLT_POST_OPERATION_FLAGS Flags)
|
||||||
|
{
|
||||||
|
FLT_POSTOP_CALLBACK_STATUS Status;
|
||||||
|
UCHAR MajorFunction;
|
||||||
|
INT i;
|
||||||
|
|
||||||
|
Status = FLT_POSTOP_FINISHED_PROCESSING;
|
||||||
|
MajorFunction = Data->Iopb->MajorFunction;
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(Callbacks) / sizeof(Callbacks[0]); i++)
|
||||||
|
{
|
||||||
|
if (MajorFunction == Callbacks[i].MajorFunction)
|
||||||
|
{
|
||||||
|
// Call their post-callback
|
||||||
|
Status = Callbacks[i].PostOperation(Data,
|
||||||
|
FltObjects,
|
||||||
|
CompletionContext,
|
||||||
|
Flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
Loading…
Reference in a new issue