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

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: ZwOpenEvent  (Прочитано 18134 раз)
0 Пользователей и 1 Гость смотрят эту тему.
grey
Гость
« : 16-03-2004 13:51 » 

Привет всем

У меня следующая проблемма:
создаю event в пользовательском режиме, а в драйвере не могу его открыть (хотя ведь это объект ядра). Искал в Global\\ и BaseNamedObjects\\ - так и не вышло.

P.S. Буду очень признателен за помощь Показываю язык [/list][/list]
Записан
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #1 : 17-03-2004 06:45 » 

Цитата

Искал в Global\\ и BaseNamedObjects\\

Чем искал?

ObReferenceObjectByHandle описана в DDK.
Записан
grey
Гость
« Ответ #2 : 17-03-2004 12:31 » 

Воспользовался подсказкой про ObReferenceObjectByHandle, но что-то не совсем выходит Улыбаюсь))

Правда потребовался не Event а Mutex (сори)

Подскажите пожалуйста где ошибка

Пользовательское приложение:

#define MUTEX_NAME "Glogal\\MyMutex"
hHookMutex = CreateMutex(NULL, FALSE, MUTEX_NAME);
...
WaitForSingleObject(hHookMutex, INFINITE);
...
ReleaseMutex(hHookMutex);

Через IOCTL передаю Handle Mutex

Драйвер:

Status = ObReferenceObjectByHandle((HANDLE)(*((PULONG)pBuffer)), 0, NULL, KernelMode, &hHookMutex, NULL);
...
KeWaitForSingleObject(hHookMutex, Executive, KernelMode, FALSE, NULL);
...
KeReleaseMutex(hHookMutex, FALSE);

В результате не происходит ожидание и сброс Mutex

P.S. Спасибо
Записан
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #3 : 19-03-2004 07:03 » 

Цитата

В результате не происходит ожидание и сброс Mutex


А тебе чего надо? Работает.
Записан
grey
Гость
« Ответ #4 : 19-03-2004 08:07 » 

Цитата: SlavaI
Цитата

В результате не происходит ожидание и сброс Mutex


А тебе чего надо? Работает.


В том - то и дело что НЕ происходит сброс и ожидание (значит не работает)
Записан
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #5 : 19-03-2004 10:14 » 

Цитата

сброс и ожидание


чего сброс. Нет такого понятия. Чего ты сбрасываешь, а потом ожидаешь?
Записан
grey
Гость
« Ответ #6 : 19-03-2004 11:16 » 

Привет

Хорошо, я объясню подробнее (Про сброс и ожидание я думаю понятно о чем я говорю. Суть не в словах а в смысле слов Улыбаюсь)))

Пользователь создает Mutex для синхронизации (монопольного доступа к памяти в которую драйвер пишет, а пользователь из нее читает). В то время пока драйвер заполняет память пользователь должен ждать, а когда она заполнена - драйвер приостанавливает все действия до того, как пользователь прочитает память и сообщит об этом драйверу. (Надеюсь идея понятна - причем это осуществляется не один раз, а постоянно).

Что происходит у меня:
пользователь создает Mutex и передает Handle через IOCTL для того, чтобы драйвер ObReferenceObjectByHandle и получил указатель на объект ядра. SoftIce показавает, что запись происходит, но когда буфер заполнился и вызывается KeReleaseMutex, то на KeWaitForMutexObject он не останавливается а продолжает писать. Причем пользователь вешается еще не доходя до WaitForSingleObject (причем висит не только пользователь, но и вся винда). Но что самое интересное - SoftIce показывает, что драйвер продолжает писать.

Тоесть вывод - неужели эта запись в буфер загружает процессор на 100% и почему не срабатывает KeReleaseMutex Не понял.

Надеюсь объяснил подробно Улыбаюсь))
Записан
Diletant
Помогающий

de
Offline Offline

« Ответ #7 : 19-03-2004 11:30 » 

Если у тебя для синхронизации используется только один мьютекс, то все логично. Так и должно быть.
Записан
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #8 : 19-03-2004 11:37 » 

Цитата

заполнился и вызывается KeReleaseMutex, то на KeWaitForMutexObject он не останавливается а продолжает пи


У тебя программа задом наперед работает? Зачем сначала вызывать KeReleaseMutex а потом KeWaitForMutexObject ? В коде у тебя наоборот.

Цитата

Причем пользователь вешается еще не доходя до WaitForSingleObject (причем висит не только пользователь, но и вся винда).


Ищи багу во всем коде.


Цитата

Надеюсь объяснил подробно ))


ага, тока объяснение с кодом расходится.
Записан
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #9 : 19-03-2004 11:41 » 

А зачем тебе мютекс- у тебя несколько потоков или драйвер асинхронную обработку делает?
Записан
grey
Гость
« Ответ #10 : 19-03-2004 12:41 » 

Я приведу тогда код с пояснениями целиком (кстати нигде этого не упомянул - запись в буфер происходит при перехвате функции ядра)

1. Пользователь создает Mutex
 hMutex = CreateMutex(...);

пересылает его драйверу через IOCTL

2. Драйвер получает указатель на объект Mutex
ObReferenceObjectByHandle(hMutex,..., &pObject)

3. Если происходит перехват функции, то
   KeWaitForMutexObject()
   ...запись в память
   if(буфер заполнен){
      KeReleaseMutex(...)
   }

Если условие выполнилось, то при перехвате следующей функции KeWaitForMutexObject() не должен разрешить запись.

4. В этот момент пользователь должен пройти WaitForSingleObject и произвести чтение. Как только закончил - ReleaseMutex и драйвер продолжает запись

Но как я и описал выше KeReleaseMutex не срабатывает и при перехвате следующей функции KeWaitForMutexObject позволяет писать дальше

Почему этот код работает наоборот Не понял (SlavaI)

И еще: может ли в данном случае произойти deadlock (может где Sleep() использовать Не понял)

P.S. Надеюсь на помощь Улыбаюсь))
Записан
maaaad
Гость
« Ответ #11 : 19-03-2004 15:22 » 

Мьютек перед рефренс надо бы открыть...
Записан
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #12 : 19-03-2004 15:32 » 

Цитата

Почему этот код работает наоборот Не понял (SlavaI)


потому что ты так описал - "заполнился и вызывается KeReleaseMutex, то на KeWaitForMutexObject он не останавливается а продолжает ". Как это еще понимать.

Далее-
Цитата

KeWaitForMutexObject()
...запись в память
if(буфер заполнен){
KeReleaseMutex(...)
}


KeWaitForMutexObject и KeReleaseMutex в одном потоке вызываются?

И наконец главное- насколько я понимаю у мютекса ведется счетчик захватов, и он должен освобождаться. То есть каждому вызову KeWaitForMutexObject должен быть соответствующий  KeReleaseMutex. А у тебя много KeWait... и один KeReleaseMutex. Вот ты и получил все время захваченный мютекс и юзер мод его получить не может. Вот так вот. К тому же учти- множественные захваты только для одного потока разрешены. Как там у тебя с контекстом?
Записан
Anonymous
Гость
« Ответ #13 : 20-03-2004 15:57 » 

Спасибо большое  всем за ответы.

Я понял почему у меня происходит эта ошибка. Если не сложно, то можно подсказку - как выйти из этой ситуации Улыбаюсь)))

Заранее всем спасибо
Записан
grey
Гость
« Ответ #14 : 20-03-2004 17:43 » 

Сорри, забыл войти Улыбаюсь))

Перехват функции и дальнейшая обработка происходит в контексте потока. Но если это приводит к постоянному захвату MUTEX, то существует ли какой-нибудь способ для выполнения моей задачи.

З.Ы. Спасибо
Записан
Anonymous
Гость
« Ответ #15 : 21-03-2004 08:06 » 

Или все-таки прейдется использовать 2 Event (т.к. для Event количество захватов не важно - ZwResetEvent вроде должен сбросить Event в любом случае) Не понял

Я нашел в google пример, но всеравно с Event не прошло Жаль(((

http://www.codeproject.com/system/driveguicomm.asp

Но почему-то Handle Mutex открывается с помощью ObReferenceObjectByHandle, а Event не хочет, хотя в примере именно так и делается.
Записан
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #16 : 22-03-2004 06:46 » 

Считай сколько раз захватил мютекс, столько раз и освобождай.
Записан
grey
Гость
« Ответ #17 : 22-03-2004 07:47 » 

Только что пробовал с Event - таже фигня (если с пишушим процессом ничего не делать, а только KeSetEvent пользователя - то все в порядке, но потеря данных, т.к. они могут перезаписаться)

Что касается на счет подсчета количества захватов, то я думаю что не выйдет. Количество захватов Mutex = числу блоков памяти. Если я KeReleaseMutex такое количество раз, до вроде бы должен сработать пользователь, но если в этот момент прийдет процесс с большим приоритетом, то он опять его захватит => опять таже проблемма Улыбаюсь))
Записан
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #18 : 23-03-2004 16:15 » 

Я не пойму, почему тебя не устраивает вариант- сигналить юзерскому приложению через event, что буффер заполнен, при этом переключаться в драйвере на другой буффер, который расширять по мере необходимости, а из него опять писать в юзерский буффер и сигналить юзеру- потерь не будет. А юзер сигналить о прочтении своим event.
Или вобще, писать в какой-то буфер в драйвере, а юзеру по его запросам передавать данные, влезающие в его буфер. А в драйвере если буфер достиг максимального размера, то перезаписывать с начала.
Записан
Anonymous
Гость
« Ответ #19 : 23-03-2004 17:19 » 

Так я в принципе так и делаю

Заполняю буфер (если он полон, то пишу сначала) и сигнализирую пользователю о заполнении, а чтоб небыло потерть данных (перезапись) необходимо приостановить запись - в этот то момент и висит. Если не приостанавливать - то все ОК.

Если использовать несколько буферов, то необходимо передавать их адреса и размеры. Причем если какой-то привилегированный процесс будет в него долго писать, то его размер будет очень большим - не очень удобно.

Я понял почему не освобождается Mutex, но я пробовал с Event - таже беда.

P.S. Буду очень благодарен решению этой проблеммы Улыбаюсь))
Записан
grey
Гость
« Ответ #20 : 24-03-2004 16:35 » 

Если я всем надоел своими тупыми вопросами, то просто скажите и я больше не буду ВАС беспокоить. Но я считаю, что единственный способ набраться опыта - это общение (т.к. в умных книгах обычно пишут в общем Улыбаюсь)))
Записан
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #21 : 25-03-2004 06:47 » 

Цитата

Если я всем надоел своими тупыми вопросами, то просто скажите и я больше не буду ВАС беспокоить. Но я считаю, что единственный способ набраться опыта - это общение (т.к. в умных книгах обычно пишут в общем )))


Ну заняты сейчас все.
Проблемы то у тебя нет. Используй Event и дополнительные буфера. А проблема переполнения не должна стоять- если все дополнительные буферы заполнены- перезаписывай наиболее старые. А потом из этих буферов копируй в тот, который юзер читает, когда он просигналит что готов принять новые данные. Зачем и кому передавать их адреса я не понял.

P.S. Ты что думаешь- тебе тут код напишут- ну тогда выкладывай свой полностью, а так сидеть и придумывать для кого код никто не будет, если это не связано с решаемой им в данный момент проблемой.
А в умных книгах все написано, в том числе и про множественные захваты мютексов, просто надо внимательно читать. Есть сайт www.osronline.com а там статья Sharing Memory..., Sharing Event... и еще другие всякие.

На вопросы твои не отвечают, так как трудно понять, что ты имеешь в виду, например твоя цитата
Цитата

Количество захватов Mutex = числу блоков памяти. Если я KeReleaseMutex такое количество раз, до вроде бы должен сработать пользователь, но если в этот момент прийдет процесс с большим приоритетом, то он опять его захватит => опять таже проблемма ))

от не понимаю я ее, о каких блоках памяти идет речь, если у тебя по твоим словам один буфер? Причем тут процесс(на самом деле единица выполнения- поток) с большим приоритетом? У тебя сколько читателей- писателей? Если твой драйвер (работающий в контексте одного и того же потока, так как ты же хочешь несколько раз хватать мютекс) решил освободить захваченный им несколько раз мютекс, нафига его сразу хватать, не дождавшись чтения от юзера, надо просто синхронизировать это, опять вылезают или Event или второй мютекс. Туманно все.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines