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

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Как синхронизировать память меж приложением и драйвром?  (Прочитано 15074 раз)
0 Пользователей и 1 Гость смотрят эту тему.
V-ctor
Гость
« : 19-01-2004 15:34 » 

Скажем такая ситуация: драйвер постоянно кидает данные в буфер, который создан в приложении и часто бывает в момент закрытия приложения выдается ошибка. Я так понимаю, что это из-за того, что дривер пишет в буфер, который система уже прибила. Т.е. если чтение не регулярное, что и ошибки такой нет.
Где про это можно почитать?
Записан
maaaaaad
Гость
« Ответ #1 : 20-01-2004 04:47 » 

1. Попробуй IRP_MJ_CLOSE сделать кэнселейшн всех ждущих irp.
2. Сделай в приложении перед закрытием ожидание окончания обработки всех закуиных и ожидающих irp.
3.
Цитата

в момент закрытия приложения выдается ошибка


ГДЕ КОНКРЕТНО ВЫДАЕТСЯ ОШИБКА!!!??? =)
Записан
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #2 : 20-01-2004 06:07 » 

Цитата

Я так понимаю, что это из-за того, что дривер пишет в буфер, который система уже прибила.


Это несколько неправильно, сделать драйвер зависящим от памяти, выделенной приложением, тут или как минимум надо оббить код записи в __try __except, или драйвер должен заблокировать память, выделенную приложением и , если нужна независимость от контекста, отобразить на системное адресное пространство. Вот тут есть статейка по теме  http://www.osronline.com/article.cfm?id=39  

maaaaaad, предлагает тебе еще следить за закрытием описателя драйвера, открытого приложением. Только помни- при закрытии сначала идут IRP_MJ_CLEANUP в контексте потока закрывшего хэндл, тут ты можешь сделать счетчик на каждый поток, открывшийhandle, например в IRP_MJ_CREATE получать PsGetCurrentThread и увеличивать счетчик для потока на единицу, в IRP_MJ_CLEANUP уменьшать на единицу. А вот IRP_MJ_CLOSE идет в контексте произвольного потока и означает что счетчик использования у FILE_OBJECT достиг нуля, то есть за одним или несколькими IRP_MJ_CLENUP идет один IRP_MJ_CLOSE.
Записан
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #3 : 20-01-2004 06:08 » 

Цитата

ГДЕ КОНКРЕТНО ВЫДАЕТСЯ ОШИБКА!!!??? =)


Я думаю в драйвере.
Записан
V-ctor
Гость
« Ответ #4 : 20-01-2004 09:54 » 

Статейку я эту читал и там же как раз пишут, что так можно сделать, работать из драйвера в память выделенную в приложении:
The application sends an IOCTL to the driver, providing a pointer to a buffer that the driver and the application thereafter share.

У меня так и сделано, а насчет блокирования, я думал, если метод директ, то система сама лочит память :
If METHOD_DIRECT is used, the user buffer will be locked into memory.
Или это все же мне надо самому лочить?

А при записи, я конечно пользую системный адрес, полученный, через MmGetSystemAddressForMdlSafe()).

А ошибка (NTSTATUS=STATUS_ACCESS_VIOLATION) выдается в приложении, если верить SIce'у.
Записан
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #5 : 20-01-2004 11:45 » 

Цитата

Статейку я эту читал и там же как раз пишут, что так можно сделать, работать из драйвера в память выделенную в приложении:


А я что сказал что так нельзя? Я же сказал что нужно сделать в этом случае для безопасности.

Цитата

 меня так и сделано, а насчет блокирования, я думал, если метод директ, то система сама лочит память :


Сама блокирует страницы, но не отображает в системное пространство.

Цитата

А при записи, я конечно пользую системный адрес, полученный, через MmGetSystemAddressForMdlSafe()).


Эта ф-ция отображает страницы из MDL в системное адресное пространство.

Цитата

А ошибка (NTSTATUS=STATUS_ACCESS_VIOLATION) выдается в приложении, если верить SIce'у.


А чего ему верить- если система рушится после выхода из него- это драйвер, если нет- то приложение. Посмотри PTE. Повторю вопрос maaaaaadа- где ошибка- в юзер моде или в кернел моде! Непонятно как-то ты говоришь, как угодно можно понять, противоречиво. Кто сбоит-то?
 А что у тебя за MDL, из Irp->Mdl. Они уничтожаются после завершения IRP, отображение тоже уничтожается.
Записан
V-ctor
Гость
« Ответ #6 : 20-01-2004 12:31 » 

Цитата

А я что сказал что так нельзя?

нет, просто меня насторожило высказывание:
Цитата

Это несколько неправильно, сделать драйвер зависящим от памяти, выделенной приложением,


нет, система не рушится, более того иногда в винде после завершения проги выскакивает сообщение, что "процес <который уже закрыт> вызвал ошибку и будет закрыт" и тут же еще окошко от д.р. ватсона, в котором написано примерно тоже самое + он не успел прицепится к приложению и код ошибки 87 (параметр задан не верно).
Видимо это приложение.

Кстати , а могут быть такие проблемы из-за того, что работа с дривером идет из двух процессов? Т.к. главное приложение создает у меня дополнительный процесс, для реагирования на прерывания. Возможно, что второй процесс продолжает работать в то время как , главный завершился? Хотя перед закрытием я делаю ему TerminateThread().
Записан
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #7 : 20-01-2004 13:48 » 

Цитата

винде после завершения проги выскакивает сообщение, что "процес <который уже закрыт> вызвал ошибку и будет закрыт"


То есть процесс закрыт, но вылетает через некоторое время ошибка? Очень похоже на то что у тебя есть зависшие IRP. При закрытии потока система пытается отменить все IRP, связанные с ним,при этом надо учесть что IRP созданное в результате запроса из потока не всегда находится в списке IRP, принадлежащих потоку, в этом списке обычно IRP от асинхронных запросов. Так вот- если отменить IRP нельзя или кто-то запендил IRP и не отпускает, то система не уничтожает поток, хотя может убрать его из списка функционирующих, давая ему время для завершения IRPs(так она сохраняет структуры, необходимые для завершения IRP), при этом могут быть частично уничтожены некоторые структуры потока, по истечении некоторого времени система принудительно прибивает поток- уничтожает все структуры и области памяти. Замечу- что проблема зависиших IRP- это проблема драйвера, а не приложения, то есть подвесить из юзер мода так систему нельзя, для этого нужен кривой драйвер.

Цитата

Кстати , а могут быть такие проблемы из-за того, что работа с дривером идет из двух процессов? Т.к. главное приложение создает у меня дополнительный процесс, для реагирования на прерывания. Возможно, что второй процесс продолжает работать в то время как , главный завершился? Хотя перед закрытием я делаю ему TerminateThread().


По моему ты путаешь потоки и процессы. Два потока и два процесса- разные вещи. У нормально написанного драйвера проблем ни с потоками ни с процессами нет.
Так что у тебя- потоки или процессы?
Записан
V-ctor
Гость
« Ответ #8 : 20-01-2004 14:39 » 

Цитата

То есть процесс закрыт, но вылетает через некоторое время ошибка?

Ошибка вылетает тут же после закрытия приложения.
Цитата

Замечу- что проблема зависиших IRP- это проблема драйвера, а не приложения, то есть подвесить из юзер мода так систему нельзя, для этого нужен кривой драйвер.

Да , но система не вешается намертво, всё продолжает работать и прога снова запускается и работает с дривером как ни в чем не бывало.

Цитата

По моему ты путаешь потоки и процессы.

мда видимо путаю...
ну так-то у меня вообще-то нитка , создается CreatThread, прибивается TerminateThread().
Записан
dorador
Гость
« Ответ #9 : 20-01-2004 15:00 » 

V-ctor, для информации:
Рихтер не рекомендует использовать TerminateThread(), так как уничтоженный поток не узнает о собственном завершении и не сможет очистить ресурсы.
Хотя в данном случае думаю это не при чем
Записан
V-ctor
Гость
« Ответ #10 : 20-01-2004 15:40 » 

Вопрос: чем тогда лучше прибивать поток?
Записан
dorador
Гость
« Ответ #11 : 20-01-2004 16:01 » 

сказать потоку через общую переменную, что пора закругляться
поток это воспринимает и выполняет _endthreadex (см. пример в MSDN)
Записан
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #12 : 21-01-2004 06:29 » 

Цитата

Рихтер не рекомендует использовать TerminateThread(), так как уничтоженный поток не узнает о собственном завершении и не сможет очистить ресурсы.


Спокойно. Поток не освободит, а вот процесс освободит. По окончании процесса ВСЕ ресурсы(память, описатели и т.д) будут освобождены, так что если не волнует временное неосвобождение памяти и хэндлов(до окончания процесса), можешь забить и вызывать TerminateTread. Хотя конечно TerminateThread это ненормальное завершение и есть другие способы отсигналить в поток- любой способ межпотоковых сообщений(ITC), в случае общего процесса наиболее удобная вещь- глобальная переменная, видимая из всех потоков.
Записан
Stran_nik
Гость
« Ответ #13 : 21-01-2004 11:46 » 

А какие сложности ввести объект синхронизации и проверить его при записи драйвером? Или скорость критична?
Записан
V-ctor
Гость
« Ответ #14 : 21-01-2004 16:31 » 

Вроде все разрулилось, спасибо за советы Ага
Записан
dorador
Гость
« Ответ #15 : 21-01-2004 16:32 » 

V-ctor, так что сделал то?
Записан
V-ctor
Гость
« Ответ #16 : 22-01-2004 06:55 » 

Дык это... у меня в обработке прерывания опрашивался чекбокс от другой формы и не учел, что когда приложение закрывается в момент выполнения обработки прерывания, то форма эта уже порушена, а я к ней лезу.
Записан
dorador
Гость
« Ответ #17 : 22-01-2004 08:13 » 

кстати, TerminateThread() функция асинхронная, т.е. после возврата из нее поток может быть еще не уничтожен. Может это и влияло.
Записан
V-ctor
Гость
« Ответ #18 : 22-01-2004 08:18 » 

может
Записан
dachny
Гость
« Ответ #19 : 22-01-2004 08:58 » 

Нормальные люди делают алок в дравере
потом по вызову из приложения делают мап ту user mode и в этомже вызове отдают валидный в user mode указатель
внимание указатель валиден только в контексте того процесса в котором происходил map
по закрытию драйвера приложением надо делать unmap если процесс в который делался map исчезнет а мар останется то будет продемонстрирован BSOD
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines