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)
|
||||
|
|
|
@ -5,6 +5,7 @@ list(APPEND SOURCE
|
|||
Interface.c
|
||||
Lib.c
|
||||
Messaging.c
|
||||
Misc.c
|
||||
Object.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/fltmgr.def
|
||||
fltmgr.h)
|
||||
|
|
|
@ -27,7 +27,7 @@ static
|
|||
NTSTATUS
|
||||
SetupContextHeader(
|
||||
_In_ PFLT_FILTER Filter,
|
||||
_In_ PFLT_CONTEXT_REGISTRATION ContextPtr,
|
||||
_In_ PCFLT_CONTEXT_REGISTRATION ContextPtr,
|
||||
_Out_ PALLOCATE_CONTEXT_HEADER ContextHeader
|
||||
);
|
||||
|
||||
|
@ -43,9 +43,102 @@ NTSTATUS
|
|||
FltpRegisterContexts(_In_ PFLT_FILTER Filter,
|
||||
_In_ const FLT_CONTEXT_REGISTRATION *Context)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Filter);
|
||||
UNREFERENCED_PARAMETER(Context);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
PCFLT_CONTEXT_REGISTRATION ContextPtr;
|
||||
PALLOCATE_CONTEXT_HEADER ContextHeader, Prev;
|
||||
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
|
||||
NTSTATUS
|
||||
SetupContextHeader(_In_ PFLT_FILTER Filter,
|
||||
_In_ PFLT_CONTEXT_REGISTRATION ContextPtr,
|
||||
_In_ PCFLT_CONTEXT_REGISTRATION ContextPtr,
|
||||
_Out_ PALLOCATE_CONTEXT_HEADER ContextHeader)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -17,6 +17,18 @@
|
|||
|
||||
/* 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;
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
|
|
|
@ -125,7 +125,7 @@ FltCreateCommunicationPort(_In_ PFLT_FILTER Filter,
|
|||
FltObjectDereference(Filter);
|
||||
}
|
||||
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
return Status;
|
||||
}
|
||||
|
||||
_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 FltUnregisterFilter(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
|
||||
#
|
||||
add_subdirectory(example)
|
||||
add_subdirectory(fltmgr)
|
||||
add_subdirectory(hidparse)
|
||||
add_subdirectory(kernel32)
|
||||
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/sefuncs.h>
|
||||
#include <ntstrsafe.h>
|
||||
#if defined KMT_FILTER_DRIVER
|
||||
#include <fltkernel.h>
|
||||
#endif
|
||||
|
||||
#elif defined KMT_USER_MODE
|
||||
#define WIN32_NO_STATUS
|
||||
|
|
|
@ -117,6 +117,29 @@ NTSTATUS TestEntry(IN PDRIVER_OBJECT DriverObject, IN PCUNICODE_STRING RegistryP
|
|||
VOID TestUnload(IN PDRIVER_OBJECT DriverObject);
|
||||
#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
|
||||
/* Device Extension layout */
|
||||
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