| 
			| 
					
						| Rulik 
								Помогающий    Offline | 
								|  | «  : 16-11-2006 09:14 »  |  | 
 
 Доброе время суток.
 Тут такая задача имеется:
 
 Драйвер сидит в режиме ядра и ничего не делает. Наступает момент когда приходят куча запросов от устройства. Драйвер должен решить, принимать запрос или отвергнуть. Причем в течении 1 сек. может прийти около 1000 запросов.
 
 Как я пердпологаю, запросы надо передать аплиухе из User мода и она ответит принимать запрос или нет.
 Соответственно задача, как приложение должно ожидать ответа от драйвера?
 |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Greysfi 
								Гость
 | 
								|  | « Ответ #1 : 16-11-2006 11:22 »  |  | 
 
 Просто реализуй в драйвере поддержку блокируемых или ассинхронных запросов. И тогда можно будет поставить запрос, а ответ от драйвера получить только когда произойдет реальное событие. |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Rulik 
								Помогающий    Offline | 
								|  | « Ответ #2 : 16-11-2006 11:39 »  |  | 
 
 Как я понимаю инициатором обмена между драйвером и приложением, может быть только приложени. Вот как бы послать приложению, что у драйвера, что  то есть. Не хотелось бы усыплять слушающий поток. Что то типа асинхронного обмена, как по ком-портам с использованием структуры OVERLAPPED. И посмотреть как это делать правильно. |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| RXL | 
								|  | « Ответ #3 : 16-11-2006 12:30 »  |  | 
 
 Rulik, асинхронная работа происходит именно так: приложение инициирует операцию, но не блокируется. |  
						| 
								|  |  
								|  |  Записан | 
 
 ... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С. |  |  | 
	| 
			| 
					
						| Greysfi 
								Гость
 | 
								|  | « Ответ #4 : 16-11-2006 12:47 »  |  | 
 
 Для того чтобы реализовать ассинхронный обмен нужно в обработчике IRP пометить IRP как pending (по моему). И сохранить его где нибудь например в очереде драйвера или создать user-driven очередь а потом когда получишь нужную информацию внути драйвера от тебя потребуется пометить это IRP как обработанное. |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Ochkarik | 
								|  | « Ответ #5 : 16-11-2006 17:38 »  |  | 
 
 Greysfi, истинно так!)
 |  
						| 
								|  |  
								|  |  Записан | 
 
 RTFM уже хоть раз наконец!     :[ ну или хотя бы STFW ... |  |  | 
	| 
			| 
					
						| Rulik 
								Помогающий    Offline | 
								|  | « Ответ #6 : 17-11-2006 03:28 »  |  | 
 
 Ок. Тогда как передаеться Event, указанный в структуре OVERLAPPED в поле hEvent? И кто его взводит при завершении операции? Сам драйвер или винда сама и управляет? |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Greysfi 
								Гость
 | 
								|  | « Ответ #7 : 17-11-2006 08:02 »  |  | 
 
 этот ивент не передается драйверу не посредственно. Ты делаешь свое дело а диспечер ввода/вывода сделает свое в том числе и ивент поднимет   |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Ochkarik | 
								|  | « Ответ #8 : 17-11-2006 08:16 »  |  | 
 
 помоему винда. примеры DDK посмотрите, не надо ленится там все есть)
 IRP_MJ_READ:
 ...ля-ля-ля. помещаем запрос в очередь
 IoMarkIrpPending(Irp);  - пометили что отложили
 возможно еще IoStartNextPacket? не помню точно... см примеры.
 return STATUS_PENDING; - вернули статус (вышли из IRP_MJ_READ)
 
 
 когда нибудь потом: обрабатываем отложенный запрос (например где нибудь в другой нити)
 ...ля-ля-ля. обработали.
 Irp->IoStatus.Status = STATUS_SUCCESS; - выставили свой статус
 Irp->IoStatus.Information = 0;- все как обычно.
 CompleteRequest(Fdo, Irp, IO_NO_INCREMENT); //ЗАВЕРШИЛИ. в этот момент выставляется событие из OVERLAPPED структуры запроса.
 
 
 помоему так) впрочем честно говоря ни разу этим не пользовался) - СМОТРИТЕ ПРИМЕРЫ DDK!!!!
 там же немерянно всего есть!
 PS лентяи;)
 |  
						| 
								|  |  
								|  |  Записан | 
 
 RTFM уже хоть раз наконец!     :[ ну или хотя бы STFW ... |  |  | 
	| 
			| 
					
						| Greysfi 
								Гость
 | 
								|  | « Ответ #9 : 17-11-2006 08:25 »  |  | 
 
 Об этом то я и говорю   . |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Rulik 
								Помогающий    Offline | 
								|  | « Ответ #10 : 17-11-2006 10:18 »  |  | 
 
 Я хотелбы пояснить, что я только проектирую драйвер и хотелось бы на этой стадии обойти возможные грабли, потому и спросил. А как делать отложенную обработку пакет я знаю, меня интересовал момент об вариантах реализации обмена с драйвером. Стандартный обмен я знаю, просто думал, что я только знаю шаблоны, и есть возможность сделать инициатором драйвер. А когда сказали, что не возможно, пришлось использовать не блокирующий ввод/вывод. А поэтому отсюда и вопрос кто правит этим Эвентом. В ДДК я по этому поводу не нашел ответа (может плохо искал). Вот теперь я точно знаю, кто его взводит. Теперь допишу ТЗ. Спасибо за уделенное время. |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Ochkarik | 
								|  | « Ответ #11 : 17-11-2006 12:27 »  |  | 
 
 впринципе возможен вариант выставления события без использования read/write/OVERLAPPED...Через DeviceIOControl передаете handle события... суть от этого не меняется, но мне удобнее. разница только в том что в этом случае вы будете его выставлять явным образом. (например так реализовано у меня для синхронизации и нити приложения и DPC обработки потока данных). в DPC - ставит событие, нить апликухи его постоянно ждет.
 
 других вариантов по большому счету нет)))
 PS
 ....в связи с тем, что приложение и драйвер работают в различных контекстах. таким образом, для того, чтобы вызвать из драйвера какую либо функцию приложения - необходимо переключить контекст, а это слишком большое вмешательство в работу планировщика задач.
 для уменьшения времени реакции приложения на выставленный в драйвере Event возможно завершение пакета CompleteRequest(Fdo, Irp, IO_NO_INCREMENT); со значением выше IO_NO_INCREMENT(от 0 до 8=IO_SOUND_INCREMENT, см дефенишены). в этом случае, если не ошибаюсь - планировщик более быстро переключит контекст, если нет более приоритетных потоков, правда и квант времени выделится меньший если не путаю. книга "внутреннее устройство W2000" раздел посвященный планировщику - там хорошо описано.
 |  
						| 
								|  |  
								| « Последнее редактирование: 17-11-2006 13:00 от Ochkarik » |  Записан | 
 
 RTFM уже хоть раз наконец!     :[ ну или хотя бы STFW ... |  |  | 
	| 
			| 
					
						| Greysfi 
								Гость
 | 
								|  | « Ответ #12 : 17-11-2006 21:40 »  |  | 
 
 Вообще при особом желании можно создать и именованный ивент в драйвере а в приложении его проверять. |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Ochkarik | 
								|  | « Ответ #13 : 20-11-2006 09:06 »  |  | 
 
 об этом и говорю... |  
						| 
								|  |  
								|  |  Записан | 
 
 RTFM уже хоть раз наконец!     :[ ну или хотя бы STFW ... |  |  | 
	| 
			| 
					
						| Karloson 
								Гость
 | 
								|  | « Ответ #14 : 12-12-2006 07:11 »  |  | 
 
 Прочитал ветку и возник косвенный вопрос по этой теме:Как все-таки драйверу узнать как была вызвана ф-ция ReadFile() - синхронно и асинхронно с OVERLAPPED?
 Ведь в первом случае драйвер не должен возвращать управление пока не считает данные или не сработает какой нибуть KeWaitForSingleObject(&event, ...., &waitDelay) == STATUS_TIMEOUT, а во втором - вызвать IoMarkIrpPending и вернуть управление. И как, в последнем случае, отразиться на драйвере вызов GetOverlappedResult()?
 |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Ochkarik | 
								|  | « Ответ #15 :  12-12-2006 08:38 »   |  | 
 
 не совсем. действия драйвера от наличия/отсутствия OVERLAPPED не зависят.драйвер всегда может вернуть статус выполнения сразу, а может отложить и вернуть pending.
 а вот операционная система в зависимости от того был вызов ReadFile - c OVERLAPPED или без - либо вернет управление вызывающему процессу с соответствующим статусом (error pending - например если требуется ожидание), либо, в противном случае, подождет события завершения IRP сама, и только после этого вернет управление вызывающему процессу.
 короче - если вы не ставите при вызове ReadFile поле OVERLAPPED, - тогда ожидание выполнется операционкой (ядровой функцией, которая ReadFile переводит в запрос IRP для конкретного девайса) в противном случае вы сами его обрабатываете.
 |  
						| 
								|  |  
								| « Последнее редактирование: 12-12-2006 08:41 от Ochkarik » |  Записан | 
 
 RTFM уже хоть раз наконец!     :[ ну или хотя бы STFW ... |  |  | 
	|  |