|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Авг 6, 2004 22:57:21 [ bd04: У меня в структуре device_extension располагается переменная указатель на структуру IO_REMOVE_LOCK, а сама эта структура как и была, в ntddk.inc ] Да ты чё! Совсем уже, того?! В ntddk.inc находится определение структуры. А её экземпляр (кусок памяти размером с эту структуру) должен быть у тя в экстеншене. Не указатель! А сама структура! Короче, вот примерно так. DEVICE_EXTENSION STRUCT
pThisDevice PDEVICE_OBJECT ?
pLowerDevice PDEVICE_OBJECT ?
RemoveLock IO_REMOVE_LOCK <> ; структура
DEVICE_EXTENSION ENDS
SomeProc1 proc...
local pDeviceObject:PDEVICE_OBJECT
. . .
invoke IoCreateDevice,..., sizeof DEVICE_EXTENSION,..., addr pDeviceObject
. . .
mov eax, pDeviceObject
mov eax, (DEVICE_OBJECT PTR [eax]).DeviceExtension
lea eax, (DEVICE_EXTENSION PTR [eax]).RemoveLock
invoke IoInitializeRemoveLock, eax,...
. . .
SomeProc1 endp
DriverDispatch proc uses ebx pDeviceObject:PDEVICE_OBJECT,...
local pRemoveLock:PTR IO_REMOVE_LOCK
. . .
mov eax, pDeviceObject
mov eax, (DEVICE_OBJECT PTR [eax]).DeviceExtension
lea eax, (DEVICE_EXTENSION PTR [eax]).RemoveLock
mov pRemoveLock, eax
invoke IoAcquireRemoveLock, pRemoveLock,...
; Ля-ля, тополя.
invoke IoReleaseRemoveLock, pRemoveLock,...
. . .
DriverDispatch endp
[ bd04: Какой код тебе показать ? ] Уже не надо. И так всё понятно :) PS: Кстати, странно. У тя кирдык должен был быть уже когда ты IoInitializeRemoveLock вызывал. Ведь экстеншн заполняется нулями (вроде). Т.е. ты фактически передаешь IoInitializeRemoveLock нулевой указатель. |
|
|
Дата: Авг 7, 2004 00:23:52 [В ntddk.inc находится определение структуры. А её экземпляр (кусок памяти размером с эту структуру) должен быть у тя в экстеншене. Не указатель! А сама структура! Короче, вот примерно так.] Почему тогда в структуре device_extension только указатели на структуру device_object, а не сами куски структуры, а сама структура описана в inc файле ? Чем структура IO_REMOVE_LOCK «провинилась» ? Или экземпляр (кусок памяти размером со структуру вида структуры device_object в device_extension) создает createdevice ? Так там же указатель, на device_object, а не структура. [Кстати, странно. У тя кирдык должен был быть уже когда ты IoInitializeRemoveLock вызывал. Ведь экстеншн заполняется нулями (вроде). Т.е. ты фактически передаешь IoInitializeRemoveLock нулевой указатель.] Вот то – то же и оно. Что, если бы совсем было не так уж хорошо, тогда бы все на стадии IoInitialize превратилось в синий экран. Или не должно было совсем работать, или должно было работать, а тут, часть работает, часть нет. [Да ты чё! Совсем уже, того?!] Так, что ты ошибся. Это гадкие программисты из MS, написали такую OS и такую документацию к системному программированию. Или не должно было совсем работать, или должно было работать, а тут, часть работает, часть нет... Если найду, посмотрю С++ пример, там вроде в device_extension был указатель на структуру, а не сама структура. |
|
|
Дата: Авг 7, 2004 00:57:19 Она (структура device_object) создается функцией createdevice наверное где – то в памяти (не в device_extension) и ее «шаблон» , описан в inc файле. Но почему тогда в device_extension указатель на device_object, на структура device_object ? |
|
|
Дата: Авг 7, 2004 01:41:56 [ bd04: Так, что ты ошибся. ] Ничего я не ошибся. Программисты из MS совсем не дураки и с документацией тоже все в порядке... ну почти :) Вобщем так. Никакой такой структуры DEVICE_EXTENSION нет! Точнее, нет предопределенной. Ты сам её определяешь. Что хочешь, то туда и понапихай. Хоть указатель на IO_REMOVE_LOCK, хоть её саму и ещё тучу всего. Системе это по барабану. Она нужна тебе. Смысл в том, что этот кусок памяти ассоциириется с девайсом. А выделяется он (кусок памяти) функцией IoCreateDevice. Второй параметр как раз и определяет, размер экстеншена. Сама эта память будет лежать сразу за DEVICE_OBJECT и будет забита нулями. После создания девайса ты понапихиваешь туда, что те надо и используешь там где надо. При удалении девайса IoDeleteDevice, девайс экстеншн автоматически удаляется. Вот те код. Ставь int 3 перед IoCreateDevice и внимательно в айсе разбирайся, где и что лежит. И почитай в ДДК "Using Remove Locks". К сожалению, у мя нет работоспособного драйвера (на асме), где использовались бы ремувлоки, но в ДДК полно примеров. DEVICE_EXTENSION STRUCT
pThisDevice PDEVICE_OBJECT ?
RemoveLock IO_REMOVE_LOCK <>
BlaBla1 DWORD ?
BlaBla2 DWORD ?
WasmTag DWORD ?
DEVICE_EXTENSION ENDS
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::
DriverEntry proc uses ebx pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING
local pDeviceObject:PDEVICE_OBJECT
invoke IoCreateDevice, pDriverObject, sizeof DEVICE_EXTENSION, addr g_usDeviceName, \
FILE_DEVICE_UNKNOWN, 0, FALSE, addr pDeviceObject
.if eax == STATUS_SUCCESS
mov eax, pDeviceObject
mov ebx, (DEVICE_OBJECT PTR [eax]).DeviceExtension
assume ebx:ptr DEVICE_EXTENSION
mov eax, pDeviceObject
mov [ebx].pThisDevice, eax
lea eax, (DEVICE_EXTENSION PTR [ebx]).RemoveLock
invoke IoInitializeRemoveLock, eax, 0, 0, 0
mov [ebx].BlaBla1, 1
mov [ebx].BlaBla2, 2
mov [ebx].WasmTag, 'MSAW'
assume ebx:nothing
invoke IoDeleteDevice, pDeviceObject
.endif
mov eax, STATUS_DEVICE_CONFIGURATION_ERROR
ret
DriverEntry endp |
|
|
Дата: Авг 7, 2004 21:32:13 [Ничего я не ошибся.] Ошибся. Ошибся в том, что ляпы - то как раз программистов, из MS. Это они так написали Windows и документацию к программированию драйверов, которой потом другие пользуются. Ты вот написал немного другое, и вроде как работает, почти. [Программисты из MS совсем не дураки] Сколько ошибок в коде Windows, как иногда написаны описания, сколько недокументированных функций, сколько недокуметированных "возможностей" у докуметированных функций. Зачем они Service Pack' и выпускают ? [и с документацией тоже все в порядке... ну почти :) ] Ага, иногда ее просто нет (кое на что совсем нет). [Вот те код. Ставь int 3 перед IoCreateDevice и внимательно в айсе разбирайся, где и что лежит. И почитай в ДДК "Using Remove Locks". К сожалению, у мя нет работоспособного драйвера (на асме), где использовались бы ремувлоки, но в ДДК полно примеров. ] Когда будет рабочий, пришлю. Cейчас работают 3 из 4 функций, не работает только IoReleaseRemoveLockAndWait в DriverUnload показывает «синеву» . Посмотрю еще ее. |
|
|
Дата: Авг 8, 2004 00:59:37 [ bd04: Ошибся. Ошибся в том, что ляпы-то как раз программистов, из MS. Это они так написали Windows и документацию к программированию драйверов, которой потом другие пользуются. Ты вот написал немного другое, и вроде как работает, почти. ] По-моему, ты мне льстишь :))) IMHO, Windows - сложная система. М$ - большая контора. Код пишут одни, доки другие. Народу тыщи... Ну это для флейма. [ bd04: IoReleaseRemoveLockAndWait в DriverUnload показывает «синеву». ] Хе-хе. это потому, что у тя IoReleaseRemoveLockAndWait вообще ничего не ждет, а просто возвращается и дровина тю-тю. А не ждет она потому, что у тя нет парного ей вызова IoAcquireRemoveLock. Вот примерный псевдо-код DispatchPnp для P'n'P драйвера. DispatchPnp {
IoAcquireRemoveLock...
switch( MinorFunction ) {
case IRP_MN_REMOVE_DEVICE:
IoReleaseRemoveLockAndWait...
return;
}
IoReleaseRemoveLock...
}Видишь пары:
IoAcquireRemoveLock IoReleaseRemoveLockAndWait IoAcquireRemoveLock IoReleaseRemoveLock Если у тя IoInitializeRemoveLock в DriverEntry, то сразу после неё вызови IoAcquireRemoveLock. Тогда должно быть всё нормально. Я уже говорил, что ни разу не встречал ремувлоки в не P'n'P дровах, т.к. изначально они для них не разрабатывались. Теоритически могут быть такие косяки. Косяк №1: В DriverUnload ты вызываешь IoReleaseRemoveLockAndWait и она подвешивает поток. Теоритически на неограниченное время. Но это поток системного процесса. Например, для DriverEntry есть такая фича, что если она в течение 30 сек не вернет управление, то система выгружает драйвер. Что-то подобное может быть и для DriverUnload. Тут надо поисследовать поведение диспетчера. Косяк №2: DriverUnload висит ожидая, что кто-то вызовет IoReleaseRemoveLock. Кто-то её вызывает. При этом IoReleaseRemoveLock освободит событие, на котором ждет поток DriverUnload и он сразу же может получить управление (ещё до возвращения из IoReleaseRemoveLock). Драйвер выгружается. Управление передается потоку, вызвавшему IoReleaseRemoveLock и она возвращается в код драйвера, которого уже нет. Этот косяк можно вылечить небольшой задержкой сразу после IoReleaseRemoveLockAndWait. Хотя тут всё сильно зависит от приоритетов потоков и загрузки системы. Обычно в не P'n'P дровах встречается другой метод. Ты просто пихаешь ноль в DRIVER_OBJECT.DriverUnload. Тогда система просто не сможет выгрузить драйвер ни при каких условиях. И ведешь подсчет отложенным операциям в/в. Когда у тя нет таких незавершенных операций, тогда драйвер можно безопасно выгрузить предварительно сделав детач от стека драйверов. Когда ты детачнулся, то никакие IRP к те больше влитать не будут. И если незавершенных операций в/в не осталось, то можно восстановить указатель на DriverUnload. И драйвер станет выгружаемым. Вобщем, экспериментируй дальше. |
|
|
Дата: Авг 8, 2004 18:26:32 [По-моему, ты мне льстишь :))) ] Может тебе отправить резюме в MS, чтобы тебя туда взяли писать документацию. Или ты не хочешь ? [Народу тыщи... Ну это для флейма.] Ок. [Видишь пары: IoAcquireRemoveLock IoReleaseRemoveLockAndWait IoAcquireRemoveLock IoReleaseRemoveLock ] Это да, но может быть в диспетчерской процедуре после IoReleaseRemoveLock поставить status = STATUS_MORE_PROCESSING_REQUIRED или как отложенный, а в Unload проверять его ? [Я уже говорил, что ни разу не встречал ремувлоки в не P'n'P дровах, т.к. изначально они для них не разрабатывались. Теоритически могут быть такие косяки. ] Но в legacy, наверное почти все что надо обрабатывать, надо писать руками. |
|
|
Дата: Авг 8, 2004 18:47:00 Это да, но может быть в диспетчерской процедуре после IoReleaseRemoveLock поставить status = STATUS_MORE_PROCESSING_REQUIRED или как отложенный, а в Unload проверять его ? То есть вернулся статус "Pending" , то IoReleaseRemoveLockAndWait, иначе выгрузка без IoReleaseRemoveLockAndWait ? [Косяк №1:] Когда такое может быть ? |
|
|
Дата: Авг 8, 2004 22:04:06 [ bd04: Может тебе отправить резюме в MS, чтобы тебя туда взяли писать документацию. Или ты не хочешь ? ] Хмм... Интересная мысль :) Боюсь тока, не возьмут меня. Да я и сам не пойду. [ bd04: Это да, но может быть в диспетчерской процедуре после IoReleaseRemoveLock поставить status = STATUS_MORE_PROCESSING_REQUIRED ] STATUS_MORE_PROCESSING_REQUIRED не возвращаеют из процедур диспетчеризации. Это статус предназначен для процедур обработки завершения IRP (Completion Routine). Ты наверное на вызываешь IoSetCompletionRoutine? В процедуре диспетчеризации ты можешь вернуть STATUS_PENDING, то тут тебе это не поможет. [ bd04: а в Unload проверять его ? ] Ну и как же ты в DriverUnload будешь его (кого, кстати) проверять? Что, будешь запоминать все IRP, которые к тебе влетели? [ bd04: Когда такое может быть ? ] Я не знаю когда и не знаю может ли он быть вообще. Это теоритически возможный косяк. Ты тормозишь системный поток. Что будет делать система, и будет ли она что-то делать вообще, я не знаю. Но для DriverEntry, как я уже сказал, есть ограничение в 30 сек. Если она зависнет на большее время, система выгрузит драйвер. Возможно и для DriverUnload есть что-то подобное. В любом случае, ты блокируешь системный поток на неопределенный интервал. Это само по себе плохо. Вобщем, ты что-то мудришь. Сам не знаешь чего. Поскольку ты фильтр пишешь, то должен знать как обрабатывается IRP. В IFS KIT есть целый раздел об этом. Стати писались командой osr.com. Возможно (даже наверняка) они там есть. Или на osronline.com. Я на всякий случай, вырипал что надо. Не советую браться за фильтры, пока не поймешь обработку IRP - это довольно сложно. Особенно, учитывая, что ты хочешь прикрутить какое-то нестандартное решение, без этих знаний никуда. 343594733__IoCompletion.rar |
|
|
Дата: Авг 8, 2004 22:48:19 [Вобщем, ты что-то мудришь. Сам не знаешь чего. ] К сожалению знаю. Потому что, если бы не знал, было бы легче, потому что, то, что ищу, не очень много нде описано, еще меньше для legacy, а тем более на ассемблере. Так не знал бы, не искал бы. [Поскольку ты фильтр пишешь, то должен знать как обрабатывается IRP] В общих чертах, уже знаю. [Не советую браться за фильтры, пока не поймешь обработку IRP - это довольно сложно] Так он у меня уже делает частично обработку IRP(потом буду добавлять еще кое что, то есть еще 1 - 2 обработчика IRP) . Тут речь - то о другом, о динамичкеской выгрузке/загрузке, хоть и во время обработки IRP. [В IFS KIT есть целый раздел об этом] У тебя нет книги про IFS в электронном виде ? Про CompletitionRoutine, для того обработчика, который пока что обрабатывает IRPs, она не совсем нужна (ее можно поставить, а можно и не ставить). |
|
|
Дата: Авг 8, 2004 22:53:36 [Если у тя IoInitializeRemoveLock в DriverEntry, то сразу после неё вызови IoAcquireRemoveLock. Тогда должно быть всё нормально. ] После вызова UnLoad синий экран. И чем интересно понравился синий цвет Б. Г.. |
|
|
Дата: Авг 8, 2004 22:54:56 То есть ее (IoAcquireRemoveLock) в драйвере 2 раза вызывать ? |
|
|
Дата: Авг 9, 2004 00:05:41 [ bd04: Так не знал бы, не искал бы. ] Забыл сказать. 15-ая статья-то как раз про фильтры будет. Вот тока когда... ;) [ bd04: У тебя нет книги про IFS в электронном виде ? ] Ищи "Building NT File System Drivers" by Rajeev Nagar. Она много где лежит в pdf. Немного старенькая, правда, но всё равно актуальна. [ bd04: После вызова UnLoad синий экран. ] Ну ты знаешь, они разные бывают :) Хоть стоп-код скажи. [ bd04: То есть ее (IoAcquireRemoveLock) в драйвере 2 раза вызывать ? ] Важно не это. Важно чтобы для каждого вызова IoAcquireRemoveLock был парный вызов IoReleaseRemoveLock. И перед IoReleaseRemoveLockAndWait должен быть парный вызов IoAcquireRemoveLock. Вот те исходники этих функций с моими комментариями(пришлось мне попариться :( ). После разбора вопросов не должно остаться. Синий экран возможно из-за того, что у тя пары не соблюдаются. IoInitializeRemoveLockEx(
IN PIO_REMOVE_LOCK Lock,
. . .
)
{
if (Lock) {
Lock->Common.Removed = FALSE;
Lock->Common.IoCount = 1;
KeInitializeEvent(&Lock->Common.RemoveEvent, SynchronizationEvent, FALSE);
}
}
IoAcquireRemoveLockEx(
IN PIO_REMOVE_LOCK Lock,
. . .
)
{
LONG lockValue;
NTSTATUS status;
; Увеличиваем на единицу счетчик блокировок IoCount
lockValue = InterlockedIncrement(&Lock->Common.IoCount);
if (! Lock->Common.Removed) {
; Усли флаг Removed не установлен, то выходим.
status = STATUS_SUCCESS;
} else {
; Усли флаг Removed установлен, значит IoReleaseRemoveLockAndWaitEx
; уже ждет. Тогда мы не должны захватывать блокировку.
; Вертаем IoCount назад.
if (0 == InterlockedDecrement (&Lock->Common.IoCount)) {
; Если это была последняя блокировка сигналим событие,
; на котором ждет IoReleaseRemoveLockAndWaitEx
KeSetEvent (&Lock->Common.RemoveEvent, 0, FALSE);
}
; Тот, кто вызвал меня, должен проверить статус.
; Я верну STATUS_DELETE_PENDING и он поймет,
; что больше использовать блокировку нельзя.
status = STATUS_DELETE_PENDING;
}
return status;
}
IoReleaseRemoveLockEx(
IN PIO_REMOVE_LOCK Lock,
. . .
)
{
LONG lockValue;
; Уменьшаем на единицу счетчик блокировок IoCount
lockValue = InterlockedDecrement(&Lock->Common.IoCount);
if (0 == lockValue) {
; Если это была последняя блокировка сигналим событие,
; на котором ждет IoReleaseRemoveLockAndWaitEx
KeSetEvent(&Lock->Common.RemoveEvent, IO_NO_INCREMENT, FALSE);
}
return;
}
IoReleaseRemoveLockAndWaitEx (
IN PIO_REMOVE_LOCK Lock,
. . .
)
{
LONG ioCount;
; Устанавливаем флаг Removed, для того, чтобы IoAcquireRemoveLockEx
; больше не захватывала эту блокировку
Lock->Common.Removed = TRUE;
; Уменьшаем на единицу счетчик блокировок IoCount
; Перед вызовом IoReleaseRemoveLockAndWaitEx должен быть
; парный вызов IoAcquireRemoveLockEx
; Этот декремент вернет IoCount в прежнее состояние
ioCount = InterlockedDecrement (&Lock->Common.IoCount);
if (0 < InterlockedDecrement (&Lock->Common.IoCount)) {
; Ещё раз уменьшаем на единицу счетчик блокировок IoCount
; IoInitializeRemoveLockEx устанавливает IoCount в единицу
; Если этот декремент ещё не обнулил IoCount, значит
; кто-то ещё пользуется этой блокировкой. Придется ждать.
; Если же IoCount стало = 0, значит больше никто не держит
; блокировку и можно возвращать управление.
KeWaitForSingleObject (&Lock->Common.RemoveEvent, Executive, KernelMode, FALSE, NULL);
}
} |
|
|
Дата: Авг 11, 2004 15:58:42 Это ты написал свой собственный диспетчер RemoveLock’ ирования или что вызывают RemoveLock' и (как они реализованы в Windows) ? Вот какая ошибка: Driver_unloading_without_canselling_pending_operation Потом … page fault. Затем в две строки указано имя драйвера (фильтра) , и адреса. |
|
|
Дата: Авг 12, 2004 00:22:20 [Вот те исходники этих функций с] То есть это то, чего в этих функциях вызывается, если их вызвать ? Где ты взял эти исходники (они, функции RemoveLock, в Win NT такие же, то есть тоже вызывают, что ты написал) ? |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.179 |