mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 17:03:02 +00:00
[FLTMGR]
- Add the beginning of the fltmgr. It's called rosfltmgr for now so I can test in Windows. - It's currently just base code which registers for file systems appearing (or disappearing), and attaches itself to them and all other mounted devices in their chain. - Although it builds (touch wood), don't add it to a running system. The IRPs aren't plugged in yet and it'll just bugcheck lower down the stack. svn path=/trunk/; revision=70409
This commit is contained in:
parent
645acc270a
commit
9b329d580d
7 changed files with 1249 additions and 0 deletions
|
@ -8,6 +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(hid)
|
add_subdirectory(hid)
|
||||||
add_subdirectory(input)
|
add_subdirectory(input)
|
||||||
add_subdirectory(ksfilter)
|
add_subdirectory(ksfilter)
|
||||||
|
|
2
reactos/drivers/fs_minifilter/CMakeLists.txt
Normal file
2
reactos/drivers/fs_minifilter/CMakeLists.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
add_subdirectory(fltmgr)
|
12
reactos/drivers/fs_minifilter/fltmgr/CMakeLists.txt
Normal file
12
reactos/drivers/fs_minifilter/fltmgr/CMakeLists.txt
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
list(APPEND SOURCE
|
||||||
|
Interface.c
|
||||||
|
Lib.c
|
||||||
|
fltmgr.h)
|
||||||
|
|
||||||
|
add_library(rosfltmgr SHARED ${SOURCE} fltmgr.rc)
|
||||||
|
set_module_type(rosfltmgr kernelmodedriver)
|
||||||
|
target_link_libraries(rosfltmgr ${PSEH_LIB})
|
||||||
|
add_importlibs(rosfltmgr ntoskrnl hal)
|
||||||
|
add_pch(rosfltmgr fltmgr.h SOURCE)
|
||||||
|
add_cd_file(TARGET rosfltmgr DESTINATION reactos/system32/drivers NO_CAB FOR all)
|
805
reactos/drivers/fs_minifilter/fltmgr/Interface.c
Normal file
805
reactos/drivers/fs_minifilter/fltmgr/Interface.c
Normal file
|
@ -0,0 +1,805 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: Filesystem Filter Manager
|
||||||
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
|
* FILE: drivers/fs_minifilter/fltmgr/interface.c
|
||||||
|
* PURPOSE: Implements the driver interface
|
||||||
|
* PROGRAMMERS: Ged Murphy (gedmurphy@reactos.org)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
|
#include "fltmgr.h"
|
||||||
|
|
||||||
|
//#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* DATA *********************************************************************/
|
||||||
|
|
||||||
|
DRIVER_INITIALIZE DriverEntry;
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
DriverEntry(
|
||||||
|
_In_ PDRIVER_OBJECT DriverObject,
|
||||||
|
_In_ PUNICODE_STRING RegistryPath
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
NTSTATUS
|
||||||
|
SetupDispatchAndCallbacksTables(
|
||||||
|
_In_ PDRIVER_OBJECT DriverObject
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
NTSTATUS
|
||||||
|
FltpAttachDeviceObject(
|
||||||
|
_In_ PDEVICE_OBJECT SourceDevice,
|
||||||
|
_In_ PDEVICE_OBJECT Targetevice,
|
||||||
|
_Out_ PDEVICE_OBJECT *AttachedToDeviceObject
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
BOOLEAN
|
||||||
|
FltpIsAttachedToDevice(
|
||||||
|
_In_ PDEVICE_OBJECT DeviceObject,
|
||||||
|
_In_opt_ PDEVICE_OBJECT *AttachedDeviceObject
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
NTSTATUS
|
||||||
|
FltpEnumerateFileSystemVolumes(
|
||||||
|
_In_ PDEVICE_OBJECT DeviceObject
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
NTSTATUS
|
||||||
|
FltpAttachToFileSystemDevice(
|
||||||
|
_In_ PDEVICE_OBJECT DeviceObject,
|
||||||
|
_In_ PUNICODE_STRING DeviceName
|
||||||
|
);
|
||||||
|
|
||||||
|
static
|
||||||
|
LONG_PTR
|
||||||
|
FltpDetachFromFileSystemDevice(
|
||||||
|
_In_ PDEVICE_OBJECT DeviceObject
|
||||||
|
);
|
||||||
|
|
||||||
|
DRIVER_FS_NOTIFICATION FltpFsNotification;
|
||||||
|
VOID
|
||||||
|
FltpFsNotification(
|
||||||
|
_In_ PDEVICE_OBJECT DeviceObject,
|
||||||
|
_In_ BOOLEAN FsActive
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef ALLOC_PRAGMA
|
||||||
|
#pragma alloc_text(INIT, DriverEntry)
|
||||||
|
#pragma alloc_text(INIT, SetupDispatchAndCallbacksTables)
|
||||||
|
#pragma alloc_text(PAGE, FltpAttachDeviceObject)
|
||||||
|
#pragma alloc_text(PAGE, FltpIsAttachedToDevice)
|
||||||
|
#pragma alloc_text(PAGE, FltpEnumerateFileSystemVolumes)
|
||||||
|
#pragma alloc_text(PAGE, FltpAttachToFileSystemDevice)
|
||||||
|
#pragma alloc_text(PAGE, FltpDetachFromFileSystemDevice)
|
||||||
|
#pragma alloc_text(PAGE, FltpFsNotification)
|
||||||
|
//#pragma alloc_text(PAGE, )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MAX_DEVNAME_LENGTH 64
|
||||||
|
|
||||||
|
DRIVER_DATA DriverData;
|
||||||
|
|
||||||
|
typedef struct _FLTMGR_DEVICE_EXTENSION
|
||||||
|
{
|
||||||
|
/* The file system we're attached to */
|
||||||
|
PDEVICE_OBJECT AttachedToDeviceObject;
|
||||||
|
|
||||||
|
// Pointer to the real (disk) device object that is associated with
|
||||||
|
// the file system device object we are attached to
|
||||||
|
/* The storage stack(disk) accociated with the file system device object we're attached to */
|
||||||
|
PDEVICE_OBJECT StorageStackDeviceObject;
|
||||||
|
|
||||||
|
/* Either physical drive for volume device objects otherwise
|
||||||
|
* it's the name of the control device we're attached to */
|
||||||
|
UNICODE_STRING DeviceName;
|
||||||
|
WCHAR DeviceNameBuffer[MAX_DEVNAME_LENGTH];
|
||||||
|
|
||||||
|
} FLTMGR_DEVICE_EXTENSION, *PFLTMGR_DEVICE_EXTENSION;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* DISPATCH ROUTINES **********************************************/
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
FltpPreFsFilterOperation(_In_ PFS_FILTER_CALLBACK_DATA Data,
|
||||||
|
_Out_ PVOID *CompletionContext)
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER(Data);
|
||||||
|
UNREFERENCED_PARAMETER(CompletionContext);
|
||||||
|
__debugbreak();
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
FltpPostFsFilterOperation(_In_ PFS_FILTER_CALLBACK_DATA Data,
|
||||||
|
_In_ NTSTATUS OperationStatus,
|
||||||
|
_In_ PVOID CompletionContext)
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER(Data);
|
||||||
|
UNREFERENCED_PARAMETER(OperationStatus);
|
||||||
|
UNREFERENCED_PARAMETER(CompletionContext);
|
||||||
|
__debugbreak();
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
FltpDispatch(_In_ PDEVICE_OBJECT DeviceObject,
|
||||||
|
_Inout_ PIRP Irp)
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER(DeviceObject);
|
||||||
|
UNREFERENCED_PARAMETER(Irp);
|
||||||
|
__debugbreak();
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
FltpCreate(_In_ PDEVICE_OBJECT DeviceObject,
|
||||||
|
_Inout_ PIRP Irp)
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER(DeviceObject);
|
||||||
|
UNREFERENCED_PARAMETER(Irp);
|
||||||
|
__debugbreak();
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
FltpFsControl(_In_ PDEVICE_OBJECT DeviceObject,
|
||||||
|
_Inout_ PIRP Irp)
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER(DeviceObject);
|
||||||
|
UNREFERENCED_PARAMETER(Irp);
|
||||||
|
__debugbreak();
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* FUNCTIONS **********************************************/
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FltpCleanupDeviceObject(_In_ PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
|
||||||
|
DeviceExtension = DeviceObject->DeviceExtension;
|
||||||
|
if (DeviceExtension)
|
||||||
|
{
|
||||||
|
// cleanup device extension
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
NTSTATUS
|
||||||
|
FltpAttachDeviceObject(_In_ PDEVICE_OBJECT SourceDevice,
|
||||||
|
_In_ PDEVICE_OBJECT TargetDevice,
|
||||||
|
_Out_ PDEVICE_OBJECT *AttachedToDeviceObject)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Before attaching, copy the flags from the device we're going to attach to */
|
||||||
|
if (FlagOn(SourceDevice->Flags, DO_BUFFERED_IO))
|
||||||
|
{
|
||||||
|
SetFlag(TargetDevice->Flags, DO_BUFFERED_IO);
|
||||||
|
}
|
||||||
|
if (FlagOn(SourceDevice->Flags, DO_DIRECT_IO))
|
||||||
|
{
|
||||||
|
SetFlag(TargetDevice->Flags, DO_DIRECT_IO);
|
||||||
|
}
|
||||||
|
if (FlagOn(SourceDevice->Flags, DO_SYSTEM_BOOT_PARTITION))
|
||||||
|
{
|
||||||
|
SetFlag(TargetDevice->Characteristics, FILE_DEVICE_SECURE_OPEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attach this device to the top of the driver stack */
|
||||||
|
Status = IoAttachDeviceToDeviceStackSafe(SourceDevice,
|
||||||
|
TargetDevice,
|
||||||
|
AttachedToDeviceObject);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
BOOLEAN
|
||||||
|
FltpIsAttachedToDevice(_In_ PDEVICE_OBJECT DeviceObject,
|
||||||
|
_In_opt_ PDEVICE_OBJECT *AttachedDeviceObject)
|
||||||
|
{
|
||||||
|
PDEVICE_OBJECT CurrentDeviceObject;
|
||||||
|
PDEVICE_OBJECT NextDeviceObject;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Initialize the return pointer */
|
||||||
|
if (AttachedDeviceObject) *AttachedDeviceObject = NULL;
|
||||||
|
|
||||||
|
/* Start by getting the top level device in the chain */
|
||||||
|
CurrentDeviceObject = IoGetAttachedDeviceReference(DeviceObject);
|
||||||
|
|
||||||
|
/* Loop while there are attached devices */
|
||||||
|
while (CurrentDeviceObject)
|
||||||
|
{
|
||||||
|
/* Check if this device driver matches ours */
|
||||||
|
if (CurrentDeviceObject->DriverObject == DriverData.DriverObject)
|
||||||
|
{
|
||||||
|
FLT_ASSERT(CurrentDeviceObject->DeviceExtension != NULL);
|
||||||
|
|
||||||
|
/* We're attached, return the device object if the caller asked for it */
|
||||||
|
if (AttachedDeviceObject)
|
||||||
|
{
|
||||||
|
*AttachedDeviceObject = CurrentDeviceObject;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We aren't returning the reference, so decrement the count */
|
||||||
|
ObDereferenceObject(CurrentDeviceObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the next device in the chain */
|
||||||
|
NextDeviceObject = IoGetLowerDeviceObject(CurrentDeviceObject);
|
||||||
|
|
||||||
|
/* Decrement the count on the last device before we update the pointer */
|
||||||
|
ObDereferenceObject(CurrentDeviceObject);
|
||||||
|
CurrentDeviceObject = NextDeviceObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
NTSTATUS
|
||||||
|
FltpEnumerateFileSystemVolumes(_In_ PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
PFLTMGR_DEVICE_EXTENSION NewDeviceExtension;
|
||||||
|
PDEVICE_OBJECT BaseDeviceObject;
|
||||||
|
PDEVICE_OBJECT NewDeviceObject;
|
||||||
|
PDEVICE_OBJECT *DeviceList;
|
||||||
|
PDEVICE_OBJECT StorageStackDeviceObject;
|
||||||
|
UNICODE_STRING DeviceName;
|
||||||
|
ULONG NumDevices;
|
||||||
|
ULONG i;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Get the base device */
|
||||||
|
BaseDeviceObject = IoGetDeviceAttachmentBaseRef(DeviceObject);
|
||||||
|
|
||||||
|
/* get the number of device object linked to the base file system */
|
||||||
|
Status = IoEnumerateDeviceObjectList(BaseDeviceObject->DriverObject,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
&NumDevices);
|
||||||
|
if (Status != STATUS_BUFFER_TOO_SMALL) return Status;
|
||||||
|
|
||||||
|
/* Add a few more slots in case the size changed between calls and allocate some memory to hold the pointers */
|
||||||
|
NumDevices += 4;
|
||||||
|
DeviceList = ExAllocatePoolWithTag(NonPagedPool,
|
||||||
|
(NumDevices * sizeof(PDEVICE_OBJECT)),
|
||||||
|
FM_TAG_DEV_OBJ_PTRS);
|
||||||
|
if (DeviceList == NULL) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
/* Now get all the device objects that this base driver has created */
|
||||||
|
Status = IoEnumerateDeviceObjectList(BaseDeviceObject->DriverObject,
|
||||||
|
DeviceList,
|
||||||
|
(NumDevices * sizeof(PDEVICE_OBJECT)),
|
||||||
|
&NumDevices);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ExFreePoolWithTag(DeviceList, FM_TAG_DEV_OBJ_PTRS);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loop through all the devices looking for ones to attach to */
|
||||||
|
for (i = 0; i < NumDevices; i++)
|
||||||
|
{
|
||||||
|
RtlInitUnicodeString(&DeviceName, NULL);
|
||||||
|
StorageStackDeviceObject = NULL;
|
||||||
|
NewDeviceObject = NULL;
|
||||||
|
|
||||||
|
/* Ignore the device we passed in, and devices of the wrong type */
|
||||||
|
if ((DeviceList[i] == BaseDeviceObject) ||
|
||||||
|
(DeviceList[i]->DeviceType != BaseDeviceObject->DeviceType))
|
||||||
|
{
|
||||||
|
goto CleanupAndNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ignore this device if we're already attached to it */
|
||||||
|
if (FltpIsAttachedToDevice(DeviceList[i], NULL) == FALSE)
|
||||||
|
{
|
||||||
|
goto CleanupAndNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the device has a name, it must be a control device.
|
||||||
|
* This handles drivers with more then one control device (like FastFat)
|
||||||
|
*/
|
||||||
|
FltpGetBaseDeviceObjectName(DeviceList[i], &DeviceName);
|
||||||
|
if (NT_SUCCESS(Status) && DeviceName.Length > 0)
|
||||||
|
{
|
||||||
|
goto CleanupAndNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Try to get the storage stack (disk) device object accociated with
|
||||||
|
* this file system device object. Ignore the device if we don't have one
|
||||||
|
*/
|
||||||
|
Status = IoGetDiskDeviceObject(DeviceList[i],
|
||||||
|
&StorageStackDeviceObject);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
goto CleanupAndNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: Don't attach to shadow copy volumes,
|
||||||
|
* ros doesn't have any so it's not an issues yet
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We're far enough to be ready to attach, create a device
|
||||||
|
* object which we'll use to do so
|
||||||
|
*/
|
||||||
|
Status = IoCreateDevice(DriverData.DriverObject,
|
||||||
|
sizeof(FLTMGR_DEVICE_EXTENSION),
|
||||||
|
NULL,
|
||||||
|
DeviceList[i]->DeviceType,
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
&NewDeviceObject);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
goto CleanupAndNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the device extension for this new object and store our disk object there */
|
||||||
|
NewDeviceExtension = NewDeviceObject->DeviceExtension;
|
||||||
|
NewDeviceExtension->StorageStackDeviceObject = StorageStackDeviceObject;
|
||||||
|
|
||||||
|
/* Lookup and store the device name for the storage stack */
|
||||||
|
RtlInitEmptyUnicodeString(&NewDeviceExtension->DeviceName,
|
||||||
|
NewDeviceExtension->DeviceNameBuffer,
|
||||||
|
sizeof(NewDeviceExtension->DeviceNameBuffer));
|
||||||
|
FltpGetObjectName(StorageStackDeviceObject,
|
||||||
|
&NewDeviceExtension->DeviceName);
|
||||||
|
|
||||||
|
|
||||||
|
/* Grab the attach lock before we attempt to attach */
|
||||||
|
ExAcquireFastMutex(&DriverData.FilterAttachLock);
|
||||||
|
|
||||||
|
/* Check again that we aren't already attached. It may have changed since our last check */
|
||||||
|
if (FltpIsAttachedToDevice(DeviceList[i], NULL) == FALSE)
|
||||||
|
{
|
||||||
|
FLT_ASSERT(NewDeviceObject->DriverObject == DriverData.DriverObject);
|
||||||
|
|
||||||
|
/* Finally, attach to the volume */
|
||||||
|
Status = FltpAttachDeviceObject(DeviceList[i],
|
||||||
|
NewDeviceObject,
|
||||||
|
&NewDeviceExtension->AttachedToDeviceObject);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Clean the initializing flag so other filters can attach to our device object */
|
||||||
|
ClearFlag(NewDeviceObject->Flags, DO_DEVICE_INITIALIZING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We're already attached. Just cleanup */
|
||||||
|
Status = STATUS_DEVICE_ALREADY_ATTACHED;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExReleaseFastMutex(&DriverData.FilterAttachLock);
|
||||||
|
|
||||||
|
CleanupAndNext:
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
if (NewDeviceObject)
|
||||||
|
{
|
||||||
|
FltpCleanupDeviceObject(NewDeviceObject);
|
||||||
|
IoDeleteDevice(NewDeviceObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StorageStackDeviceObject)
|
||||||
|
{
|
||||||
|
/* A ref was added for us when we attached, so we can deref ours now */
|
||||||
|
ObDereferenceObject(StorageStackDeviceObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove the ref which was added by IoEnumerateDeviceObjectList */
|
||||||
|
ObDereferenceObject(DeviceList[i]);
|
||||||
|
|
||||||
|
/* Free the buffer that FltpGetBaseDeviceObjectName added */
|
||||||
|
FltpFreeUnicodeString(&DeviceName);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the memory we allocated for the list */
|
||||||
|
ExFreePoolWithTag(DeviceList, FM_TAG_DEV_OBJ_PTRS);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
NTSTATUS
|
||||||
|
FltpAttachToFileSystemDevice(_In_ PDEVICE_OBJECT DeviceObject,
|
||||||
|
_In_ PUNICODE_STRING DeviceName)
|
||||||
|
{
|
||||||
|
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
PDEVICE_OBJECT NewDeviceObject;
|
||||||
|
WCHAR Buffer[MAX_DEVNAME_LENGTH];
|
||||||
|
UNICODE_STRING FileSystemDeviceName;
|
||||||
|
UNICODE_STRING FsRecDeviceName;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Only handle device types we're interested in */
|
||||||
|
if (DeviceObject->DeviceType != FILE_DEVICE_DISK_FILE_SYSTEM &&
|
||||||
|
DeviceObject->DeviceType != FILE_DEVICE_CD_ROM_FILE_SYSTEM &&
|
||||||
|
DeviceObject->DeviceType != FILE_DEVICE_NETWORK_FILE_SYSTEM)
|
||||||
|
{
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup the buffer to hold the device name */
|
||||||
|
RtlInitEmptyUnicodeString(&FileSystemDeviceName,
|
||||||
|
Buffer,
|
||||||
|
MAX_DEVNAME_LENGTH * sizeof(WCHAR));
|
||||||
|
|
||||||
|
/* Get the the name of the file system device */
|
||||||
|
Status = FltpGetObjectName(DeviceObject->DriverObject, &FileSystemDeviceName);
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
|
DPRINT("Found device %wZ, checking if we need to attach...", &FileSystemDeviceName);
|
||||||
|
|
||||||
|
/* Build up the name of the file system recognizer device */
|
||||||
|
RtlInitUnicodeString(&FsRecDeviceName, L"\\FileSystem\\Fs_Rec");
|
||||||
|
|
||||||
|
/* We don't attach to recognizer devices, so bail if this is one */
|
||||||
|
if (RtlCompareUnicodeString(&FileSystemDeviceName, &FsRecDeviceName, TRUE) == 0)
|
||||||
|
{
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a device object which we can attach to this file system */
|
||||||
|
Status = IoCreateDevice(DriverData.DriverObject,
|
||||||
|
sizeof(FLTMGR_DEVICE_EXTENSION),
|
||||||
|
NULL,
|
||||||
|
DeviceObject->DeviceType,
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
&NewDeviceObject);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to create a DO for attatching to a FS : 0x%X", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cast the device extension to something we understand */
|
||||||
|
DeviceExtension = NewDeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
/* Attach this device to the top of the driver stack and store the DO we attached to in the DE */
|
||||||
|
Status = FltpAttachDeviceObject(NewDeviceObject,
|
||||||
|
DeviceObject,
|
||||||
|
&DeviceExtension->AttachedToDeviceObject);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("Attached to %wZ", &FileSystemDeviceName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to attach to the driver stack : 0x%X", Status);
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup the unicode string buffer and copy the device name to the device extension */
|
||||||
|
RtlInitEmptyUnicodeString(&DeviceExtension->DeviceName,
|
||||||
|
DeviceExtension->DeviceNameBuffer,
|
||||||
|
MAX_DEVNAME_LENGTH * sizeof(WCHAR));
|
||||||
|
RtlCopyUnicodeString(&DeviceExtension->DeviceName, DeviceName);
|
||||||
|
|
||||||
|
/* We're done, remove the initializing flag */
|
||||||
|
ClearFlag(NewDeviceObject->Flags, DO_DEVICE_INITIALIZING);
|
||||||
|
|
||||||
|
/* Look for existing mounted devices for this file system */
|
||||||
|
Status = FltpEnumerateFileSystemVolumes(DeviceObject);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to enumerate file system volumes for this file system : 0x%X", Status);
|
||||||
|
IoDetachDevice(DeviceExtension->AttachedToDeviceObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
Cleanup:
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
IoDeleteDevice(NewDeviceObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
LONG_PTR
|
||||||
|
FltpDetachFromFileSystemDevice(_In_ PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
PDEVICE_OBJECT AttachedDevice, LowestDevice;
|
||||||
|
PFLTMGR_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
LONG_PTR Count;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Get the attached device and increment the ref count on it */
|
||||||
|
AttachedDevice = IoGetAttachedDeviceReference(DeviceObject);
|
||||||
|
|
||||||
|
/* Loop through all attached devices until we reach the bottom (file system driver) */
|
||||||
|
while (AttachedDevice->DriverObject != DriverData.DriverObject)
|
||||||
|
{
|
||||||
|
/* Get the attached device */
|
||||||
|
LowestDevice = IoGetLowerDeviceObject(AttachedDevice);
|
||||||
|
|
||||||
|
/* Remove the reference we added. If it's zero then we're already clean */
|
||||||
|
Count = ObfDereferenceObject(AttachedDevice);
|
||||||
|
if (Count == 0) return Count;
|
||||||
|
|
||||||
|
/* Try the next one */
|
||||||
|
AttachedDevice = LowestDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DeviceExtension = AttachedDevice->DeviceExtension;
|
||||||
|
if (DeviceExtension)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// FIXME: Put any device extension cleanup code here
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Detach the device from the chain and delete the object */
|
||||||
|
IoDetachDevice(DeviceObject);
|
||||||
|
IoDeleteDevice(AttachedDevice);
|
||||||
|
|
||||||
|
/* Remove the reference we added so the delete can complete */
|
||||||
|
return ObfDereferenceObject(AttachedDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
DRIVER_FS_NOTIFICATION FltpFsNotification;
|
||||||
|
VOID
|
||||||
|
FltpFsNotification(_In_ PDEVICE_OBJECT DeviceObject,
|
||||||
|
_In_ BOOLEAN FsActive)
|
||||||
|
{
|
||||||
|
UNICODE_STRING DeviceName;
|
||||||
|
NTSTATUS Status;
|
||||||
|
__debugbreak();
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Set an empty string */
|
||||||
|
RtlInitUnicodeString(&DeviceName, NULL);
|
||||||
|
|
||||||
|
/* Get the name of the lowest device object on the stack */
|
||||||
|
Status = FltpGetBaseDeviceObjectName(DeviceObject, &DeviceName);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Check if it's attaching or detaching*/
|
||||||
|
if (FsActive)
|
||||||
|
{
|
||||||
|
/* Run the attach routine */
|
||||||
|
FltpAttachToFileSystemDevice(DeviceObject, &DeviceName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Run the detatch routine */
|
||||||
|
FltpDetachFromFileSystemDevice(DeviceObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the buffer which FltpGetBaseDeviceObjectName allocated */
|
||||||
|
FltpFreeUnicodeString(&DeviceName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DRIVER_INITIALIZE DriverEntry;
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
DriverEntry(_In_ PDRIVER_OBJECT DriverObject,
|
||||||
|
_In_ PUNICODE_STRING RegistryPath)
|
||||||
|
{
|
||||||
|
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\FileSystem\\Filters\\"DRIVER_NAME);
|
||||||
|
PDEVICE_OBJECT RawDeviceObject;
|
||||||
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
PFILE_OBJECT RawFileObject;
|
||||||
|
UNICODE_STRING ObjectName;
|
||||||
|
UNICODE_STRING SymLink;
|
||||||
|
|
||||||
|
NTSTATUS Status;
|
||||||
|
__debugbreak();
|
||||||
|
RtlZeroMemory(&DriverData, sizeof(DRIVER_DATA));
|
||||||
|
DriverData.DriverObject = DriverObject;
|
||||||
|
|
||||||
|
/* Save the registry key for this driver */
|
||||||
|
DriverData.ServiceKey.Length = RegistryPath->Length;
|
||||||
|
DriverData.ServiceKey.MaximumLength = RegistryPath->MaximumLength;
|
||||||
|
DriverData.ServiceKey.Buffer = (PWCHAR)ExAllocatePoolWithTag(NonPagedPool,
|
||||||
|
RegistryPath->MaximumLength,
|
||||||
|
FM_TAG_REGISTRY_DATA);
|
||||||
|
if (!DriverData.ServiceKey.Buffer) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
RtlCopyUnicodeString(&DriverData.ServiceKey, RegistryPath);
|
||||||
|
|
||||||
|
/* Do some initialization */
|
||||||
|
ExInitializeFastMutex(&DriverData.FilterAttachLock);
|
||||||
|
|
||||||
|
/* Create the main filter manager device object */
|
||||||
|
Status = IoCreateDevice(DriverObject,
|
||||||
|
0,
|
||||||
|
&DeviceName,
|
||||||
|
FILE_DEVICE_DISK_FILE_SYSTEM,
|
||||||
|
FILE_DEVICE_SECURE_OPEN,
|
||||||
|
FALSE,
|
||||||
|
&DeviceObject);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("fltmgr IoCreateDevice failed. Status = %X", Status);
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store a global reference so we can access from callbacks */
|
||||||
|
DriverData.DeviceObject = DeviceObject;
|
||||||
|
|
||||||
|
/* Generate the symbolic link name */
|
||||||
|
RtlInitUnicodeString(&SymLink, L"\\??\\"DRIVER_NAME);
|
||||||
|
Status = IoCreateSymbolicLink(&SymLink, &DeviceName);
|
||||||
|
if (!NT_SUCCESS(Status)) goto Cleanup;
|
||||||
|
|
||||||
|
/* Create the callbacks for the dispatch table, FastIo and FS callbacks */
|
||||||
|
Status = SetupDispatchAndCallbacksTables(DriverObject);
|
||||||
|
if (!NT_SUCCESS(Status)) goto Cleanup;
|
||||||
|
|
||||||
|
//
|
||||||
|
// TODO: Create fltmgr message device
|
||||||
|
//
|
||||||
|
|
||||||
|
/* Register for notifications when a new file system is loaded. This also enumerates any existing file systems */
|
||||||
|
Status = IoRegisterFsRegistrationChange(DriverObject, FltpFsNotification);
|
||||||
|
FLT_ASSERT(Status != STATUS_DEVICE_ALREADY_ATTACHED); // Windows checks for this, but I'm not sure how that can happen??
|
||||||
|
if (!NT_SUCCESS(Status)) goto Cleanup;
|
||||||
|
|
||||||
|
/* IoRegisterFsRegistrationChange isn't notified about the raw file systems, so we attach to them manually */
|
||||||
|
RtlInitUnicodeString(&ObjectName, L"\\Device\\RawDisk");
|
||||||
|
Status = IoGetDeviceObjectPointer(&ObjectName,
|
||||||
|
FILE_READ_ATTRIBUTES,
|
||||||
|
&RawFileObject,
|
||||||
|
&RawDeviceObject);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
FltpFsNotification(RawDeviceObject, TRUE);
|
||||||
|
ObfDereferenceObject(RawFileObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&ObjectName, L"\\Device\\RawCdRom");
|
||||||
|
Status = IoGetDeviceObjectPointer(&ObjectName,
|
||||||
|
FILE_READ_ATTRIBUTES,
|
||||||
|
&RawFileObject,
|
||||||
|
&RawDeviceObject);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
FltpFsNotification(RawDeviceObject, TRUE);
|
||||||
|
ObfDereferenceObject(RawFileObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We're done, clear the initializing flag */
|
||||||
|
ClearFlag(DeviceObject->Flags, DO_DEVICE_INITIALIZING);
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
Cleanup:
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
if (DriverData.FastIoDispatch)
|
||||||
|
{
|
||||||
|
DriverObject->FastIoDispatch = NULL;
|
||||||
|
ExFreePoolWithTag(DriverData.FastIoDispatch, FM_TAG_DISPATCH_TABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
IoDeleteSymbolicLink(&SymLink);
|
||||||
|
|
||||||
|
if (DeviceObject)
|
||||||
|
IoDeleteDevice(DeviceObject);
|
||||||
|
|
||||||
|
if (DriverData.ServiceKey.Buffer)
|
||||||
|
ExFreePoolWithTag(DriverData.ServiceKey.Buffer, FM_TAG_REGISTRY_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
NTSTATUS
|
||||||
|
SetupDispatchAndCallbacksTables(_In_ PDRIVER_OBJECT DriverObject)
|
||||||
|
{
|
||||||
|
PFAST_IO_DISPATCH FastIoDispatch;
|
||||||
|
FS_FILTER_CALLBACKS Callbacks;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
/* Plug all the IRPs */
|
||||||
|
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
|
||||||
|
{
|
||||||
|
DriverObject->MajorFunction[i] = FltpDispatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Override the ones we're interested in */
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CREATE] = FltpCreate;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] = FltpCreate;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CREATE_MAILSLOT] = FltpCreate;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FltpFsControl;
|
||||||
|
|
||||||
|
/* The FastIo diapatch table is stored in the pool along with a tag */
|
||||||
|
FastIoDispatch = ExAllocatePoolWithTag(NonPagedPool, sizeof(FAST_IO_DISPATCH), FM_TAG_DISPATCH_TABLE);
|
||||||
|
if (FastIoDispatch == NULL) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
/* Fill out the FastIo table */
|
||||||
|
RtlZeroMemory(FastIoDispatch, sizeof(FAST_IO_DISPATCH));
|
||||||
|
FastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
|
||||||
|
FastIoDispatch->FastIoCheckIfPossible = (PFAST_IO_CHECK_IF_POSSIBLE)NULL;
|
||||||
|
FastIoDispatch->FastIoRead = (PFAST_IO_READ)NULL;
|
||||||
|
FastIoDispatch->FastIoWrite = (PFAST_IO_WRITE)NULL;
|
||||||
|
FastIoDispatch->FastIoQueryBasicInfo = (PFAST_IO_QUERY_BASIC_INFO)NULL;
|
||||||
|
FastIoDispatch->FastIoQueryStandardInfo = (PFAST_IO_QUERY_STANDARD_INFO)NULL;
|
||||||
|
FastIoDispatch->FastIoLock = (PFAST_IO_LOCK)NULL;
|
||||||
|
FastIoDispatch->FastIoUnlockSingle = (PFAST_IO_UNLOCK_SINGLE)NULL;
|
||||||
|
FastIoDispatch->FastIoUnlockAll = (PFAST_IO_UNLOCK_ALL)NULL;
|
||||||
|
FastIoDispatch->FastIoUnlockAllByKey = (PFAST_IO_UNLOCK_ALL_BY_KEY)NULL;
|
||||||
|
FastIoDispatch->FastIoDeviceControl = (PFAST_IO_DEVICE_CONTROL)NULL;
|
||||||
|
FastIoDispatch->FastIoDetachDevice = (PFAST_IO_DETACH_DEVICE)NULL;
|
||||||
|
FastIoDispatch->FastIoQueryNetworkOpenInfo = (PFAST_IO_QUERY_NETWORK_OPEN_INFO)NULL;
|
||||||
|
FastIoDispatch->MdlRead = (PFAST_IO_MDL_READ)NULL;
|
||||||
|
FastIoDispatch->MdlReadComplete = (PFAST_IO_MDL_READ_COMPLETE)NULL;
|
||||||
|
FastIoDispatch->PrepareMdlWrite = (PFAST_IO_PREPARE_MDL_WRITE)NULL;
|
||||||
|
FastIoDispatch->MdlWriteComplete = (PFAST_IO_MDL_WRITE_COMPLETE)NULL;
|
||||||
|
FastIoDispatch->FastIoReadCompressed = (PFAST_IO_READ_COMPRESSED)NULL;
|
||||||
|
FastIoDispatch->FastIoWriteCompressed = (PFAST_IO_WRITE_COMPRESSED)NULL;
|
||||||
|
FastIoDispatch->MdlReadCompleteCompressed = (PFAST_IO_MDL_READ_COMPLETE_COMPRESSED)NULL;
|
||||||
|
FastIoDispatch->MdlWriteCompleteCompressed = (PFAST_IO_MDL_WRITE_COMPLETE_COMPRESSED)NULL;
|
||||||
|
FastIoDispatch->FastIoQueryOpen = (PFAST_IO_QUERY_OPEN)NULL;
|
||||||
|
|
||||||
|
/* Store the FastIo table address for easy reference */
|
||||||
|
DriverData.FastIoDispatch = FastIoDispatch;
|
||||||
|
|
||||||
|
/* Initialize the callback table */
|
||||||
|
Callbacks.SizeOfFsFilterCallbacks = sizeof(FS_FILTER_CALLBACKS);
|
||||||
|
Callbacks.PreAcquireForSectionSynchronization = FltpPreFsFilterOperation;
|
||||||
|
Callbacks.PostAcquireForSectionSynchronization = FltpPostFsFilterOperation;
|
||||||
|
Callbacks.PreReleaseForSectionSynchronization = FltpPreFsFilterOperation;
|
||||||
|
Callbacks.PostReleaseForSectionSynchronization = FltpPostFsFilterOperation;
|
||||||
|
Callbacks.PreAcquireForCcFlush = FltpPreFsFilterOperation;
|
||||||
|
Callbacks.PostAcquireForCcFlush = FltpPostFsFilterOperation;
|
||||||
|
Callbacks.PreReleaseForCcFlush = FltpPreFsFilterOperation;
|
||||||
|
Callbacks.PostReleaseForCcFlush = FltpPostFsFilterOperation;
|
||||||
|
Callbacks.PreAcquireForModifiedPageWriter = FltpPreFsFilterOperation;
|
||||||
|
Callbacks.PostAcquireForModifiedPageWriter = FltpPostFsFilterOperation;
|
||||||
|
Callbacks.PreReleaseForModifiedPageWriter = FltpPreFsFilterOperation;
|
||||||
|
Callbacks.PostReleaseForModifiedPageWriter = FltpPostFsFilterOperation;
|
||||||
|
|
||||||
|
/* Register our callbacks */
|
||||||
|
return FsRtlRegisterFileSystemFilterCallbacks(DriverObject, &Callbacks);
|
||||||
|
}
|
160
reactos/drivers/fs_minifilter/fltmgr/Lib.c
Normal file
160
reactos/drivers/fs_minifilter/fltmgr/Lib.c
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: Filesystem Filter Manager
|
||||||
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
|
* FILE: drivers/fs_minifilter/fltmgr/Lib.c
|
||||||
|
* PURPOSE: Miscellaneous library functions
|
||||||
|
* PROGRAMMERS: Ged Murphy (gedmurphy@reactos.org)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
|
#include "fltmgr.h"
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* DATA *********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
FltpFreeUnicodeString(_In_ PUNICODE_STRING String)
|
||||||
|
{
|
||||||
|
/* Free up any existing buffer */
|
||||||
|
if (String->Buffer)
|
||||||
|
{
|
||||||
|
ExFreePoolWithTag(String->Buffer, FM_TAG_UNICODE_STRING);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Empty the string */
|
||||||
|
String->Buffer = NULL;
|
||||||
|
String->Length = 0;
|
||||||
|
String->MaximumLength = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
FltpReallocateUnicodeString(_In_ PUNICODE_STRING String,
|
||||||
|
_In_ SIZE_T NewLength,
|
||||||
|
_In_ BOOLEAN CopyExisting)
|
||||||
|
{
|
||||||
|
PWCH NewBuffer;
|
||||||
|
|
||||||
|
/* Don't bother reallocating if the buffer is smaller */
|
||||||
|
if (NewLength <= String->MaximumLength)
|
||||||
|
{
|
||||||
|
String->Length = 0;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate a new buffer at the size requested */
|
||||||
|
NewBuffer = ExAllocatePoolWithTag(PagedPool, NewLength, FM_TAG_UNICODE_STRING);
|
||||||
|
if (NewBuffer == NULL) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
if (CopyExisting)
|
||||||
|
{
|
||||||
|
/* Copy the old data across */
|
||||||
|
RtlCopyMemory(NewBuffer, String->Buffer, String->Length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Reset the length */
|
||||||
|
String->Length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free any old buffer */
|
||||||
|
if (String->Buffer)
|
||||||
|
ExFreePoolWithTag(String->Buffer, FM_TAG_UNICODE_STRING);
|
||||||
|
|
||||||
|
/* Update the lengths */
|
||||||
|
String->Buffer = NewBuffer;
|
||||||
|
String->MaximumLength = NewLength;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
FltpCopyUnicodeString(_In_ PUNICODE_STRING StringOne,
|
||||||
|
_In_ PUNICODE_STRING StringTwo)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
264
reactos/drivers/fs_minifilter/fltmgr/fltmgr.h
Normal file
264
reactos/drivers/fs_minifilter/fltmgr/fltmgr.h
Normal file
|
@ -0,0 +1,264 @@
|
||||||
|
#ifndef _FLTMGR_H
|
||||||
|
#define _FLTMGR_H
|
||||||
|
|
||||||
|
#include <ntifs.h>
|
||||||
|
//#include <fltkernel.h>
|
||||||
|
#include <pseh/pseh2.h>
|
||||||
|
|
||||||
|
#define DRIVER_NAME L"RosFltMgr"
|
||||||
|
|
||||||
|
#define FM_TAG_DISPATCH_TABLE 'ifMF'
|
||||||
|
#define FM_TAG_REGISTRY_DATA 'rtMF'
|
||||||
|
#define FM_TAG_DEV_OBJ_PTRS 'ldMF'
|
||||||
|
#define FM_TAG_UNICODE_STRING 'suMF'
|
||||||
|
|
||||||
|
typedef struct _DRIVER_DATA
|
||||||
|
{
|
||||||
|
PDRIVER_OBJECT DriverObject;
|
||||||
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
UNICODE_STRING ServiceKey;
|
||||||
|
|
||||||
|
PFAST_IO_DISPATCH FastIoDispatch;
|
||||||
|
|
||||||
|
FAST_MUTEX FilterAttachLock;
|
||||||
|
|
||||||
|
} DRIVER_DATA, *PDRIVER_DATA;
|
||||||
|
|
||||||
|
|
||||||
|
#define FLT_ASSERT(_e) NT_ASSERT(_e) //FIXME
|
||||||
|
|
||||||
|
|
||||||
|
//FM ? ? -fltmgr.sys - Unrecognized FltMgr tag(update pooltag.w)
|
||||||
|
//FMac - fltmgr.sys - ASCII String buffers
|
||||||
|
//FMas - fltmgr.sys - ASYNC_IO_COMPLETION_CONTEXT structure
|
||||||
|
//FMcb - fltmgr.sys - FLT_CCB structure
|
||||||
|
//FMcr - fltmgr.sys - Context registration structures
|
||||||
|
//FMct - fltmgr.sys - TRACK_COMPLETION_NODES structure
|
||||||
|
//FMdl - fltmgr.sys - Array of DEVICE_OBJECT pointers
|
||||||
|
//FMea - fltmgr.sys - EA buffer for create
|
||||||
|
//FMfc - fltmgr.sys - FLTMGR_FILE_OBJECT_CONTEXT structure
|
||||||
|
//FMfi - fltmgr.sys - Fast IO dispatch table
|
||||||
|
//FMfk - fltmgr.sys - Byte Range Lock structure
|
||||||
|
//FMfl - fltmgr.sys - FLT_FILTER structure
|
||||||
|
//FMfn - fltmgr.sys - NAME_CACHE_NODE structure
|
||||||
|
//FMfr - fltmgr.sys - FLT_FRAME structure
|
||||||
|
//FMfz - fltmgr.sys - FILE_LIST_CTRL structure
|
||||||
|
//FMib - fltmgr.sys - Irp SYSTEM buffers
|
||||||
|
//FMic - fltmgr.sys - IRP_CTRL structure
|
||||||
|
//FMin - fltmgr.sys - FLT_INSTANCE name
|
||||||
|
//FMil - fltmgr.sys - IRP_CTRL completion node stack
|
||||||
|
//FMis - fltmgr.sys - FLT_INSTANCE structure
|
||||||
|
//FMla - fltmgr.sys - Per - processor IRPCTRL lookaside lists
|
||||||
|
//FMnc - fltmgr.sys - NAME_CACHE_CREATE_CTRL structure
|
||||||
|
//FMng - fltmgr.sys - NAME_GENERATION_CONTEXT structure
|
||||||
|
//FMol - fltmgr.sys - OPLOCK_CONTEXT structure
|
||||||
|
//FMos - fltmgr.sys - Operation status ctrl structure
|
||||||
|
//FMpl - fltmgr.sys - Cache aware pushLock
|
||||||
|
//FMpr - fltmgr.sys - FLT_PRCB structure
|
||||||
|
//FMrl - fltmgr.sys - FLT_OBJECT rundown logs
|
||||||
|
//FMrp - fltmgr.sys - Reparse point data buffer
|
||||||
|
//FMrr - fltmgr.sys - Per - processor Cache - aware rundown ref structure
|
||||||
|
//FMsd - fltmgr.sys - Security descriptors
|
||||||
|
//FMsl - fltmgr.sys - STREAM_LIST_CTRL structure
|
||||||
|
//FMtn - fltmgr.sys - Temporary file names
|
||||||
|
//FMtr - fltmgr.sys - Temporary Registry information
|
||||||
|
//FMts - fltmgr.sys - Tree Stack
|
||||||
|
//FMus - fltmgr.sys - Unicode string
|
||||||
|
//FMvf - fltmgr.sys - FLT_VERIFIER_EXTENSION structure
|
||||||
|
//FMvj - fltmgr.sys - FLT_VERIFIER_OBJECT structure
|
||||||
|
//FMvo - fltmgr.sys - FLT_VOLUME structure
|
||||||
|
//FMwi - fltmgr.sys - Work item structures
|
||||||
|
//FMcn - fltmgr.sys - Non paged context extension structures.
|
||||||
|
//FMtp - fltmgr.sys - Non Paged tx vol context structures.
|
||||||
|
//FMlp - fltmgr.sys - Paged stream list control entry structures.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
FltAcquirePushLockExclusive
|
||||||
|
FltAcquirePushLockShared
|
||||||
|
FltAcquireResourceExclusive
|
||||||
|
FltAcquireResourceShared
|
||||||
|
FltAllocateCallbackData
|
||||||
|
FltAllocateContext
|
||||||
|
FltAllocateDeferredIoWorkItem
|
||||||
|
FltAllocateFileLock
|
||||||
|
FltAllocateGenericWorkItem
|
||||||
|
FltAllocatePoolAlignedWithTag
|
||||||
|
FltAttachVolume
|
||||||
|
FltAttachVolumeAtAltitude
|
||||||
|
FltBuildDefaultSecurityDescriptor
|
||||||
|
FltCancelFileOpen
|
||||||
|
FltCancelIo
|
||||||
|
FltCbdqDisable
|
||||||
|
FltCbdqEnable
|
||||||
|
FltCbdqInitialize
|
||||||
|
FltCbdqInsertIo
|
||||||
|
FltCbdqRemoveIo
|
||||||
|
FltCbdqRemoveNextIo
|
||||||
|
FltCheckAndGrowNameControl
|
||||||
|
FltCheckLockForReadAccess
|
||||||
|
FltCheckLockForWriteAccess
|
||||||
|
FltCheckOplock
|
||||||
|
FltClearCallbackDataDirty
|
||||||
|
FltClearCancelCompletion
|
||||||
|
FltClose
|
||||||
|
FltCloseClientPort
|
||||||
|
FltCloseCommunicationPort
|
||||||
|
FltCompareInstanceAltitudes
|
||||||
|
FltCompletePendedPostOperation
|
||||||
|
FltCompletePendedPreOperation
|
||||||
|
FltCreateCommunicationPort
|
||||||
|
FltCreateFile
|
||||||
|
FltCreateFileEx
|
||||||
|
FltCreateSystemVolumeInformationFolder
|
||||||
|
FltCurrentBatchOplock
|
||||||
|
FltDecodeParameters
|
||||||
|
FltDeleteContext
|
||||||
|
FltDeleteFileContext
|
||||||
|
FltDeleteInstanceContext
|
||||||
|
FltDeletePushLock
|
||||||
|
FltDeleteStreamContext
|
||||||
|
FltDeleteStreamHandleContext
|
||||||
|
FltDeleteVolumeContext
|
||||||
|
FltDetachVolume
|
||||||
|
FltDeviceIoControlFile
|
||||||
|
FltDoCompletionProcessingWhenSafe
|
||||||
|
FltEnumerateFilterInformation
|
||||||
|
FltEnumerateFilters
|
||||||
|
FltEnumerateInstanceInformationByFilter
|
||||||
|
FltEnumerateInstanceInformationByVolume
|
||||||
|
FltEnumerateInstances
|
||||||
|
FltEnumerateVolumeInformation
|
||||||
|
FltEnumerateVolumes
|
||||||
|
FltFlushBuffers
|
||||||
|
FltFreeCallbackData
|
||||||
|
FltFreeDeferredIoWorkItem
|
||||||
|
FltFreeFileLock
|
||||||
|
FltFreeGenericWorkItem
|
||||||
|
FltFreePoolAlignedWithTag
|
||||||
|
FltFreeSecurityDescriptor
|
||||||
|
FltFsControlFile
|
||||||
|
FltGetBottomInstance
|
||||||
|
FltGetContexts
|
||||||
|
FltGetDestinationFileNameInformation
|
||||||
|
FltGetDeviceObject
|
||||||
|
FltGetDiskDeviceObject
|
||||||
|
FltGetFileContext
|
||||||
|
FltGetFileNameInformation
|
||||||
|
FltGetFileNameInformationUnsafe
|
||||||
|
FltGetFilterFromInstance
|
||||||
|
FltGetFilterFromName
|
||||||
|
FltGetFilterInformation
|
||||||
|
FltGetInstanceContext
|
||||||
|
FltGetInstanceInformation
|
||||||
|
FltGetIrpName
|
||||||
|
FltGetLowerInstance
|
||||||
|
FltGetRequestorProcess
|
||||||
|
FltGetRequestorProcessId
|
||||||
|
FltGetRoutineAddress
|
||||||
|
FltGetStreamContext
|
||||||
|
FltGetStreamHandleContext
|
||||||
|
FltGetSwappedBufferMdlAddress
|
||||||
|
FltGetTopInstance
|
||||||
|
FltGetTunneledName
|
||||||
|
FltGetUpperInstance
|
||||||
|
FltGetVolumeContext
|
||||||
|
FltGetVolumeFromDeviceObject
|
||||||
|
FltGetVolumeFromFileObject
|
||||||
|
FltGetVolumeFromInstance
|
||||||
|
FltGetVolumeFromName
|
||||||
|
FltGetVolumeGuidName
|
||||||
|
FltGetVolumeInstanceFromName
|
||||||
|
FltGetVolumeName
|
||||||
|
FltGetVolumeProperties
|
||||||
|
FltInitializeFileLock
|
||||||
|
FltInitializeOplock
|
||||||
|
FltInitializePushLock
|
||||||
|
FltIs32bitProcess
|
||||||
|
FltIsCallbackDataDirty
|
||||||
|
FltIsDirectory
|
||||||
|
FltIsIoCanceled
|
||||||
|
FltIsOperationSynchronous
|
||||||
|
FltIsVolumeWritable
|
||||||
|
FltLoadFilter
|
||||||
|
FltLockUserBuffer
|
||||||
|
FltNotifyFilterChangeDirectory
|
||||||
|
FltObjectDereference
|
||||||
|
FltObjectReference
|
||||||
|
FltOpenVolume
|
||||||
|
FltOplockFsctrl
|
||||||
|
FltOplockIsFastIoPossible
|
||||||
|
FltParseFileName
|
||||||
|
FltParseFileNameInformation
|
||||||
|
FltPerformAsynchronousIo
|
||||||
|
FltPerformSynchronousIo
|
||||||
|
FltProcessFileLock
|
||||||
|
FltPurgeFileNameInformationCache
|
||||||
|
FltQueryEaFile
|
||||||
|
FltQueryInformationFile
|
||||||
|
FltQuerySecurityObject
|
||||||
|
FltQueryVolumeInformation
|
||||||
|
FltQueryVolumeInformationFile
|
||||||
|
FltQueueDeferredIoWorkItem
|
||||||
|
FltQueueGenericWorkItem
|
||||||
|
FltReadFile
|
||||||
|
FltReferenceContext
|
||||||
|
FltReferenceFileNameInformation
|
||||||
|
FltRegisterFilter
|
||||||
|
FltReissueSynchronousIo
|
||||||
|
FltReleaseContext
|
||||||
|
FltReleaseContexts
|
||||||
|
FltReleaseFileNameInformation
|
||||||
|
FltReleasePushLock
|
||||||
|
FltReleaseResource
|
||||||
|
FltRequestOperationStatusCallback
|
||||||
|
FltRetainSwappedBufferMdlAddress
|
||||||
|
FltReuseCallbackData
|
||||||
|
FltSendMessage
|
||||||
|
FltSetCallbackDataDirty
|
||||||
|
FltSetCancelCompletion
|
||||||
|
FltSetEaFile
|
||||||
|
FltSetFileContext
|
||||||
|
FltSetInformationFile
|
||||||
|
FltSetInstanceContext
|
||||||
|
FltSetSecurityObject
|
||||||
|
FltSetStreamContext
|
||||||
|
FltSetStreamHandleContext
|
||||||
|
FltSetVolumeContext
|
||||||
|
FltSetVolumeInformation
|
||||||
|
FltStartFiltering
|
||||||
|
FltSupportsFileContexts
|
||||||
|
FltSupportsStreamContexts
|
||||||
|
FltSupportsStreamHandleContexts
|
||||||
|
FltTagFile
|
||||||
|
FltUninitializeFileLock
|
||||||
|
FltUninitializeOplock
|
||||||
|
FltUnloadFilter
|
||||||
|
FltUnregisterFilter
|
||||||
|
FltUntagFile
|
||||||
|
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 */
|
5
reactos/drivers/fs_minifilter/fltmgr/fltmgr.rc
Normal file
5
reactos/drivers/fs_minifilter/fltmgr/fltmgr.rc
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#define REACTOS_VERSION_DLL
|
||||||
|
#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Filesystem Filter Manager"
|
||||||
|
#define REACTOS_STR_INTERNAL_NAME "fltmgr"
|
||||||
|
#define REACTOS_STR_ORIGINAL_FILENAME "fltmgr.sys"
|
||||||
|
#include <reactos/version.rc>
|
Loading…
Add table
Add a link
Reference in a new issue