Как узнать путь к файлу(драйвер фильтр)

Тема в разделе "WASM.WIN32", создана пользователем LuckyDevil, 11 авг 2006.

  1. LuckyDevil

    LuckyDevil New Member

    Публикаций:
    0
    Регистрация:
    10 мар 2005
    Сообщения:
    278
    Адрес:
    Uzbekistan
    Всем доброго!
    Фильтрую пакеты, все вроде было нормально, пока не обнаружил следующую странность.
    Открываю файл Far'ом и не получаю полного пути к файлу, а только имя файла, к примеру если открываю тот же файл notepad'ом то все гуд. Как получить полный путь к файлу в данной ситуации?

    Заранее спасибо!
     
  2. MiraclE

    MiraclE New Member

    Публикаций:
    0
    Регистрация:
    10 авг 2005
    Сообщения:
    38
    Адрес:
    Kazakhstan
    Скорее всего потому что открытие относительное,т.е IrpSp->FileObject->RelatedFileObject!=NULL
     
  3. LuckyDevil

    LuckyDevil New Member

    Публикаций:
    0
    Регистрация:
    10 мар 2005
    Сообщения:
    278
    Адрес:
    Uzbekistan
    MiraclE, и как быть?
    RelatedFileObject попытка прочитать FileName, отправляет системы в BSOD.
     
  4. MiraclE

    MiraclE New Member

    Публикаций:
    0
    Регистрация:
    10 авг 2005
    Сообщения:
    38
    Адрес:
    Kazakhstan
    строка FileName валидна только во время обработки IRP_MJ_CREATE,после создания файла там может быть что угодно.Поэтому для того чтобы узнать имя файла нужно отправить объекту ФС IRP_MJ_QUERY_INFORMATION указав класс FileNameInformation
     
  5. PE386

    PE386 New Member

    Публикаций:
    0
    Регистрация:
    7 авг 2006
    Сообщения:
    127
    Значит смотришь не прямыми руками.

    Код (Text):
    1.     PUNICODE_STRING FileName;
    2.     ULONG           Len  = 0;
    3.     ULONG           Len2 = 0;
    4.     PWCHAR          fName, p;
    5.     BOOLEAN         bFirst = TRUE;
    6.  
    7.     if (FileObject->RelatedFileObject)
    8.     {
    9.         FileName = &FileObject->RelatedFileObject->FileName;
    10.  
    11.         if (FileName->Buffer)
    12.         {
    13.             Len = FileName->Length >> 1;
    14.             memcpy(OutName, FileName->Buffer, FileName->Length);
    15.         }
    16.     }
    17.  
    18.     if (FileObject->FileName.Buffer)
    19.     {
    20.         FileName = &FileObject->FileName;
    21.  
    22.         memcpy(&OutName[Len], FileName->Buffer, FileName->Length);
    23.  
    24.         Len  += FileName->Length >> 1;
    25.     }
     
  6. PE386

    PE386 New Member

    Публикаций:
    0
    Регистрация:
    7 авг 2006
    Сообщения:
    127
    Если это каждый раз делать в обработчике create, то производитетльность пострадает ощутимо. IRP_MJ_QUERY_INFORMATION выполняется довольно долго.
     
  7. MiraclE

    MiraclE New Member

    Публикаций:
    0
    Регистрация:
    10 авг 2005
    Сообщения:
    38
    Адрес:
    Kazakhstan
    Это делается не каждый раз,т.к. процент "относительных открытий" довольно маленький,зато можно не боятся BSOD'a если на месте буфера строки окажется мусор, как я уже говорил,буфер с именем файла 100% валиден только в процессе обработки IRP_MJ_CREATE
     
  8. PE386

    PE386 New Member

    Публикаций:
    0
    Регистрация:
    7 авг 2006
    Сообщения:
    127
    Просмотри сорцов винды показал, что это не так. После посылки IRP_MJ_CLOSE делается освобождение буфера
    Код (Text):
    1. if (fileObject->FileName.Length != 0) {
    2.             ExFreePool( fileObject->FileName.Buffer );
    3.         }
    Тоесть необходимо просто делать проверку на fileObject->FileName.Length.
    Если буфер освобождается черт знает где, то почему же винда тогда не падает при закрытии файлов?
    Вот буфер RelatedFileObject имхо может быть освобожден до закрытия основного FileObject (поправьте меня, если я ошибаюсь).
     
  9. MiraclE

    MiraclE New Member

    Публикаций:
    0
    Регистрация:
    10 авг 2005
    Сообщения:
    38
    Адрес:
    Kazakhstan
    у тебя есть сорцы NTFS ? Кроме IO manager'a буфер трогают драйверы ФС,в рассылке от OSR товарищами из микрософт ясно об этом сказано.
     
  10. LuckyDevil

    LuckyDevil New Member

    Публикаций:
    0
    Регистрация:
    10 мар 2005
    Сообщения:
    278
    Адрес:
    Uzbekistan
    PE386, спасибо за код, но если честно мне он никак не помог, потому как в IRP_MJ_CREATE, если и присутсвует RelatedFileObject, то буфер RelatedFileObject->FileName.Buffer пуст. Замечу проверку делаю в диспечере, потому как условия таковы, получить полный путь к файлу в диспечере.
    MiraclE, скорей всего я пойду вашем методом.
     
  11. LuckyDevil

    LuckyDevil New Member

    Публикаций:
    0
    Регистрация:
    10 мар 2005
    Сообщения:
    278
    Адрес:
    Uzbekistan
    MiraclE, да кстати я тут подумал, что IRP_MJ_QUERY_INFORMATION тоже не получиться использовать, проблема в том что прежде чем послать запрос, нужно открыть файл, т.е. получить хэндл или вы знаете иной способ?
    А если пытаться открыть, то в результате получаем рекурсию или я не прав?
     
  12. LuckyDevil

    LuckyDevil New Member

    Публикаций:
    0
    Регистрация:
    10 мар 2005
    Сообщения:
    278
    Адрес:
    Uzbekistan
    PE386, покривости рук, мне нет соперников :), я был не прав.
     
  13. MiraclE

    MiraclE New Member

    Публикаций:
    0
    Регистрация:
    10 авг 2005
    Сообщения:
    38
    Адрес:
    Kazakhstan
    Ни какой рекурсии не будет,и хэндлы никакие не нужны т.к. мы посылаем ирп напрямую объекту устройство ФС.Вот пример такой функции:
    Код (Text):
    1. BOOLEAN
    2. QueryFile(
    3.     PDEVICE_OBJECT DeviceObject,
    4.     PFILE_OBJECT FileObject,
    5.     FILE_INFORMATION_CLASS FileInformationClass,
    6.     PVOID FileQueryBuffer,
    7.     ULONG FileQueryBufferLength
    8.     )
    9. {
    10.     PIRP irp;
    11.     KEVENT event;
    12.     IO_STATUS_BLOCK IoStatusBlock;
    13.     PIO_STACK_LOCATION ioStackLocation;
    14.     NTSTATUS status;
    15.  
    16.  
    17.     //
    18.     // инициализируем объект событие
    19.     //
    20.     KeInitializeEvent(&event, SynchronizationEvent, FALSE);
    21.  
    22.     //
    23.     // создаем ирп
    24.     //
    25.     //
    26.     irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
    27.     if(!irp) {
    28.  
    29.         //
    30.         // ошибка создания ирп
    31.         //
    32.         return FALSE;
    33.     }
    34.  
    35.     //
    36.     // заполняем тело ирп
    37.     //  
    38.     irp->AssociatedIrp.SystemBuffer = FileQueryBuffer;
    39.     irp->UserEvent = &event;
    40.     irp->UserIosb = &IoStatusBlock;
    41.     irp->Tail.Overlay.Thread = PsGetCurrentThread();
    42.     irp->Tail.Overlay.OriginalFileObject = FileObject;
    43.     irp->RequestorMode = KernelMode;
    44.     irp->Flags = 0;
    45.  
    46.    
    47.     ioStackLocation = IoGetNextIrpStackLocation(irp);
    48.     ioStackLocation->MajorFunction = IRP_MJ_QUERY_INFORMATION;
    49.     ioStackLocation->DeviceObject = DeviceObject;
    50.     ioStackLocation->FileObject = FileObject;
    51.     ioStackLocation->Parameters.QueryFile.Length = FileQueryBufferLength;
    52.     ioStackLocation->Parameters.QueryFile.FileInformationClass = FileInformationClass;
    53.  
    54.     //
    55.     // устанавливаем процедуру завершения
    56.     //
    57.     IoSetCompletionRoutine(irp, QueryFileComplete, 0, TRUE, TRUE, TRUE);
    58.  
    59.     //
    60.     // послыаем ирп драйверу фс
    61.     //
    62.     status=IoCallDriver(DeviceObject, irp);
    63.  
    64.    
    65.     if(status==STATUS_PENDING){
    66.         //если завершение ирп было отложенно ждем на событии
    67.     KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);
    68.     status=IoStatusBlock.Status;
    69.     }
    70.  
    71.     //
    72.     // запрос обработан - возвращаем статус
    73.     //
    74.     //
    75.     return NT_SUCCESS(status);
    76. }
    а вообще можно в ддк поглядеть по вдумчевее и подобные вопросы сами отпадут :)