📄 scanner.c
字号:
/*++
Copyright (c) 1999-2002 Microsoft Corporation
Module Name:
scanner.c
Abstract:
This is the main module of the scanner filter.
This filter scans the data in a file before allowing an open to proceed. This is similar
to what virus checkers do.
Environment:
Kernel mode
--*/
#include <winerror.h>
#include <fltKernel.h>
#include "scanuk.h"
#include "scanner.h"
#include <dontuse.h>
//
// Structure that contains all the global data structures
// used throughout the scanner.
//
SCANNER_DATA ScannerData;
//
// This is a static list of file name extensions files we are interested in scanning
//
const UNICODE_STRING ScannerExtensionsToScan[] =
{ RTL_CONSTANT_STRING( L"doc"),
RTL_CONSTANT_STRING( L"txt"),
RTL_CONSTANT_STRING( L"bat"),
RTL_CONSTANT_STRING( L"cmd"),
RTL_CONSTANT_STRING( L"inf"),
/*RTL_CONSTANT_STRING( L"ini"), Removed, to much usage*/
{0, 0, NULL}
};
//
// Function prototypes
//
NTSTATUS
ScannerPortConnect (
__in PFLT_PORT ClientPort,
__in_opt PVOID ServerPortCookie,
__in_bcount_opt(SizeOfContext) PVOID ConnectionContext,
__in ULONG SizeOfContext,
__deref_out_opt PVOID *ConnectionCookie
);
VOID
ScannerPortDisconnect (
__in PVOID ConnectionCookie
);
NTSTATUS
ScannerpScanFileInUserMode (
__in PFLT_INSTANCE Instance,
__in PFILE_OBJECT FileObject,
__out PBOOLEAN SafeToOpen
);
BOOLEAN
ScannerpCheckExtension (
__in PUNICODE_STRING Extension
);
//
// Assign text sections for each routine.
//
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGE, ScannerInstanceSetup)
#pragma alloc_text(PAGE, ScannerPreCreate)
#pragma alloc_text(PAGE, ScannerPortConnect)
#pragma alloc_text(PAGE, ScannerPortDisconnect)
#endif
//
// Constant FLT_REGISTRATION structure for our filter. This
// initializes the callback routines our filter wants to register
// for. This is only used to register with the filter manager
//
const FLT_OPERATION_REGISTRATION Callbacks[] = {
{ IRP_MJ_CREATE,
0,
ScannerPreCreate,
ScannerPostCreate},
{ IRP_MJ_CLEANUP,
0,
ScannerPreCleanup,
NULL},
{ IRP_MJ_WRITE,
0,
ScannerPreWrite,
NULL},
{ IRP_MJ_OPERATION_END}
};
const FLT_CONTEXT_REGISTRATION ContextRegistration[] = {
{ FLT_STREAMHANDLE_CONTEXT,
0,
NULL,
sizeof(SCANNER_STREAM_HANDLE_CONTEXT),
'chBS' },
{ FLT_CONTEXT_END }
};
const FLT_REGISTRATION FilterRegistration = {
sizeof( FLT_REGISTRATION ), // Size
FLT_REGISTRATION_VERSION, // Version
0, // Flags
ContextRegistration, // Context Registration.
Callbacks, // Operation callbacks
ScannerUnload, // FilterUnload
ScannerInstanceSetup, // InstanceSetup
ScannerQueryTeardown, // InstanceQueryTeardown
NULL, // InstanceTeardownStart
NULL, // InstanceTeardownComplete
NULL, // GenerateFileName
NULL, // GenerateDestinationFileName
NULL // NormalizeNameComponent
};
////////////////////////////////////////////////////////////////////////////
//
// Filter initialization and unload routines.
//
////////////////////////////////////////////////////////////////////////////
NTSTATUS
DriverEntry (
__in PDRIVER_OBJECT DriverObject,
__in PUNICODE_STRING RegistryPath
)
/*++
Routine Description:
This is the initialization routine for the Filter driver. This
registers the Filter with the filter manager and initializes all
its global data structures.
Arguments:
DriverObject - Pointer to driver object created by the system to
represent this driver.
RegistryPath - Unicode string identifying where the parameters for this
driver are located in the registry.
Return Value:
Returns STATUS_SUCCESS.
--*/
{
OBJECT_ATTRIBUTES oa;
UNICODE_STRING uniString;
PSECURITY_DESCRIPTOR sd;
NTSTATUS status;
UNREFERENCED_PARAMETER( RegistryPath );
//
// Register with filter manager.
//
status = FltRegisterFilter( DriverObject,
&FilterRegistration,
&ScannerData.Filter );
if (!NT_SUCCESS( status )) {
return status;
}
//
// Create a communication port.
//
RtlInitUnicodeString( &uniString, ScannerPortName );
//
// We secure the port so only ADMINs & SYSTEM can acecss it.
//
status = FltBuildDefaultSecurityDescriptor( &sd, FLT_PORT_ALL_ACCESS );
if (NT_SUCCESS( status )) {
InitializeObjectAttributes( &oa,
&uniString,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
sd );
status = FltCreateCommunicationPort( ScannerData.Filter,
&ScannerData.ServerPort,
&oa,
NULL,
ScannerPortConnect,
ScannerPortDisconnect,
NULL,
1 );
//
// Free the security descriptor in all cases. It is not needed once
// the call to FltCreateCommunicationPort() is made.
//
FltFreeSecurityDescriptor( sd );
if (NT_SUCCESS( status )) {
//
// Start filtering I/O.
//
status = FltStartFiltering( ScannerData.Filter );
if (NT_SUCCESS( status )) {
return STATUS_SUCCESS;
}
FltCloseCommunicationPort( ScannerData.ServerPort );
}
}
FltUnregisterFilter( ScannerData.Filter );
return status;
}
NTSTATUS
ScannerPortConnect (
__in PFLT_PORT ClientPort,
__in_opt PVOID ServerPortCookie,
__in_bcount_opt(SizeOfContext) PVOID ConnectionContext,
__in ULONG SizeOfContext,
__deref_out_opt PVOID *ConnectionCookie
)
/*++
Routine Description
This is called when user-mode connects to the server port - to establish a
connection
Arguments
ClientPort - This is the client connection port that will be used to
send messages from the filter
ServerPortCookie - The context associated with this port when the
minifilter created this port.
ConnectionContext - Context from entity connecting to this port (most likely
your user mode service)
SizeofContext - Size of ConnectionContext in bytes
ConnectionCookie - Context to be passed to the port disconnect routine.
Return Value
STATUS_SUCCESS - to accept the connection
--*/
{
PAGED_CODE();
UNREFERENCED_PARAMETER( ServerPortCookie );
UNREFERENCED_PARAMETER( ConnectionContext );
UNREFERENCED_PARAMETER( SizeOfContext);
UNREFERENCED_PARAMETER( ConnectionCookie );
ASSERT( ScannerData.ClientPort == NULL );
ASSERT( ScannerData.UserProcess == NULL );
//
// Set the user process and port.
//
ScannerData.UserProcess = PsGetCurrentProcess();
ScannerData.ClientPort = ClientPort;
DbgPrint( "!!! scanner.sys --- connected, port=0x%X\n", ClientPort );
return STATUS_SUCCESS;
}
VOID
ScannerPortDisconnect(
__in_opt PVOID ConnectionCookie
)
/*++
Routine Description
This is called when the connection is torn-down. We use it to close our
handle to the connection
Arguments
ConnectionCookie - Context from the port connect routine
Return value
None
--*/
{
UNREFERENCED_PARAMETER( ConnectionCookie );
PAGED_CODE();
DbgPrint( "!!! scanner.sys --- disconnected, port=0x%X\n", ScannerData.ClientPort );
//
// Close our handle to the connection: note, since we limited max connections to 1,
// another connect will not be allowed until we return from the disconnect routine.
//
FltCloseClientPort( ScannerData.Filter, &ScannerData.ClientPort );
//
// Reset the user-process field.
//
ScannerData.UserProcess = NULL;
}
NTSTATUS
ScannerUnload (
__in FLT_FILTER_UNLOAD_FLAGS Flags
)
/*++
Routine Description:
This is the unload routine for the Filter driver. This unregisters the
Filter with the filter manager and frees any allocated global data
structures.
Arguments:
None.
Return Value:
Returns the final status of the deallocation routines.
--*/
{
UNREFERENCED_PARAMETER( Flags );
//
// Close the server port.
//
FltCloseCommunicationPort( ScannerData.ServerPort );
//
// Unregister the filter
//
FltUnregisterFilter( ScannerData.Filter );
return STATUS_SUCCESS;
}
NTSTATUS
ScannerInstanceSetup (
__in PCFLT_RELATED_OBJECTS FltObjects,
__in FLT_INSTANCE_SETUP_FLAGS Flags,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -