Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Фильтр Драйвер для файловой системы  (Прочитано 9062 раз)
0 Пользователей и 1 Гость смотрят эту тему.
HighLander
Постоялец

il
Offline Offline
Пол: Мужской

« : 28-08-2007 07:40 » 

Всем привет!

Наверное мой вопрос немного странный, но мне очень нужна помощ...

Я хочу написать драйвер который будет следить за всеми I/O на жестком диске, и потом может даже при входе на

сетевые ресурсы (\\Server\Share). (Как FileMon). Основная проблема в том что я нашел очень мало матерьяла про это.

Я начал читать несколько книг, но у меня много вопросов на которые я не нахожу ответов.

Я написал простой драйвер, но он не работает так как я хотел.

Может кто-то может мне помоч? Я был бы очень благодарен...



Женя.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 28-08-2007 14:55 » 

отлично... только где же сами вопросы на которые вы не нашли ответа?)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
HighLander
Постоялец

il
Offline Offline
Пол: Мужской

« Ответ #2 : 28-08-2007 15:40 » 

Я написал вот такой драйвер:

#include <ntddk.h>

typedef unsigned int UINT;
typedef char * PCHAR;

typedef struct _MY_FILTER_EXTENSION
{
    PDEVICE_OBJECT pNextDeviceInChain;

} MY_FILTER_EXTENSION, *PMY_FILTER_EXTENSION;

VOID MyUnload(PDRIVER_OBJECT  DriverObject);
NTSTATUS DriverEntry(PDRIVER_OBJECT  pDriverObject, PUNICODE_STRING  pRegistryPath);
NTSTATUS MyCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS MyClose(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS MyIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS MyWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS MyRead(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS MyUnSupportedFunction(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS MyIoControlInternal(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS MyFixNullString(PCHAR pString, UINT uiSize);
NTSTATUS MyFastIoWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp);

NTSTATUS MyCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    NTSTATUS NtStatus = STATUS_SUCCESS;
    PMY_FILTER_EXTENSION pMyFilterDeviceContext = (PMY_FILTER_EXTENSION)DeviceObject->DeviceExtension;
    PIO_STACK_LOCATION pIoStackIrp = NULL;

    DbgPrint("MyCreate Called \r\n");

    IoSkipCurrentIrpStackLocation(Irp);

    NtStatus = IoCallDriver(pMyFilterDeviceContext->pNextDeviceInChain, Irp);

    DbgPrint("MyCreate Exit 0x%0x \r\n", NtStatus);
   
   return NtStatus;
}

NTSTATUS MyClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    NTSTATUS NtStatus = STATUS_SUCCESS;
    PMY_FILTER_EXTENSION pMyFilterDeviceContext = (PMY_FILTER_EXTENSION)DeviceObject->DeviceExtension;
    PIO_STACK_LOCATION pIoStackIrp = NULL;

    DbgPrint("MyClose Called \r\n");

    IoSkipCurrentIrpStackLocation(Irp);

    NtStatus = IoCallDriver(pMyFilterDeviceContext->pNextDeviceInChain, Irp);

    DbgPrint("MyClose Exit 0x%0x \r\n", NtStatus);
   
   return NtStatus;
}

NTSTATUS MyIoControlInternal(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    NTSTATUS NtStatus = STATUS_SUCCESS;
    PMY_FILTER_EXTENSION pMyFilterDeviceContext = (PMY_FILTER_EXTENSION)DeviceObject->DeviceExtension;
    PIO_STACK_LOCATION pIoStackIrp = NULL;

    DbgPrint("MyIoControlInternal Called \r\n");

    IoSkipCurrentIrpStackLocation(Irp);

    NtStatus = IoCallDriver(pMyFilterDeviceContext->pNextDeviceInChain, Irp);

    DbgPrint("MyIoControlInternal Exit 0x%0x \r\n", NtStatus);
   
   return NtStatus;
}

NTSTATUS MyIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    NTSTATUS NtStatus = STATUS_SUCCESS;
    PMY_FILTER_EXTENSION pMyFilterDeviceContext = (PMY_FILTER_EXTENSION)DeviceObject->DeviceExtension;
    PIO_STACK_LOCATION pIoStackIrp = NULL;

    DbgPrint("MyIoControl Called \r\n");

    IoSkipCurrentIrpStackLocation(Irp);

    NtStatus = IoCallDriver(pMyFilterDeviceContext->pNextDeviceInChain, Irp);

    DbgPrint("MyIoControl Exit 0x%0x \r\n", NtStatus);
   
   return NtStatus;
}

NTSTATUS MyWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    NTSTATUS NtStatus = STATUS_SUCCESS;
    PMY_FILTER_EXTENSION pMyFilterDeviceContext = (PMY_FILTER_EXTENSION)DeviceObject->DeviceExtension;
    PIO_STACK_LOCATION pIoStackIrp = NULL;

    DbgPrint("MyWrite Called \r\n");

    IoSkipCurrentIrpStackLocation(Irp);

    NtStatus = IoCallDriver(pMyFilterDeviceContext->pNextDeviceInChain, Irp);

    DbgPrint("MyWrite Exit 0x%0x \r\n", NtStatus);
   
   return NtStatus;
}

NTSTATUS MyRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    NTSTATUS NtStatus = STATUS_BUFFER_TOO_SMALL;
    PMY_FILTER_EXTENSION pMyFilterDeviceContext = (PMY_FILTER_EXTENSION)DeviceObject->DeviceExtension;
    PIO_STACK_LOCATION pIoStackIrp = NULL;
    PCHAR pReadDataBuffer;

    DbgPrint("MyRead Called \r\n");

    pIoStackIrp = IoGetCurrentIrpStackLocation(Irp);

    IoCopyCurrentIrpStackLocationToNext(Irp);
    IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) MyCompletionRoutine, NULL, TRUE, TRUE, TRUE);

    NtStatus = IoCallDriver(pMyFilterDeviceContext->pNextDeviceInChain, Irp);

    if(NT_SUCCESS(NtStatus))
    {
        if(Irp->IoStatus.Information)
        {
            if(DeviceObject->Flags & DO_BUFFERED_IO)
            {

                    DbgPrint("MyRead - Use Buffered I/O \r\n");

                    pReadDataBuffer = (PCHAR)Irp->AssociatedIrp.SystemBuffer;
               
                    if(pReadDataBuffer && pIoStackIrp->Parameters.Read.Length > 0)
                    {                             
                        MyFixNullString(pReadDataBuffer, (UINT)Irp->IoStatus.Information);
                    }
            }
            else
            {
                if(DeviceObject->Flags & DO_DIRECT_IO)
                {
                    DbgPrint("MyRead - Use Direct I/O \r\n");

                    if(pIoStackIrp && Irp->MdlAddress)
                    {
                        pReadDataBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
                   
                        if(pReadDataBuffer && pIoStackIrp->Parameters.Read.Length)
                        {                             
                            MyFixNullString(pReadDataBuffer, (UINT)Irp->IoStatus.Information);
                        }
                    }
                }
                else
                {

                    DbgPrint("MyRead - Use Neither I/O \r\n");

                    __try {
       
                            if(pIoStackIrp->Parameters.Read.Length > 0 && Irp->UserBuffer)
                            {
                   
                                ProbeForWrite(Irp->UserBuffer, pIoStackIrp->Parameters.Read.Length, TYPE_ALIGNMENT(char));
                                pReadDataBuffer = Irp->UserBuffer;
                   
                                MyFixNullString(pReadDataBuffer, (UINT)Irp->IoStatus.Information);
                            }
                   
                        } __except( EXCEPTION_EXECUTE_HANDLER ) {
                   
                              NtStatus = GetExceptionCode();     
                        }
                }
            }

        }
    }

    Irp->IoStatus.Status = NtStatus;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    DbgPrint("MyRead Exit 0x%0x \r\n", NtStatus);

    return NtStatus;
}

NTSTATUS MyUnSupportedFunction(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    NTSTATUS NtStatus = STATUS_SUCCESS;
    PMY_FILTER_EXTENSION pMyFilterDeviceContext = (PMY_FILTER_EXTENSION)DeviceObject->DeviceExtension;
    PIO_STACK_LOCATION pIoStackIrp = NULL;

    DbgPrint("MyUnSupportedFunction Called \r\n");

    IoSkipCurrentIrpStackLocation(Irp);

    NtStatus = IoCallDriver(pMyFilterDeviceContext->pNextDeviceInChain, Irp);

    DbgPrint("MyUnSupportedFunction Exit 0x%0x \r\n", NtStatus);
   
   return NtStatus;
}

NTSTATUS MyFixNullString(PCHAR pString, UINT uiSize)
{
   NTSTATUS NtStatus = STATUS_SUCCESS;
   UINT uiIndex = 0;

   while(uiIndex < (uiSize - 1))
   {
       if(pString[uiIndex] == 0)
       {
           pString[uiIndex] = ' ';
       }

       uiIndex++;
   }

   pString[uiIndex] = 0;

   return NtStatus;
}

NTSTATUS DriverEntry(PDRIVER_OBJECT  pDriverObject, PUNICODE_STRING  pRegistryPath)
{
    NTSTATUS NtStatus = STATUS_SUCCESS;
    UINT uiIndex = 0;
    PDEVICE_OBJECT pDeviceObject = NULL, pFilteredDevice = NULL;
    UNICODE_STRING usDeviceToFilter;
    PMY_FILTER_EXTENSION pMyFilterDeviceContext;

    DbgPrint("DriverEntry Called \r\n");

    NtStatus = IoCreateDevice(pDriverObject, sizeof(MY_FILTER_EXTENSION), NULL, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDeviceObject);

    if(NtStatus == STATUS_SUCCESS)
    {
      DbgPrint("Device Created \r\n");

        for(uiIndex = 0; uiIndex < IRP_MJ_MAXIMUM_FUNCTION; uiIndex++)
             pDriverObject->MajorFunction[uiIndex] = MyUnSupportedFunction;
   
        pDriverObject->MajorFunction[IRP_MJ_CLOSE]             = MyClose;
        pDriverObject->MajorFunction[IRP_MJ_CREATE]            = MyCreate;
        pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]    = MyIoControl;
        pDriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = MyIoControlInternal;
        pDriverObject->MajorFunction[IRP_MJ_READ]              = MyRead;
        pDriverObject->MajorFunction[IRP_MJ_WRITE]             = MyWrite;

      DbgPrint("MajorFunctions Added 0x%0x \r\n", NtStatus);
   
        pDriverObject->DriverUnload =  MyUnload;

        pMyFilterDeviceContext = (PMY_FILTER_EXTENSION)pDeviceObject->DeviceExtension;

      RtlInitUnicodeString(&usDeviceToFilter, L"\\??\\C:");
        NtStatus = IoAttachDevice(pDeviceObject, &usDeviceToFilter, &pMyFilterDeviceContext->pNextDeviceInChain);

      if(NtStatus == STATUS_SUCCESS)
      {
         DbgPrint("Attached To Device \r\n");
      }

        if(!NT_SUCCESS(NtStatus))
        {
           IoDeleteDevice(pDeviceObject);
        }
        else
        {
            pFilteredDevice = pMyFilterDeviceContext->pNextDeviceInChain;

            pDeviceObject->Flags |= pFilteredDevice->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO);
            pDeviceObject->DeviceType = pFilteredDevice->DeviceType;
            pDeviceObject->Characteristics = pFilteredDevice->Characteristics;
            pDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
        }
    }

   DbgPrint("DriverEntry Finished 0x%0x \r\n", NtStatus);
                               
    return NtStatus;
}

