Author: gedmurphy Date: Fri May 19 09:37:38 2017 New Revision: 74589
URL: http://svn.reactos.org/svn/reactos?rev=74589&view=rev Log: [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.
Added: trunk/reactos/drivers/filters/fltmgr/Messaging.c (with props) Modified: trunk/reactos/drivers/filters/fltmgr/fltmgr.h trunk/reactos/drivers/filters/fltmgr/fltmgr.spec
Added: trunk/reactos/drivers/filters/fltmgr/Messaging.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filters/fltmgr/Mess... ============================================================================== --- trunk/reactos/drivers/filters/fltmgr/Messaging.c (added) +++ trunk/reactos/drivers/filters/fltmgr/Messaging.c [iso-8859-1] Fri May 19 09:37:38 2017 @@ -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 ******************************************************/ +
Propchange: trunk/reactos/drivers/filters/fltmgr/Messaging.c ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/drivers/filters/fltmgr/fltmgr.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filters/fltmgr/fltm... ============================================================================== --- trunk/reactos/drivers/filters/fltmgr/fltmgr.h [iso-8859-1] (original) +++ trunk/reactos/drivers/filters/fltmgr/fltmgr.h [iso-8859-1] Fri May 19 09:37:38 2017 @@ -1,11 +1,9 @@ #ifndef _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 <ndk/obfuncs.h> +#include <ndk/exfuncs.h> #include <fltkernel.h> #include <pseh/pseh2.h>
Modified: trunk/reactos/drivers/filters/fltmgr/fltmgr.spec URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filters/fltmgr/fltm... ============================================================================== --- trunk/reactos/drivers/filters/fltmgr/fltmgr.spec [iso-8859-1] (original) +++ trunk/reactos/drivers/filters/fltmgr/fltmgr.spec [iso-8859-1] Fri May 19 09:37:38 2017 @@ -1,4 +1,5 @@
@ stdcall FltRegisterFilter(ptr ptr ptr) @ stdcall FltUnregisterFilter(ptr) + @ stdcall FltCloseCommunicationPort(ptr)