mirror of
https://github.com/reactos/reactos.git
synced 2024-09-28 21:44:31 +00:00
[FLTMGR]
- Implement basic versions of FltRegisterFilter and FltUnregisterFilter - Add layout of data for FLT_FILTER, FLT_INSTANCE, FLT_OBJECT and their accociated data - Add basic rundown protection for the FLT_FILTER object - Removed from the build for now because GCC doesn't like our fltkernel.h header svn path=/trunk/; revision=71859
This commit is contained in:
parent
872139bf03
commit
02ded7fff1
|
@ -8,7 +8,7 @@ add_subdirectory(bus)
|
||||||
add_subdirectory(crypto)
|
add_subdirectory(crypto)
|
||||||
add_subdirectory(filesystems)
|
add_subdirectory(filesystems)
|
||||||
add_subdirectory(filters)
|
add_subdirectory(filters)
|
||||||
add_subdirectory(fs_minifilter)
|
#add_subdirectory(fs_minifilter)
|
||||||
add_subdirectory(hid)
|
add_subdirectory(hid)
|
||||||
add_subdirectory(input)
|
add_subdirectory(input)
|
||||||
add_subdirectory(ksfilter)
|
add_subdirectory(ksfilter)
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
|
||||||
list(APPEND SOURCE
|
list(APPEND SOURCE
|
||||||
Interface.c
|
Interface.c
|
||||||
|
Registration.c
|
||||||
|
Object.c
|
||||||
Lib.c
|
Lib.c
|
||||||
fltmgr.h)
|
fltmgr.h)
|
||||||
|
|
||||||
|
|
|
@ -370,6 +370,7 @@ FltpFastIoQueryOpen(
|
||||||
|
|
||||||
DRIVER_DATA DriverData;
|
DRIVER_DATA DriverData;
|
||||||
|
|
||||||
|
|
||||||
typedef struct _FLTMGR_DEVICE_EXTENSION
|
typedef struct _FLTMGR_DEVICE_EXTENSION
|
||||||
{
|
{
|
||||||
/* The file system we're attached to */
|
/* The file system we're attached to */
|
||||||
|
@ -425,12 +426,19 @@ FltpDispatch(_In_ PDEVICE_OBJECT DeviceObject,
|
||||||
_Inout_ PIRP Irp)
|
_Inout_ PIRP Irp)
|
||||||
{
|
{
|
||||||
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
|
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
PIO_STACK_LOCATION StackPtr;
|
||||||
|
|
||||||
DeviceExtension = DeviceObject->DeviceExtension;
|
DeviceExtension = DeviceObject->DeviceExtension;
|
||||||
__debugbreak();
|
__debugbreak();
|
||||||
FLT_ASSERT(DeviceExtension &&
|
FLT_ASSERT(DeviceExtension &&
|
||||||
DeviceExtension->AttachedToDeviceObject);
|
DeviceExtension->AttachedToDeviceObject);
|
||||||
|
|
||||||
|
StackPtr = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
if (StackPtr->MajorFunction == IRP_MJ_SHUTDOWN)
|
||||||
|
{
|
||||||
|
//FltpProcessShutdownRequest(DeviceObject);
|
||||||
|
}
|
||||||
|
|
||||||
/* Just pass the IRP down the stack */
|
/* Just pass the IRP down the stack */
|
||||||
IoSkipCurrentIrpStackLocation(Irp);
|
IoSkipCurrentIrpStackLocation(Irp);
|
||||||
return IoCallDriver(DeviceExtension->AttachedToDeviceObject, Irp);
|
return IoCallDriver(DeviceExtension->AttachedToDeviceObject, Irp);
|
||||||
|
|
|
@ -20,83 +20,6 @@
|
||||||
|
|
||||||
/* FUNCTIONS **********************************************/
|
/* FUNCTIONS **********************************************/
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
FltpGetBaseDeviceObjectName(_In_ PDEVICE_OBJECT DeviceObject,
|
|
||||||
_Inout_ PUNICODE_STRING ObjectName)
|
|
||||||
{
|
|
||||||
PDEVICE_OBJECT BaseDeviceObject;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get the lowest device object on the stack, which may be the
|
|
||||||
* object we were passed, and lookup the name for that object
|
|
||||||
*/
|
|
||||||
BaseDeviceObject = IoGetDeviceAttachmentBaseRef(DeviceObject);
|
|
||||||
Status = FltpGetObjectName(BaseDeviceObject, ObjectName);
|
|
||||||
ObDereferenceObject(BaseDeviceObject);
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
FltpGetObjectName(_In_ PVOID Object,
|
|
||||||
_Inout_ PUNICODE_STRING ObjectName)
|
|
||||||
{
|
|
||||||
POBJECT_NAME_INFORMATION ObjectNameInfo = NULL;
|
|
||||||
OBJECT_NAME_INFORMATION LocalNameInfo;
|
|
||||||
ULONG ReturnLength;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
if (ObjectName == NULL)
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
|
||||||
|
|
||||||
/* Get the size of the buffer required to hold the nameinfo */
|
|
||||||
Status = ObQueryNameString(Object,
|
|
||||||
&LocalNameInfo,
|
|
||||||
sizeof(LocalNameInfo),
|
|
||||||
&ReturnLength);
|
|
||||||
if (Status == STATUS_INFO_LENGTH_MISMATCH)
|
|
||||||
{
|
|
||||||
ObjectNameInfo = ExAllocatePoolWithTag(PagedPool,
|
|
||||||
ReturnLength,
|
|
||||||
FM_TAG_UNICODE_STRING);
|
|
||||||
if (ObjectNameInfo == NULL) return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
|
|
||||||
/* Get the actual name info now we have the buffer to hold it */
|
|
||||||
Status = ObQueryNameString(Object,
|
|
||||||
ObjectNameInfo,
|
|
||||||
ReturnLength,
|
|
||||||
&ReturnLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
/* Make sure the buffer we were passed is large enough to hold the string */
|
|
||||||
if (ObjectName->MaximumLength < ObjectNameInfo->Name.Length)
|
|
||||||
{
|
|
||||||
/* It wasn't, let's enlarge the buffer */
|
|
||||||
Status = FltpReallocateUnicodeString(ObjectName,
|
|
||||||
ObjectNameInfo->Name.Length,
|
|
||||||
FALSE);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
/* Copy the object name into the callers buffer */
|
|
||||||
RtlCopyUnicodeString(ObjectName, &ObjectNameInfo->Name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ObjectNameInfo)
|
|
||||||
{
|
|
||||||
ExFreePoolWithTag(ObjectNameInfo, FM_TAG_UNICODE_STRING);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
FltpFreeUnicodeString(_In_ PUNICODE_STRING String)
|
FltpFreeUnicodeString(_In_ PUNICODE_STRING String)
|
||||||
{
|
{
|
||||||
|
|
158
reactos/drivers/fs_minifilter/fltmgr/Object.c
Normal file
158
reactos/drivers/fs_minifilter/fltmgr/Object.c
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: Filesystem Filter Manager
|
||||||
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
|
* FILE: drivers/fs_minifilter/fltmgr/Object.c
|
||||||
|
* PURPOSE: Miscellaneous library functions
|
||||||
|
* PROGRAMMERS: Ged Murphy (gedmurphy@reactos.org)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// NOTE: Split this file into filter object and device object functions
|
||||||
|
// when the code base grows sufficiently
|
||||||
|
|
||||||
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
|
#include "fltmgr.h"
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* DATA *********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* EXPORTED FUNCTIONS ******************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
FltObjectReference(_Inout_ PFLT_OBJECT Object)
|
||||||
|
{
|
||||||
|
if (!FltpExAcquireRundownProtection(&Object->RundownRef))
|
||||||
|
{
|
||||||
|
return STATUS_FLT_DELETING_OBJECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
FltObjectDereference(_Inout_ PFLT_OBJECT Object)
|
||||||
|
{
|
||||||
|
return FltpExReleaseRundownProtection(&Object->RundownRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* INTERNAL FUNCTIONS ******************************************************/
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FltpExInitializeRundownProtection(_Out_ PEX_RUNDOWN_REF RundownRef)
|
||||||
|
{
|
||||||
|
ExInitializeRundownProtection(RundownRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
FltpExAcquireRundownProtection(_Inout_ PEX_RUNDOWN_REF RundownRef)
|
||||||
|
{
|
||||||
|
return ExAcquireRundownProtection(RundownRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
FltpExReleaseRundownProtection(_Inout_ PEX_RUNDOWN_REF RundownRef)
|
||||||
|
{
|
||||||
|
ExReleaseRundownProtection(RundownRef);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
FltpExRundownCompleted(_Inout_ PEX_RUNDOWN_REF RundownRef)
|
||||||
|
{
|
||||||
|
return _InterlockedExchange((PLONG)RundownRef, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
FltpObjectRundownWait(_Inout_ PEX_RUNDOWN_REF RundownRef)
|
||||||
|
{
|
||||||
|
//return FltpExWaitForRundownProtectionRelease(RundownRef);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
FltpGetBaseDeviceObjectName(_In_ PDEVICE_OBJECT DeviceObject,
|
||||||
|
_Inout_ PUNICODE_STRING ObjectName)
|
||||||
|
{
|
||||||
|
PDEVICE_OBJECT BaseDeviceObject;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the lowest device object on the stack, which may be the
|
||||||
|
* object we were passed, and lookup the name for that object
|
||||||
|
*/
|
||||||
|
BaseDeviceObject = IoGetDeviceAttachmentBaseRef(DeviceObject);
|
||||||
|
Status = FltpGetObjectName(BaseDeviceObject, ObjectName);
|
||||||
|
ObDereferenceObject(BaseDeviceObject);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
FltpGetObjectName(_In_ PVOID Object,
|
||||||
|
_Inout_ PUNICODE_STRING ObjectName)
|
||||||
|
{
|
||||||
|
POBJECT_NAME_INFORMATION ObjectNameInfo = NULL;
|
||||||
|
OBJECT_NAME_INFORMATION LocalNameInfo;
|
||||||
|
ULONG ReturnLength;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
if (ObjectName == NULL)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
/* Get the size of the buffer required to hold the nameinfo */
|
||||||
|
Status = ObQueryNameString(Object,
|
||||||
|
&LocalNameInfo,
|
||||||
|
sizeof(LocalNameInfo),
|
||||||
|
&ReturnLength);
|
||||||
|
if (Status == STATUS_INFO_LENGTH_MISMATCH)
|
||||||
|
{
|
||||||
|
ObjectNameInfo = ExAllocatePoolWithTag(PagedPool,
|
||||||
|
ReturnLength,
|
||||||
|
FM_TAG_UNICODE_STRING);
|
||||||
|
if (ObjectNameInfo == NULL) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
/* Get the actual name info now we have the buffer to hold it */
|
||||||
|
Status = ObQueryNameString(Object,
|
||||||
|
ObjectNameInfo,
|
||||||
|
ReturnLength,
|
||||||
|
&ReturnLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Make sure the buffer we were passed is large enough to hold the string */
|
||||||
|
if (ObjectName->MaximumLength < ObjectNameInfo->Name.Length)
|
||||||
|
{
|
||||||
|
/* It wasn't, let's enlarge the buffer */
|
||||||
|
Status = FltpReallocateUnicodeString(ObjectName,
|
||||||
|
ObjectNameInfo->Name.Length,
|
||||||
|
FALSE);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Copy the object name into the callers buffer */
|
||||||
|
RtlCopyUnicodeString(ObjectName, &ObjectNameInfo->Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ObjectNameInfo)
|
||||||
|
{
|
||||||
|
ExFreePoolWithTag(ObjectNameInfo, FM_TAG_UNICODE_STRING);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
251
reactos/drivers/fs_minifilter/fltmgr/Registration.c
Normal file
251
reactos/drivers/fs_minifilter/fltmgr/Registration.c
Normal file
|
@ -0,0 +1,251 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: Filesystem Filter Manager
|
||||||
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
|
* FILE: drivers/fs_minifilter/fltmgr/Registration.c
|
||||||
|
* PURPOSE: Handles registration of mini filters
|
||||||
|
* PROGRAMMERS: Ged Murphy (gedmurphy@reactos.org)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
|
#include "fltmgr.h"
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* DATA *********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
FltpStartingToDrainObject(
|
||||||
|
_Inout_ PFLT_OBJECT Object
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/* EXPORTED FUNCTIONS ******************************************************/
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
FltRegisterFilter(_In_ PDRIVER_OBJECT DriverObject,
|
||||||
|
_In_ const FLT_REGISTRATION *Registration,
|
||||||
|
_Out_ PFLT_FILTER *RetFilter)
|
||||||
|
{
|
||||||
|
PFLT_OPERATION_REGISTRATION Callbacks;
|
||||||
|
PFLT_FILTER Filter;
|
||||||
|
ULONG CallbackBufferSize;
|
||||||
|
ULONG FilterBufferSize;
|
||||||
|
ULONG Count = 0;
|
||||||
|
PCHAR Ptr;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
Status = 0; //remove me
|
||||||
|
|
||||||
|
/* Make sure we're targeting the correct major revision */
|
||||||
|
if ((Registration->Version & 0xFF00) != FLT_MAJOR_VERSION)
|
||||||
|
{
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure our namespace callbacks are valid */
|
||||||
|
if ((!Registration->GenerateFileNameCallback && Registration->NormalizeNameComponentCallback) ||
|
||||||
|
(!Registration->NormalizeNameComponentCallback && Registration->NormalizeContextCleanupCallback))
|
||||||
|
{
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Count the number of operations that were requested */
|
||||||
|
Callbacks = (PFLT_OPERATION_REGISTRATION)Registration->OperationRegistration;
|
||||||
|
while (Callbacks)
|
||||||
|
{
|
||||||
|
Count++;
|
||||||
|
|
||||||
|
/* Bail when we find the last one */
|
||||||
|
if (Callbacks->MajorFunction == IRP_MJ_OPERATION_END)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Move to the next item */
|
||||||
|
Callbacks++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate the buffer sizes */
|
||||||
|
CallbackBufferSize = Count * sizeof(FLT_OPERATION_REGISTRATION);
|
||||||
|
FilterBufferSize = sizeof(FLT_FILTER) + CallbackBufferSize +
|
||||||
|
DriverObject->DriverExtension->ServiceKeyName.Length;
|
||||||
|
|
||||||
|
/* Allocate a buffer to hold our filter data */
|
||||||
|
Filter = ExAllocatePoolWithTag(NonPagedPool,
|
||||||
|
FilterBufferSize,
|
||||||
|
FM_TAG_FILTER);
|
||||||
|
if (Filter == NULL) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
RtlZeroMemory(Filter, FilterBufferSize);
|
||||||
|
|
||||||
|
/* Find the end of the fixed struct */
|
||||||
|
Ptr = (PCHAR)(Filter + 1);
|
||||||
|
|
||||||
|
/* Store a copy of the driver object of this filter */
|
||||||
|
Filter->DriverObject = DriverObject;
|
||||||
|
|
||||||
|
/* Initialize the base object data */
|
||||||
|
Filter->Base.Flags = FLT_OBFL_TYPE_FILTER;
|
||||||
|
Filter->Base.PointerCount = 1;
|
||||||
|
FltpExInitializeRundownProtection(&Filter->Base.RundownRef);
|
||||||
|
FltObjectReference(&Filter->Base);
|
||||||
|
|
||||||
|
/* Set the callback addresses */
|
||||||
|
Filter->FilterUnload = Registration->FilterUnloadCallback;
|
||||||
|
Filter->InstanceSetup = Registration->InstanceSetupCallback;
|
||||||
|
Filter->InstanceQueryTeardown = Registration->InstanceQueryTeardownCallback;
|
||||||
|
Filter->InstanceTeardownStart = Registration->InstanceTeardownStartCallback;
|
||||||
|
Filter->InstanceTeardownComplete = Registration->InstanceTeardownCompleteCallback;
|
||||||
|
Filter->GenerateFileName = Registration->GenerateFileNameCallback;
|
||||||
|
Filter->NormalizeNameComponent = Registration->NormalizeNameComponentCallback;
|
||||||
|
Filter->NormalizeContextCleanup = Registration->NormalizeContextCleanupCallback;
|
||||||
|
|
||||||
|
/* Initialize the instance list */
|
||||||
|
ExInitializeResourceLite(&Filter->InstanceList.rLock);
|
||||||
|
InitializeListHead(&Filter->InstanceList.rList);
|
||||||
|
Filter->InstanceList.rCount = 0;
|
||||||
|
|
||||||
|
ExInitializeFastMutex(&Filter->ActiveOpens.mLock);
|
||||||
|
InitializeListHead(&Filter->ActiveOpens.mList);
|
||||||
|
Filter->ActiveOpens.mCount = 0;
|
||||||
|
|
||||||
|
/* Initialize the usermode port list */
|
||||||
|
ExInitializeFastMutex(&Filter->PortList.mLock);
|
||||||
|
InitializeListHead(&Filter->PortList.mList);
|
||||||
|
Filter->PortList.mCount = 0;
|
||||||
|
|
||||||
|
/* Check if the caller requested any context data */
|
||||||
|
if (Registration->ContextRegistration)
|
||||||
|
{
|
||||||
|
// register the context information
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Registration->OperationRegistration)
|
||||||
|
{
|
||||||
|
/* The callback data comes after the fixed struct */
|
||||||
|
Filter->Operations = (PFLT_OPERATION_REGISTRATION)Ptr;
|
||||||
|
Ptr += (Count * sizeof(FLT_OPERATION_REGISTRATION));
|
||||||
|
|
||||||
|
/* Tag the operation data onto the end of the filter data */
|
||||||
|
RtlCopyMemory(Filter->Operations, Registration->OperationRegistration, CallbackBufferSize);
|
||||||
|
|
||||||
|
/* walk through the requested callbacks */
|
||||||
|
for (Callbacks = Filter->Operations;
|
||||||
|
Callbacks->MajorFunction != IRP_MJ_OPERATION_END;
|
||||||
|
Callbacks++)
|
||||||
|
{
|
||||||
|
// http://fsfilters.blogspot.co.uk/2011/03/how-file-system-filters-attach-to_17.html
|
||||||
|
/* Check if this is an attach to a volume */
|
||||||
|
if (Callbacks->MajorFunction == IRP_MJ_VOLUME_MOUNT)
|
||||||
|
{
|
||||||
|
Filter->PreVolumeMount = Callbacks->PreOperation;
|
||||||
|
Filter->PostVolumeMount = Callbacks->PostOperation;
|
||||||
|
}
|
||||||
|
else if (Callbacks->MajorFunction == IRP_MJ_SHUTDOWN)
|
||||||
|
{
|
||||||
|
Callbacks->PostOperation = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the filter name buffer onto the end of the data and fill in the string */
|
||||||
|
Filter->Name.Length = 0;
|
||||||
|
Filter->Name.MaximumLength = DriverObject->DriverExtension->ServiceKeyName.Length;
|
||||||
|
Filter->Name.Buffer = (PWCH)Ptr;
|
||||||
|
RtlCopyUnicodeString(&Filter->Name, &DriverObject->DriverExtension->ServiceKeyName);
|
||||||
|
|
||||||
|
//
|
||||||
|
// - Get the altitude string
|
||||||
|
// - Slot the filter into the correct altitude location
|
||||||
|
// - More stuff??
|
||||||
|
//
|
||||||
|
|
||||||
|
//Quit:
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
// Add cleanup for context resources
|
||||||
|
|
||||||
|
ExDeleteResourceLite(&Filter->InstanceList.rLock);
|
||||||
|
ExFreePoolWithTag(Filter, FM_TAG_FILTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FLTAPI
|
||||||
|
FltUnregisterFilter(_In_ PFLT_FILTER Filter)
|
||||||
|
{
|
||||||
|
PFLT_INSTANCE Instance;
|
||||||
|
PLIST_ENTRY CurrentEntry;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* Set the draining flag */
|
||||||
|
Status = FltpStartingToDrainObject(&Filter->Base);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Someone already unregistered us, just remove our ref and bail */
|
||||||
|
FltObjectDereference(&Filter->Base);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lock the instance list */
|
||||||
|
KeEnterCriticalRegion();
|
||||||
|
ExAcquireResourceSharedLite(&Filter->InstanceList.rLock, TRUE);
|
||||||
|
|
||||||
|
/* Set the first entry in the list */
|
||||||
|
CurrentEntry = Filter->InstanceList.rList.Flink;
|
||||||
|
|
||||||
|
/* Free all instances referenced by the filter */
|
||||||
|
while (CurrentEntry != &Filter->InstanceList.rList)
|
||||||
|
{
|
||||||
|
/* Get the record pointer */
|
||||||
|
Instance = CONTAINING_RECORD(CurrentEntry, FLT_INSTANCE, FilterLink);
|
||||||
|
|
||||||
|
// FIXME: implement
|
||||||
|
|
||||||
|
/* Reset the pointer and move to next entry */
|
||||||
|
Instance = NULL;
|
||||||
|
CurrentEntry = CurrentEntry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We're done with instances now */
|
||||||
|
ExReleaseResourceLite(&Filter->InstanceList.rLock);
|
||||||
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
|
/* Remove the reference from the base object */
|
||||||
|
FltObjectDereference(&Filter->Base);
|
||||||
|
|
||||||
|
/* Wait until we're sure nothing is using the filter */
|
||||||
|
FltpObjectRundownWait(&Filter->Base.RundownRef);
|
||||||
|
|
||||||
|
/* Delete the instance list lock */
|
||||||
|
ExDeleteResourceLite(&Filter->InstanceList.rLock);
|
||||||
|
|
||||||
|
/* We're finished cleaning up now */
|
||||||
|
FltpExRundownCompleted(&Filter->Base.RundownRef);
|
||||||
|
|
||||||
|
/* Hand the memory back */
|
||||||
|
ExFreePoolWithTag(Filter, FM_TAG_FILTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* INTERNAL FUNCTIONS ******************************************************/
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
FltpStartingToDrainObject(_Inout_ PFLT_OBJECT Object)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Set the draining flag for the filter. This let's us force
|
||||||
|
* a post op callback for minifilters currently awaiting one.
|
||||||
|
*/
|
||||||
|
if (InterlockedOr((PLONG)&Object->Flags, FLT_OBFL_DRAINING) & 1)
|
||||||
|
{
|
||||||
|
/* We've been called once, we're already being deleted */
|
||||||
|
return STATUS_FLT_DELETING_OBJECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
|
@ -1,16 +1,25 @@
|
||||||
#ifndef _FLTMGR_H
|
#ifndef _FLTMGR_H
|
||||||
#define _FLTMGR_H
|
#define _FLTMGR_H
|
||||||
|
|
||||||
|
// Hack - our SDK reports NTDDI_VERSION as 0x05020100 (from _WIN32_WINNT 0x502)
|
||||||
|
// which doesn't pass the FLT_MGR_BASELINE check in fltkernel.h
|
||||||
|
#define NTDDI_VERSION NTDDI_WS03SP1
|
||||||
|
|
||||||
#include <ntifs.h>
|
#include <ntifs.h>
|
||||||
//#include <fltkernel.h>
|
#include <fltkernel.h>
|
||||||
#include <pseh/pseh2.h>
|
#include <pseh/pseh2.h>
|
||||||
|
|
||||||
#define DRIVER_NAME L"RosFltMgr"
|
#define DRIVER_NAME L"RosFltMgr"
|
||||||
|
|
||||||
|
#define FLT_MAJOR_VERSION 0x02
|
||||||
|
#define FLT_MINOR_VERSION 0x00 //win2k3
|
||||||
|
|
||||||
#define FM_TAG_DISPATCH_TABLE 'ifMF'
|
#define FM_TAG_DISPATCH_TABLE 'ifMF'
|
||||||
#define FM_TAG_REGISTRY_DATA 'rtMF'
|
#define FM_TAG_REGISTRY_DATA 'rtMF'
|
||||||
#define FM_TAG_DEV_OBJ_PTRS 'ldMF'
|
#define FM_TAG_DEV_OBJ_PTRS 'ldMF'
|
||||||
#define FM_TAG_UNICODE_STRING 'suMF'
|
#define FM_TAG_UNICODE_STRING 'suMF'
|
||||||
|
#define FM_TAG_FILTER 'lfMF'
|
||||||
|
|
||||||
|
|
||||||
typedef struct _DRIVER_DATA
|
typedef struct _DRIVER_DATA
|
||||||
{
|
{
|
||||||
|
@ -25,7 +34,160 @@ typedef struct _DRIVER_DATA
|
||||||
} DRIVER_DATA, *PDRIVER_DATA;
|
} DRIVER_DATA, *PDRIVER_DATA;
|
||||||
|
|
||||||
|
|
||||||
#define FLT_ASSERT(_e) NT_ASSERT(_e) //FIXME
|
typedef enum _FLT_OBJECT_FLAGS
|
||||||
|
{
|
||||||
|
FLT_OBFL_DRAINING = 1,
|
||||||
|
FLT_OBFL_ZOMBIED = 2,
|
||||||
|
FLT_OBFL_TYPE_INSTANCE = 0x1000000,
|
||||||
|
FLT_OBFL_TYPE_FILTER = 0x2000000,
|
||||||
|
FLT_OBFL_TYPE_VOLUME = 0x4000000
|
||||||
|
|
||||||
|
} FLT_OBJECT_FLAGS, *PFLT_OBJECT_FLAGS;
|
||||||
|
|
||||||
|
typedef enum _FLT_FILTER_FLAGS
|
||||||
|
{
|
||||||
|
FLTFL_MANDATORY_UNLOAD_IN_PROGRESS = 1,
|
||||||
|
FLTFL_FILTERING_INITIATED = 2
|
||||||
|
|
||||||
|
} FLT_FILTER_FLAGS, *PFLT_FILTER_FLAGS;
|
||||||
|
|
||||||
|
typedef struct _FLT_OBJECT // size = 0x14
|
||||||
|
{
|
||||||
|
volatile FLT_OBJECT_FLAGS Flags;
|
||||||
|
ULONG PointerCount;
|
||||||
|
EX_RUNDOWN_REF RundownRef;
|
||||||
|
LIST_ENTRY PrimaryLink;
|
||||||
|
|
||||||
|
} FLT_OBJECT, *PFLT_OBJECT;
|
||||||
|
|
||||||
|
typedef struct _FLT_RESOURCE_LIST_HEAD
|
||||||
|
{
|
||||||
|
ERESOURCE rLock;
|
||||||
|
LIST_ENTRY rList;
|
||||||
|
ULONG rCount;
|
||||||
|
|
||||||
|
} FLT_RESOURCE_LIST_HEAD, *PFLT_RESOURCE_LIST_HEAD;
|
||||||
|
|
||||||
|
typedef struct _FLT_MUTEX_LIST_HEAD
|
||||||
|
{
|
||||||
|
FAST_MUTEX mLock;
|
||||||
|
LIST_ENTRY mList;
|
||||||
|
ULONG mCount;
|
||||||
|
|
||||||
|
} FLT_MUTEX_LIST_HEAD, *PFLT_MUTEX_LIST_HEAD;
|
||||||
|
|
||||||
|
typedef struct _FLT_FILTER // size = 0x120
|
||||||
|
{
|
||||||
|
FLT_OBJECT Base;
|
||||||
|
PVOID Frame; //FLTP_FRAME
|
||||||
|
UNICODE_STRING Name;
|
||||||
|
UNICODE_STRING DefaultAltitude;
|
||||||
|
FLT_FILTER_FLAGS Flags;
|
||||||
|
PDRIVER_OBJECT DriverObject;
|
||||||
|
FLT_RESOURCE_LIST_HEAD InstanceList;
|
||||||
|
PVOID VerifierExtension;
|
||||||
|
PFLT_FILTER_UNLOAD_CALLBACK FilterUnload;
|
||||||
|
PFLT_INSTANCE_SETUP_CALLBACK InstanceSetup;
|
||||||
|
PFLT_INSTANCE_QUERY_TEARDOWN_CALLBACK InstanceQueryTeardown;
|
||||||
|
PFLT_INSTANCE_TEARDOWN_CALLBACK InstanceTeardownStart;
|
||||||
|
PFLT_INSTANCE_TEARDOWN_CALLBACK InstanceTeardownComplete;
|
||||||
|
PVOID SupportedContextsListHead; //PALLOCATE_CONTEXT_HEADER
|
||||||
|
PVOID SupportedContexts; //PALLOCATE_CONTEXT_HEADER
|
||||||
|
PVOID PreVolumeMount;
|
||||||
|
PVOID PostVolumeMount;
|
||||||
|
PFLT_GENERATE_FILE_NAME GenerateFileName;
|
||||||
|
PFLT_NORMALIZE_NAME_COMPONENT NormalizeNameComponent;
|
||||||
|
PFLT_NORMALIZE_CONTEXT_CLEANUP NormalizeContextCleanup;
|
||||||
|
PFLT_OPERATION_REGISTRATION Operations;
|
||||||
|
PFLT_FILTER_UNLOAD_CALLBACK OldDriverUnload;
|
||||||
|
FLT_MUTEX_LIST_HEAD ActiveOpens;
|
||||||
|
FLT_MUTEX_LIST_HEAD PortList;
|
||||||
|
EX_PUSH_LOCK PortLock;
|
||||||
|
|
||||||
|
} FLT_FILTER, *PFLT_FILTER;
|
||||||
|
|
||||||
|
typedef enum _FLT_INSTANCE_FLAGS
|
||||||
|
{
|
||||||
|
INSFL_CAN_BE_DETACHED = 0x01,
|
||||||
|
INSFL_DELETING = 0x02,
|
||||||
|
INSFL_INITING = 0x04
|
||||||
|
|
||||||
|
} FLT_INSTANCE_FLAGS, *PFLT_INSTANCE_FLAGS;
|
||||||
|
|
||||||
|
typedef struct _FLT_INSTANCE // size = 0x144
|
||||||
|
{
|
||||||
|
FLT_OBJECT Base;
|
||||||
|
ULONG OperationRundownRef;
|
||||||
|
PVOID Volume; //PFLT_VOLUME
|
||||||
|
PFLT_FILTER Filter;
|
||||||
|
FLT_INSTANCE_FLAGS Flags;
|
||||||
|
UNICODE_STRING Altitude;
|
||||||
|
UNICODE_STRING Name;
|
||||||
|
LIST_ENTRY FilterLink;
|
||||||
|
ERESOURCE ContextLock;
|
||||||
|
PVOID Context;
|
||||||
|
PVOID TrackCompletionNodes;
|
||||||
|
PVOID CallbackNodes;
|
||||||
|
|
||||||
|
} FLT_INSTANCE, *PFLT_INSTANCE;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FltpExInitializeRundownProtection(
|
||||||
|
_Out_ PEX_RUNDOWN_REF RundownRef
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
FltpExAcquireRundownProtection(
|
||||||
|
_Inout_ PEX_RUNDOWN_REF RundownRef
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
FltpExReleaseRundownProtection(
|
||||||
|
_Inout_ PEX_RUNDOWN_REF RundownRef
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
FltpObjectRundownWait(
|
||||||
|
_Inout_ PEX_RUNDOWN_REF RundownRef
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
FltpExRundownCompleted(
|
||||||
|
_Inout_ PEX_RUNDOWN_REF RundownRef
|
||||||
|
);
|
||||||
|
|
||||||
|
/////////// FIXME: put these into the correct header
|
||||||
|
NTSTATUS
|
||||||
|
FltpGetBaseDeviceObjectName(_In_ PDEVICE_OBJECT DeviceObject,
|
||||||
|
_Inout_ PUNICODE_STRING ObjectName);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
FltpGetObjectName(_In_ PVOID Object,
|
||||||
|
_Inout_ PUNICODE_STRING ObjectName);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
FltpReallocateUnicodeString(_In_ PUNICODE_STRING String,
|
||||||
|
_In_ SIZE_T NewLength,
|
||||||
|
_In_ BOOLEAN CopyExisting);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FltpFreeUnicodeString(_In_ PUNICODE_STRING String);
|
||||||
|
////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//FM ? ? -fltmgr.sys - Unrecognized FltMgr tag(update pooltag.w)
|
//FM ? ? -fltmgr.sys - Unrecognized FltMgr tag(update pooltag.w)
|
||||||
|
@ -243,22 +405,5 @@ FltWriteFile
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/////////// FIXME: put these into the correct header
|
|
||||||
NTSTATUS
|
|
||||||
FltpGetBaseDeviceObjectName(_In_ PDEVICE_OBJECT DeviceObject,
|
|
||||||
_Inout_ PUNICODE_STRING ObjectName);
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
FltpGetObjectName(_In_ PVOID Object,
|
|
||||||
_Inout_ PUNICODE_STRING ObjectName);
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
FltpReallocateUnicodeString(_In_ PUNICODE_STRING String,
|
|
||||||
_In_ SIZE_T NewLength,
|
|
||||||
_In_ BOOLEAN CopyExisting);
|
|
||||||
|
|
||||||
VOID
|
|
||||||
FltpFreeUnicodeString(_In_ PUNICODE_STRING String);
|
|
||||||
////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#endif /* _FLTMGR_H */
|
#endif /* _FLTMGR_H */
|
||||||
|
|
Loading…
Reference in a new issue