VOID MyUnload(PDRIVER_OBJECT DriverObject)
{
    PMY_FILTER_EXTENSION pMyFilterDeviceContext = (PMY_FILTER_EXTENSION)DriverObject->DeviceObject->DeviceExtension;
    DbgPrint("MyUnload Called \r\n");
    IoDetachDevice(pMyFilterDeviceContext->pNextDeviceInChain);
    IoDeleteDevice(DriverObject->DeviceObject);
}

Я написал его не сам, а нашел в интернете и изменил несколько вещей.

Я понимаю почти все в нем, но есть вещи которые я не понимаю. Может потаму он и не работает как надо.

1. Что делает эта часть кода:

pFilteredDevice = pMyFilterDeviceContext->pNextDeviceInChain;

pDeviceObject->Flags |= pFilteredDevice->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO);
pDeviceObject->DeviceType = pFilteredDevice->DeviceType;
pDeviceObject->Characteristics = pFilteredDevice->Characteristics;
pDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

Что это за флаги? Что такое Characteristics? И зачем мы создаем pFilteredDevice?

2. Что такое Device Extension?

3. В драйвере я подключаюсь к диску С, но даже если я делаю что-то на диске Е драйвер все равно

реагирует.

4. Если я открываю файл то при первом открытии драйвер заходит в MyCreate, MyCleanup, i MyClose,

а потом не реагирует. Внутри MyClose функция IoCallDriver возвращает ошибку 0xc0000010.

Что это может быть?



Зарание благодарю за помощ!
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 29-08-2007 08:21 » 

1. pFilteredDevice -указатель на нижележащий драйвер к которому вы подключились.
   далее копируются свойства:
   первое копирование выставления параметров IOCTL запросов (влияют на то в каком виде к вам придут запросы IOCTL)
   далее тип и хараткеристики - посмотрите в ДДК описание полей структуры DEVICE_OBJECT
DO_DEVICE_INITIALIZING - флаг что устройство находится в стадии инициализации(чтобы к нему никто не обращался раньше времени. перед выходом из DriverEntry обычно его снимают. как и сделано.
   pFilteredDevice(он же pMyFilterDeviceContext->pNextDeviceInChain) - создаем не мы, мы получаем на него ссылку чтоб к нему приатачится - строка:
IoAttachDevice(pDeviceObject, &usDeviceToFilter, &pMyFilterDeviceContext->pNextDeviceInChain);

DeviceExtension - структура котокая содержит все настройки данного объекта (драйвер может быть один а устройств много, поэтому под каждое устройство создается свой DeviceExtension. это вкратце. опять же см DDK.

3. не знаю, надо подумать...

4. MyCleanup - кода не нашел. вместо него будет заходить в MyUnSupportedFunction.
MyCompletionRoutine ссылка в MyRead - кода нет, откуда, где?

..........
подождите.............. а где вообще AddDevice?Не понял
не, помоему вы не разобрались до конца)
не берите пример из интернета. возмите пример из DDK. там их слава богу хватает...
например \DDK3790.1830\src\storage\filters\
он конечно посложнее, разбираться дольше, но зато он целиком правильный) думаю он вам подойдет.
главное для начала основные части понять: DriverEntry|AddDevice|PNPDispatch. IO-Create|Close|Read|Write, IOCTL- интерфейсные
не поленитесь посмотрите требования к ним в DDK/

по началу лучше делать свои ошибки а не исправлять чужие. а это... не будет оно работать в таком виде)

Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
HighLander
Постоялец

il
Offline Offline
Пол: Мужской

« Ответ #4 : 29-08-2007 12:33 » 

Большое спасибо за ответы!

Я наверное еще почитаю книги про драйверы...
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines