mirror of
https://github.com/reactos/reactos.git
synced 2024-07-05 12:15:46 +00:00
[FLTMGR]
- Implement FltCreateCommunicationPort, FltCloseCommunicationPort, FltCloseClientPort, and stub FltSendMessage - Add two new object types for the server port and client ports - Implement object type callbacks for closing and deleting these new ports - Create the comms object and create the symbolic link (FltMgrMsg) to allow usermode to open a handle to the comms layer (aka FilterConnectCommunicationPort) - Although untested, the comms layer objects should be mostly setup, and we should be able to open a connection from usermode. svn path=/trunk/; revision=74589
This commit is contained in:
parent
fb1948e7d4
commit
7a5211283a
373
reactos/drivers/filters/fltmgr/Messaging.c
Normal file
373
reactos/drivers/filters/fltmgr/Messaging.c
Normal file
|
@ -0,0 +1,373 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: Filesystem Filter Manager
|
||||||
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
|
* FILE: drivers/filters/fltmgr/Messaging.c
|
||||||
|
* PURPOSE: Contains the routines to handle the comms layer
|
||||||
|
* PROGRAMMERS: Ged Murphy (gedmurphy@reactos.org)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
|
#include "fltmgr.h"
|
||||||
|
#include "fltmgrint.h"
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* DATA *********************************************************************/
|
||||||
|
|
||||||
|
UNICODE_STRING CommsDeviceName = RTL_CONSTANT_STRING(L"\\FileSystem\\Filters\\FltMgrMsg");
|
||||||
|
PDEVICE_OBJECT CommsDeviceObject;
|
||||||
|
|
||||||
|
POBJECT_TYPE ServerPortObjectType;
|
||||||
|
POBJECT_TYPE ClientPortObjectType;
|
||||||
|
|
||||||
|
static
|
||||||
|
BOOLEAN
|
||||||
|
FltpDisconnectPort(
|
||||||
|
_In_ PFLT_PORT_OBJECT PortObject
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* EXPORTED FUNCTIONS ******************************************************/
|
||||||
|
|
||||||
|
_Must_inspect_result_
|
||||||
|
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||||
|
NTSTATUS
|
||||||
|
FLTAPI
|
||||||
|
FltCreateCommunicationPort(_In_ PFLT_FILTER Filter,
|
||||||
|
_Outptr_ PFLT_PORT *ServerPort,
|
||||||
|
_In_ POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
|
_In_opt_ PVOID ServerPortCookie,
|
||||||
|
_In_ PFLT_CONNECT_NOTIFY ConnectNotifyCallback,
|
||||||
|
_In_ PFLT_DISCONNECT_NOTIFY DisconnectNotifyCallback,
|
||||||
|
_In_opt_ PFLT_MESSAGE_NOTIFY MessageNotifyCallback,
|
||||||
|
_In_ LONG MaxConnections)
|
||||||
|
{
|
||||||
|
PFLT_SERVER_PORT_OBJECT PortObject;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* The caller must allow at least one connection */
|
||||||
|
if (MaxConnections == 0)
|
||||||
|
{
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The request must be for a kernel handle */
|
||||||
|
if (!(ObjectAttributes->Attributes & OBJ_KERNEL_HANDLE))
|
||||||
|
{
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get rundown protection on the target to stop the owner
|
||||||
|
* from unloading whilst this port object is open. It gets
|
||||||
|
* removed in the FltpServerPortClose callback
|
||||||
|
*/
|
||||||
|
Status = FltObjectReference(Filter);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create our new server port object */
|
||||||
|
Status = ObCreateObject(0,
|
||||||
|
ServerPortObjectType,
|
||||||
|
ObjectAttributes,
|
||||||
|
KernelMode,
|
||||||
|
NULL,
|
||||||
|
sizeof(FLT_SERVER_PORT_OBJECT),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
(PVOID *)&PortObject);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Zero out the struct */
|
||||||
|
RtlZeroMemory(PortObject, sizeof(FLT_SERVER_PORT_OBJECT));
|
||||||
|
|
||||||
|
/* Increment the ref count on the target filter */
|
||||||
|
FltpObjectPointerReference((PFLT_OBJECT)Filter);
|
||||||
|
|
||||||
|
/* Setup the filter port object */
|
||||||
|
PortObject->Filter = Filter;
|
||||||
|
PortObject->ConnectNotify = ConnectNotifyCallback;
|
||||||
|
PortObject->DisconnectNotify = DisconnectNotifyCallback;
|
||||||
|
PortObject->MessageNotify = MessageNotifyCallback;
|
||||||
|
PortObject->Cookie = ServerPortCookie;
|
||||||
|
PortObject->MaxConnections = MaxConnections;
|
||||||
|
|
||||||
|
/* Insert the object */
|
||||||
|
Status = ObInsertObject(PortObject,
|
||||||
|
NULL,
|
||||||
|
STANDARD_RIGHTS_ALL | FILE_READ_DATA,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
(PHANDLE)ServerPort);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Lock the connection list */
|
||||||
|
ExAcquireFastMutex(&Filter->ConnectionList.mLock);
|
||||||
|
|
||||||
|
/* Add the new port object to the connection list and increment the count */
|
||||||
|
InsertTailList(&Filter->ConnectionList.mList, &PortObject->FilterLink);
|
||||||
|
Filter->ConnectionList.mCount++;
|
||||||
|
|
||||||
|
/* Unlock the connection list*/
|
||||||
|
ExReleaseFastMutex(&Filter->ConnectionList.mLock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Allow the filter to be cleaned up */
|
||||||
|
FltObjectDereference(Filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||||
|
VOID
|
||||||
|
FLTAPI
|
||||||
|
FltCloseCommunicationPort(_In_ PFLT_PORT ServerPort)
|
||||||
|
{
|
||||||
|
/* Just close the handle to initiate the cleanup callbacks */
|
||||||
|
ZwClose(ServerPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
_IRQL_requires_max_(PASSIVE_LEVEL)
|
||||||
|
VOID
|
||||||
|
FLTAPI
|
||||||
|
FltCloseClientPort(_In_ PFLT_FILTER Filter,
|
||||||
|
_Inout_ PFLT_PORT *ClientPort)
|
||||||
|
{
|
||||||
|
PFLT_PORT Port;
|
||||||
|
|
||||||
|
/* Protect against the handle being used whilst we're closing it */
|
||||||
|
FltAcquirePushLockShared(&Filter->PortLock);
|
||||||
|
|
||||||
|
/* Store the port handle while we have the lock held */
|
||||||
|
Port = *ClientPort;
|
||||||
|
|
||||||
|
if (*ClientPort)
|
||||||
|
{
|
||||||
|
/* Set the hadle to null */
|
||||||
|
*ClientPort = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unlock the port */
|
||||||
|
FltReleasePushLock(&Filter->PortLock);
|
||||||
|
|
||||||
|
if (Port)
|
||||||
|
{
|
||||||
|
/* Close the safe handle */
|
||||||
|
ZwClose(Port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_Must_inspect_result_
|
||||||
|
_IRQL_requires_max_(APC_LEVEL)
|
||||||
|
NTSTATUS
|
||||||
|
FLTAPI
|
||||||
|
FltSendMessage(_In_ PFLT_FILTER Filter,
|
||||||
|
_In_ PFLT_PORT *ClientPort,
|
||||||
|
_In_reads_bytes_(SenderBufferLength) PVOID SenderBuffer,
|
||||||
|
_In_ ULONG SenderBufferLength,
|
||||||
|
_Out_writes_bytes_opt_(*ReplyLength) PVOID ReplyBuffer,
|
||||||
|
_Inout_opt_ PULONG ReplyLength,
|
||||||
|
_In_opt_ PLARGE_INTEGER Timeout)
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER(Filter);
|
||||||
|
UNREFERENCED_PARAMETER(ClientPort);
|
||||||
|
UNREFERENCED_PARAMETER(SenderBuffer);
|
||||||
|
UNREFERENCED_PARAMETER(SenderBufferLength);
|
||||||
|
UNREFERENCED_PARAMETER(ReplyBuffer);
|
||||||
|
UNREFERENCED_PARAMETER(ReplyLength);
|
||||||
|
UNREFERENCED_PARAMETER(Timeout);
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* INTERNAL FUNCTIONS ******************************************************/
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
FltpServerPortClose(_In_opt_ PEPROCESS Process,
|
||||||
|
_In_ PVOID Object,
|
||||||
|
_In_ ACCESS_MASK GrantedAccess,
|
||||||
|
_In_ ULONG ProcessHandleCount,
|
||||||
|
_In_ ULONG SystemHandleCount)
|
||||||
|
{
|
||||||
|
PFLT_SERVER_PORT_OBJECT PortObject;
|
||||||
|
PFAST_MUTEX Lock;
|
||||||
|
|
||||||
|
/* Cast the object to a server port object */
|
||||||
|
PortObject = (PFLT_SERVER_PORT_OBJECT)Object;
|
||||||
|
|
||||||
|
/* Lock the connection list */
|
||||||
|
Lock = &PortObject->Filter->ConnectionList.mLock;
|
||||||
|
ExAcquireFastMutex(Lock);
|
||||||
|
|
||||||
|
/* Remove the server port object from the list */
|
||||||
|
RemoveEntryList(&PortObject->FilterLink);
|
||||||
|
|
||||||
|
/* Unlock the connection list */
|
||||||
|
ExReleaseFastMutex(Lock);
|
||||||
|
|
||||||
|
/* Remove the rundown protection we added to stop the owner from tearing us down */
|
||||||
|
FltObjectDereference(PortObject->Filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
FltpServerPortDelete(PVOID Object)
|
||||||
|
{
|
||||||
|
/* Decrement the filter count we added in the create routine */
|
||||||
|
PFLT_SERVER_PORT_OBJECT PortObject = (PFLT_SERVER_PORT_OBJECT)Object;
|
||||||
|
FltpObjectPointerDereference((PFLT_OBJECT)PortObject->Filter);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
FltpClientPortClose(_In_opt_ PEPROCESS Process,
|
||||||
|
_In_ PVOID Object,
|
||||||
|
_In_ ACCESS_MASK GrantedAccess,
|
||||||
|
_In_ ULONG ProcessHandleCount,
|
||||||
|
_In_ ULONG SystemHandleCount)
|
||||||
|
{
|
||||||
|
PFLT_PORT_OBJECT PortObject = (PFLT_PORT_OBJECT)Object;
|
||||||
|
|
||||||
|
if (FltpDisconnectPort(PortObject))
|
||||||
|
{
|
||||||
|
InterlockedDecrement(&PortObject->ServerPort->NumberOfConnections);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
FltpDisconnectPort(_In_ PFLT_PORT_OBJECT PortObject)
|
||||||
|
{
|
||||||
|
BOOLEAN Disconnected = FALSE;
|
||||||
|
|
||||||
|
/* Lock the port object while we disconnect it */
|
||||||
|
ExAcquireFastMutex(&PortObject->Lock);
|
||||||
|
|
||||||
|
/* Make sure we have a valid connection */
|
||||||
|
if (PortObject->Disconnected == FALSE)
|
||||||
|
{
|
||||||
|
/* Let any waiters know we're dusconnecing */
|
||||||
|
KeSetEvent(&PortObject->DisconnectEvent, 0, 0);
|
||||||
|
|
||||||
|
// cleanup everything in the message queue (PortObject->MsgQ.Csq)
|
||||||
|
|
||||||
|
/* Set the disconnected state to true */
|
||||||
|
PortObject->Disconnected = TRUE;
|
||||||
|
Disconnected = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unlock and exit*/
|
||||||
|
ExReleaseFastMutex(&PortObject->Lock);
|
||||||
|
return Disconnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
FltpClientPortDelete(PVOID Object)
|
||||||
|
{
|
||||||
|
PFLT_PORT_OBJECT PortObject = (PFLT_PORT_OBJECT)Object;
|
||||||
|
ObfDereferenceObject(PortObject->ServerPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
FltpSetupCommunicationObjects(_In_ PDRIVER_OBJECT DriverObject)
|
||||||
|
{
|
||||||
|
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
|
||||||
|
UNICODE_STRING SymLinkName;
|
||||||
|
UNICODE_STRING Name;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
GENERIC_MAPPING Mapping =
|
||||||
|
{
|
||||||
|
STANDARD_RIGHTS_READ,
|
||||||
|
STANDARD_RIGHTS_WRITE,
|
||||||
|
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
|
||||||
|
FLT_PORT_ALL_ACCESS
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Create the server comms object type */
|
||||||
|
RtlZeroMemory(&ObjectTypeInitializer, sizeof(OBJECT_TYPE_INITIALIZER));
|
||||||
|
RtlInitUnicodeString(&Name, L"FilterConnectionPort");
|
||||||
|
ObjectTypeInitializer.Length = sizeof(OBJECT_TYPE_INITIALIZER);
|
||||||
|
ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
|
||||||
|
ObjectTypeInitializer.GenericMapping = Mapping;
|
||||||
|
ObjectTypeInitializer.PoolType = NonPagedPool;
|
||||||
|
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(FLT_SERVER_PORT_OBJECT);
|
||||||
|
ObjectTypeInitializer.ValidAccessMask = GENERIC_ALL;
|
||||||
|
ObjectTypeInitializer.CloseProcedure = FltpServerPortClose;
|
||||||
|
ObjectTypeInitializer.DeleteProcedure = FltpServerPortDelete;
|
||||||
|
Status = ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ServerPortObjectType);
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
|
/* Create the client comms object type */
|
||||||
|
RtlZeroMemory(&ObjectTypeInitializer, sizeof(OBJECT_TYPE_INITIALIZER));
|
||||||
|
RtlInitUnicodeString(&Name, L"FilterCommunicationPort");
|
||||||
|
ObjectTypeInitializer.Length = sizeof(OBJECT_TYPE_INITIALIZER);
|
||||||
|
ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
|
||||||
|
ObjectTypeInitializer.GenericMapping = Mapping;
|
||||||
|
ObjectTypeInitializer.PoolType = NonPagedPool;
|
||||||
|
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(FLT_PORT_OBJECT);
|
||||||
|
ObjectTypeInitializer.ValidAccessMask = GENERIC_ALL;
|
||||||
|
ObjectTypeInitializer.CloseProcedure = FltpClientPortClose;
|
||||||
|
ObjectTypeInitializer.DeleteProcedure = FltpClientPortDelete;
|
||||||
|
Status = ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ClientPortObjectType);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the device object */
|
||||||
|
Status = IoCreateDevice(DriverObject,
|
||||||
|
0,
|
||||||
|
&CommsDeviceName,
|
||||||
|
FILE_DEVICE_WPD,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
&CommsDeviceObject);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Setup a symbolic link for the device */
|
||||||
|
RtlInitUnicodeString(&SymLinkName, L"\\DosDevices\\FltMgrMsg");
|
||||||
|
Status = IoCreateSymbolicLink(&SymLinkName, &CommsDeviceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
Quit:
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Something went wrong, undo */
|
||||||
|
if (CommsDeviceObject)
|
||||||
|
{
|
||||||
|
IoDeleteDevice(CommsDeviceObject);
|
||||||
|
CommsDeviceObject = NULL;
|
||||||
|
}
|
||||||
|
if (ClientPortObjectType)
|
||||||
|
{
|
||||||
|
ObMakeTemporaryObject(ClientPortObjectType);
|
||||||
|
ObfDereferenceObject(ClientPortObjectType);
|
||||||
|
ClientPortObjectType = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ServerPortObjectType)
|
||||||
|
{
|
||||||
|
ObMakeTemporaryObject(ServerPortObjectType);
|
||||||
|
ObfDereferenceObject(ServerPortObjectType);
|
||||||
|
ServerPortObjectType = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PRIVATE FUNCTIONS ******************************************************/
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
#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 <ndk/obfuncs.h>
|
||||||
|
#include <ndk/exfuncs.h>
|
||||||
#include <fltkernel.h>
|
#include <fltkernel.h>
|
||||||
#include <pseh/pseh2.h>
|
#include <pseh/pseh2.h>
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
|
|
||||||
@ stdcall FltRegisterFilter(ptr ptr ptr)
|
@ stdcall FltRegisterFilter(ptr ptr ptr)
|
||||||
@ stdcall FltUnregisterFilter(ptr)
|
@ stdcall FltUnregisterFilter(ptr)
|
||||||
|
@ stdcall FltCloseCommunicationPort(ptr)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue