Статья третья, управление...

Сделаем чтобы драйвер блокировал файл только тогда, когда нам нужно.

А вернее чтобы программа управляла драйвером,

и так что нам нужно изменить от предыдущего примера,

Объявим функции в самом начале,

NTSTATUS

NullPortConnect (

__in PFLT_PORT ClientPort,

__in_opt PVOID ServerPortCookie,

__in_bcount_opt(SizeOfContext) PVOID ConnectionContext,

__in ULONG SizeOfContext,

__deref_out_opt PVOID *ConnectionCookie

);

VOID

NullPortDisconnect (

__in_opt PVOID ConnectionCookie

);

NTSTATUS

NullPortMessageNotify (

IN PVOID PortCookie,

IN PVOID InputBuffer OPTIONAL,

IN ULONG InputBufferLength,

OUT PVOID OutputBuffer OPTIONAL,

IN ULONG OutputBufferLength,

OUT PULONG ReturnOutputBufferLength

);

Три функции для работы с портом, вызываются при подключении отключении и принятии сообщения от порта.

Также объявим их чтобы они были в "подкачиваемой" памяти

#ifdef ALLOC_PRAGMA

#pragma alloc_text(INIT, DriverEntry)

#pragma alloc_text(PAGE, NullUnload)

#pragma alloc_text(PAGE, NullInstanceSetup)

#pragma alloc_text(PAGE, NullQueryTeardown)

#pragma alloc_text(PAGE, NullPreCreate)

#pragma alloc_text(PAGE, NullPortConnect)

#pragma alloc_text(PAGE, NullPortDisconnect)

#pragma alloc_text(PAGE, NullPortMessageNotify)

#endif

Теперь изменим функцию входа в драйвер, добавим "тела" трех функций и изменим функцию выгрузки

NTSTATUS

DriverEntry (

__in PDRIVER_OBJECT DriverObject,

__in PUNICODE_STRING RegistryPath

)

{

OBJECT_ATTRIBUTES oa;

UNICODE_STRING uniString;

PSECURITY_DESCRIPTOR sd;

NTSTATUS status;

UNREFERENCED_PARAMETER( RegistryPath );

DbgPrint("Null Filter, DriverEntry\n");

NullFilterData.BlockFile=0; // Уберем мусор из переменной

status = FltRegisterFilter( DriverObject,

&FilterRegistration,

&NullFilterData.FilterHandle );

if (!NT_SUCCESS( status ))

return status;

RtlInitUnicodeString( &uniString, ScannerPortName);

status = FltBuildDefaultSecurityDescriptor( &sd, FLT_PORT_ALL_ACCESS );

if (NT_SUCCESS( status ))

{

InitializeObjectAttributes( &oa,&uniString,OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,NULL,sd );

status = FltCreateCommunicationPort(NullFilterData.FilterHandle,&NullFilterData.ServerPort,&oa,NULL,NullPortConnect,NullPortDisconnect,NullPortMessageNotify,1);// регистрируем наши функции

FltFreeSecurityDescriptor( sd );

if (NT_SUCCESS( status ))

{

status = FltStartFiltering( NullFilterData.FilterHandle );

if (!NT_SUCCESS( status ))

{

FltCloseCommunicationPort( NullFilterData.ServerPort );//Ничего не вышло мы выгружаем все

FltUnregisterFilter( NullFilterData.FilterHandle );

}

}

}

return status;

}

NTSTATUS

NullPortConnect (

__in PFLT_PORT ClientPort,

__in_opt PVOID ServerPortCookie,

__in_bcount_opt(SizeOfContext) PVOID ConnectionContext,

__in ULONG SizeOfContext,

__deref_out_opt PVOID *ConnectionCookie

)

{

PAGED_CODE();

UNREFERENCED_PARAMETER( ServerPortCookie );

UNREFERENCED_PARAMETER( ConnectionContext );

UNREFERENCED_PARAMETER( SizeOfContext);

UNREFERENCED_PARAMETER( ConnectionCookie );

ASSERT( NullFilterData.ClientPort == NULL );

ASSERT( NullFilterData.UserProcess == NULL );

NullFilterData.UserProcess = PsGetCurrentProcess();

NullFilterData.ClientPort = ClientPort;

// Запомним порт

DbgPrint( "!!! NullFilter.sys --- connected, port=0x%p\n", ClientPort );

return STATUS_SUCCESS;

}

VOID

NullPortDisconnect(

__in_opt PVOID ConnectionCookie

)

{

UNREFERENCED_PARAMETER( ConnectionCookie );

PAGED_CODE();

DbgPrint( "!!! NullFilter.sys --- disconnected, port=0x%p\n", NullFilterData.ClientPort );

FltCloseClientPort( NullFilterData.FilterHandle, &NullFilterData.ClientPort );

NullFilterData.UserProcess = NULL;

// отсоединение

}

NTSTATUS

NullPortMessageNotify (

IN PVOID PortCookie,

IN PVOID InputBuffer OPTIONAL,

IN ULONG InputBufferLength,

OUT PVOID OutputBuffer OPTIONAL,

IN ULONG OutputBufferLength,

OUT PULONG ReturnOutputBufferLength

)

// При получении сообщения из программы вызывается эта функция

{

ULONG i;

PAGED_CODE();


DbgPrint( "!!! NullFilter.sys --- Message notify, port=0x%p\n", NullFilterData.ClientPort );

if(InputBufferLength==1)// Проверим буфер

RtlCopyMemory(&NullFilterData.BlockFile,InputBuffer,1);//запомним его

return STATUS_SUCCESS;

}

NTSTATUS

NullUnload (

__in FLT_FILTER_UNLOAD_FLAGS Flags

)

{

UNREFERENCED_PARAMETER( Flags );

PAGED_CODE();

FltCloseCommunicationPort( NullFilterData.ServerPort );

FltUnregisterFilter( NullFilterData.FilterHandle );

DbgPrint("Null Filter, NullUnload");

return STATUS_SUCCESS;

}

...

Наша функция блокировки

FLT_PREOP_CALLBACK_STATUS

NullPreCreate (

__inout PFLT_CALLBACK_DATA Data,

__in PCFLT_RELATED_OBJECTS FltObjects,

__deref_out_opt PVOID *CompletionContext

)

{

PFLT_FILE_NAME_INFORMATION nameInfo;

NTSTATUS status;

BOOLEAN scanFile;

UNICODE_STRING filename;

UNREFERENCED_PARAMETER( FltObjects );

UNREFERENCED_PARAMETER( CompletionContext );


PAGED_CODE();

if(NullFilterData.BlockFile==1)// Если мы получили указание блокировать, то...

{

ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

status = FltGetFileNameInformation( Data,

FLT_FILE_NAME_NORMALIZED |FLT_FILE_NAME_QUERY_DEFAULT,

&nameInfo );

if (!NT_SUCCESS( status )) {

return FLT_PREOP_SUCCESS_WITH_CALLBACK;

}

status = FltParseFileNameInformation( nameInfo );

if (!NT_SUCCESS( status )) {

return FLT_PREOP_SUCCESS_WITH_CALLBACK;

}


if(nameInfo->FinalComponent.Length>0)

{

if (NullFilterData.ClientPort != NULL)

{


}

RtlInitUnicodeString(&filename,L"123.txt\0");

scanFile = RtlEqualUnicodeString(&nameInfo->FinalComponent,&filename,TRUE);

if(scanFile)

{

Data->IoStatus.Status=STATUS_ACCESS_DENIED;

return FLT_PREOP_COMPLETE;

}

}

}

return FLT_PREOP_SUCCESS_WITH_CALLBACK;

}

С драйвером все, теперь возьмемся за программу, её я взял из примера scanner

и очень сильно сократил,

#include <windows.h>

#include <stdio.h>

#include <fltuser.h>

int _cdecl

main (

__in int argc,

__in_ecount(argc) char *argv[]

)

{

HANDLE port;

HRESULT hr;

DWORD bytesReturned;

CHAR buf;

printf( "Scanner: Connecting to the filter ...\n" );

hr = FilterConnectCommunicationPort( L"\\ScannerPort",

0,

NULL,

0,

NULL,

&port );

// Соединяемся с портом драйвера

if (IS_ERROR( hr )) {

printf( "ERROR: Connecting to filter port: 0x%08x\n", hr );

return 2;

}


printf( "Scanner: Port = 0x%p \n", port);

buf=1;

hr = FilterSendMessage( port,

&buf,

1,

0,

0,

&bytesReturned );

//Отсылаем месагу

printf( "Scanner: All done. Result = 0x%08x\n", hr );


CloseHandle( port );

return hr;

}

Теперь включаем драйвер, проверяем можно ли изменять файл 123.txt , после запускаем нашу программу и проверяем снова.

Вот так вот все просто на этом думаю закончу описывать драйвер мини фильтр файловой системы,

Если возникли вопросы пишите мне на почту.

Скачать пример.