shadow device или IoCreateFileSpecifyDeviceObjectHint
От:
Аноним
Дата:
19.06.09 09:31
Оценка:
Для того чтобы избежать рекурсию при открытии файла в irp_mj_create можно использовать IoCreateFileSpecifyDeviceObjectHint, при этом указатель на нижнее устройство можно сохранить (а потом взять) в device extension.
А откуда его брать если у меня есть только имя файла, которое я получаю например из юзер мода через ioctl запрос ? Или в этом случае придется использовать shadow device ?
Re: shadow device или IoCreateFileSpecifyDeviceObjectHint
А>Для того чтобы избежать рекурсию при открытии файла в irp_mj_create можно использовать IoCreateFileSpecifyDeviceObjectHint, при этом указатель на нижнее устройство можно сохранить (а потом взять) в device extension.
Проблема решается парсингом левой части пути с целью извлечь имя устройства, которому, собственно, и следует отправлять запрос. Задача, кстати, совсем не сложная.
Re[2]: shadow device или IoCreateFileSpecifyDeviceObjectHint
От:
Аноним
Дата:
19.06.09 13:53
Оценка:
Здравствуйте, x64, Вы писали:
А>>Для того чтобы избежать рекурсию при открытии файла в irp_mj_create можно использовать IoCreateFileSpecifyDeviceObjectHint, при этом указатель на нижнее устройство можно сохранить (а потом взять) в device extension.
x64>Проблема решается парсингом левой части пути с целью извлечь имя устройства, которому, собственно, и следует отправлять запрос. Задача, кстати, совсем не сложная.
извините не понял.
как мне получить device jbject ? если его открыть для получения по хнедлу запрос же пойдет через мой драйвер ?
Re[3]: shadow device или IoCreateFileSpecifyDeviceObjectHint
Что непонятного-то? Тебе нужен volume device object, так? Так. Я тебе предлагаю получить его не через открытие файла (ну я что, на идиота похож?), а единственно верным способом — парсингом того самого пути, который тебе по IOCTL'у приходит.
Re[4]: shadow device или IoCreateFileSpecifyDeviceObjectHint
От:
Аноним
Дата:
19.06.09 14:47
Оценка:
Здравствуйте, x64, Вы писали:
А>>извините не понял.
x64>Что непонятного-то? Тебе нужен volume device object, так? Так. Я тебе предлагаю получить его не через открытие файла (ну я что, на идиота похож?), а единственно верным способом — парсингом того самого пути, который тебе по IOCTL'у приходит.
как это делается ? можно примерный код ?
Re[5]: shadow device или IoCreateFileSpecifyDeviceObjectHint
Советую прийти сюда через год-два и устыдиться написанному.
Re[2]: shadow device или IoCreateFileSpecifyDeviceObjectHint
От:
Аноним
Дата:
21.06.09 15:00
Оценка:
Здравствуйте, x64, Вы писали:
x64>Проблема решается парсингом левой части пути с целью извлечь имя устройства, которому, собственно, и следует отправлять запрос. Задача, кстати, совсем не сложная.
есть путь
\Device\HarddiskVolume1\Documents and Settings\user\Рабочий стол\Текстовый документ.txt
имя устройства
\Device\HarddiskVolume1
для получения device object вызываю
IoGetDeviceObjectPointer(&DevName, FILE_READ_DATA, &pFileObject, &pDeviceObject)
возвращается 0x00000022 access denied (делал и в текущем контексте и в системном (через создание потока))
если в DevName передать первоначальный путь, то отрабатывает без ошибок, но запрос проходит через мой фильтр, что меня не устраивает.
что я делаю не так и как правильно ?
Re[3]: shadow device или IoCreateFileSpecifyDeviceObjectHint
Re[4]: shadow device или IoCreateFileSpecifyDeviceObjectHint
От:
Аноним
Дата:
22.06.09 09:22
Оценка:
Здравствуйте, x64, Вы писали:
А>>...как правильно ?
x64>ObReferenceObjectByName()
объявлено так (нашел на форуме, т.к. в хедерах объявлений не нашел):
extern POBJECT_TYPE IoDeviceObjectType;
extern NTKERNELAPI NTSTATUS ObReferenceObjectByName(IN PUNICODE_STRING ObjectName,
IN ULONG Attributes,
IN PACCESS_STATE PassedAccessState OPTIONAL,
IN ACCESS_MASK DesiredAccess OPTIONAL,
IN POBJECT_TYPE ObjectType,
IN KPROCESSOR_MODE AccessMode,
IN OUT PVOID ParseContext OPTIONAL,
OUT PVOID *Object);
Да, действительно, и не поможет, ибо для девайсов эта функция работать не будет, если в предпоследнем параметре передать NULL. Реально система передаёт туда указатель на OPEN_PACKET, который недокументирован и вручную собирать его нам не с руки. Потому для решения твоей проблемы предлагаю два варианта — либо парсить дерево имён менеджера объектов вручную, т.е. открывать сначала \Device через ZwOpenFile(), это будет папка, по её хендлу получить указатель на объект-папку, который далее приводить уже к настоящим (но недокументированным) структурам, в которых уже и будут указатели на объекты, в том числе и на искомый объект-девайс \HarddiskVolume1. В этом способе ничего хитрого или сложного нет, единственное, что придётся под каждую версию Windows (XP, Vista, ...) смотреть какие там структуры и менять в зависимости от этого код. Плюс это не универсально. Второй способ заключается в манипуляциях с top level IRP, — способ практически документированный, но имеет свои недостатки. Есть ещё упомянутый тобой способ с shadow device, но он тоже не универсален будет в данном случае.
Итак, что выбираешь, о, мой маленький Аладдин?
Re[8]: shadow device или IoCreateFileSpecifyDeviceObjectHint
От:
Аноним
Дата:
22.06.09 16:34
Оценка:
Здравствуйте, x64, Вы писали:
x64>Итак, что выбираешь, о, мой маленький Аладдин?
если так:
беру все устрнойства моего драйвера, смотрю куда они приатачены, прохожу по стеку до самого нижнего, запрашиваю для него имя и сравниваю с искомым
если совпало, то у меня указатель на нужное устройство, для которого можно вызвать IoCreateFileSpecifyDeviceObjectHint
Re[9]: shadow device или IoCreateFileSpecifyDeviceObjectHint
А>беру все устрнойства моего драйвера, смотрю куда они приатачены, прохожу по стеку до самого нижнего, запрашиваю для него имя и сравниваю с искомым А>если совпало, то у меня указатель на нужное устройство, для которого можно вызвать IoCreateFileSpecifyDeviceObjectHint
А это всё "вариации на тему" того же shadow device, например. Это, в общем и целом, конечно, будет работать, но ты уверен, что пути, которые приложение тебе будет посылать, всегда будут в нормализованном виде? Я имею в виду без ссылок типа \??\X: . Если да, тогда способ одобряю, иначе без парсинга всё равно не обойтись, хотя бы для того, чтобы нормализовать имя.
P.S.
Почему бы не перейти на минифильтры, пока не поздно?
Re[10]: shadow device или IoCreateFileSpecifyDeviceObjectHin
От:
Аноним
Дата:
22.06.09 16:50
Оценка:
Здравствуйте, x64, Вы писали:
А>>беру все устрнойства моего драйвера, смотрю куда они приатачены, прохожу по стеку до самого нижнего, запрашиваю для него имя и сравниваю с искомым А>>если совпало, то у меня указатель на нужное устройство, для которого можно вызвать IoCreateFileSpecifyDeviceObjectHint
x64>А это всё "вариации на тему" того же shadow device, например. Это, в общем и целом, конечно, будет работать, но ты уверен, что пути, которые приложение тебе будет посылать, всегда будут в нормализованном виде? Я имею в виду без ссылок типа \??\X: . Если да, тогда способ одобряю, иначе без парсинга всё равно не обойтись, хотя бы для того, чтобы нормализовать имя.
путь же я сам формирую и парсю его еще на р3
а для того, что приходит через irp create используется IoCreateFileSpecifyDeviceObjectHint так как там указатель на следующее устройство известен
x64>P.S. x64>Почему бы не перейти на минифильтры, пока не поздно?
а что мне это даст ?
мне надо в irp create решать можно или нет открыть файл
а в irp write при необходимости ставить файлу атрибут
Re[11]: shadow device или IoCreateFileSpecifyDeviceObjectHin
Ну, я предупредил.
x64>>Почему бы не перейти на минифильтры, пока не поздно? А>а что мне это даст ?
Преимущества минифильтров перед legacy-моделью описаны в MSDN. В твоём случае это, как минимум, поможет избежать рекурсии безо всяких заморочек, ибо читаем внимательно описание FltCreateFile():
FltCreateFile sends the create request only to the instances attached below the specified minifilter driver instance and to the file system. The specified instance and the instances attached above it do not receive the create request. If no instance is specified, the request goes to the top of the stack and is received by all instances and the file system.
Я не уговариваю, это так... совет.
Re[12]: shadow device или IoCreateFileSpecifyDeviceObjectHin
x64>Преимущества минифильтров перед legacy-моделью описаны в MSDN. В твоём случае это, как минимум, поможет избежать рекурсии безо всяких заморочек, ибо читаем внимательно описание FltCreateFile():
Нисколько не умаляя достоинств минифильтров... чем в данном случае FltCreateFile лучше, чем IoCreateFileSpecifyDeviceObjectHint?
Re[9]: shadow device или IoCreateFileSpecifyDeviceObjectHint
А>если так: А>беру все устрнойства моего драйвера, смотрю куда они приатачены, прохожу по стеку до самого нижнего, запрашиваю для него имя и сравниваю с искомым А>если совпало, то у меня указатель на нужное устройство, для которого можно вызвать IoCreateFileSpecifyDeviceObjectHint
Можно не бегать вниз по стеку, а просто при маунте запросить имя у IrpSp->Parameters.MountVolume.Vpb->RealDevice и сохранить его в device extension.
Re[13]: shadow device или IoCreateFileSpecifyDeviceObjectHin
AA>Нисколько не умаляя достоинств минифильтров... чем в данном случае FltCreateFile лучше, чем IoCreateFileSpecifyDeviceObjectHint?
Перечитай всю ветку ещё раз более внимательно. Для IoCreateFileSpecifyDeviceObjectHint() нужно иметь под рукой указатель на целевой девайс, в то время как для FltCreateFile() достаточно передать указатель на экземпляр своего минифильтра и запрос автоматически пойдёт к тому девайсу, который ниже по стеку (см. параметр Instance у этой функции). Т.е. с минифильтрами думать о рекурсиях в общем случае не приходится.
Re[14]: shadow device или IoCreateFileSpecifyDeviceObjectHin
Здравствуйте, x64, Вы писали:
AA>>Нисколько не умаляя достоинств минифильтров... чем в данном случае FltCreateFile лучше, чем IoCreateFileSpecifyDeviceObjectHint?
x64>Перечитай всю ветку ещё раз более внимательно. Для IoCreateFileSpecifyDeviceObjectHint() нужно иметь под рукой указатель на целевой девайс, в то время как для FltCreateFile() достаточно передать указатель на экземпляр своего минифильтра и запрос автоматически пойдёт к тому девайсу, который ниже по стеку (см. параметр Instance у этой функции). Т.е. с минифильтрами думать о рекурсиях в общем случае не приходится.
Автор спрашивал в своём первом сообщении о защите от рекурсии при открытии файла по имени. А получить экземпляр своего фильтра по имени — это не совсем простая задача. Нужно сначала получить объект тома с помощью вызова FltGetVolumeFromName, а потом из него получить экземпляр с помощью вызова FltEnumerateInstances. Причём FltGetVolumeFromName — это очень медленная функция, и она тоже требует путь к устройству \Device\Harddiskvolume1.
Проблем нет, только если вы точно знаете, что открываемый файл лежит на том же томе, что и файл, к которому пришёл запрос, например в Pre-Create колбек. В этом случае экземпляр фильтра приходит вам в параметрах.
Кстати, FltCreateFile внутри реализована именно через IoCreateFileSpecifyDeviceObjectHint.