· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.WIN32 —› IoInitializeRemoveLock и так далее ?

<< . 1 . 2 . 3 . >>

Посл.отвђт Сообщен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 такие же, то есть тоже вызывают, что ты написал) ?

<< . 1 . 2 . 3 . >>


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.179