нить обработки данных (пример, не реализация):
Функция обработки данных вызвается в цикле из нити обработки
if (буфер данных пустой)
{
do{
WaiteForSingleObject{hEventDrv,...}
while(пока не появятся новые данные, либо что то еще, таймаут и т.д.)
}
обработка данных малая часть (произвольный размер от одного dword и более)...
уменьшение счетчика необработанных данных: InterlockedDecrement()
return;
то есть событие проверяется не всегда, но только когда данные закончатся - это сделано для повышения быстродействия. по той же причине не производится промежуточная буферизация данных в приложении. впрочем это не страшно, из драйвера я могу обнулить счетчик (хотя тоже синхронизировать придется... обнуление счетчика в драйвере InterlockedAdd() и в приложении InterlockedDecrement)
проблемма в том что в любом случае ждать в драйвере пока цикл в нити обработке дойдет до моей функции. а это время переключения контекстов + остальная обработка в нити обработке, которая мне неподвластна и поэтому неподконтрольны задержки выполнения. хотя можно попробовать переключить драйвером контекст сразу (повышением приоритета события).
---------------------------------------------------------
теперь насчет общей проблеммы.
покопал в выходные литературу, выяснилось что действительно данная проблемма удаления оборудования может быть решена не только придуманным мною способом но и штатным, через функции OC.
(всегда говорю что если вы пользуетесь хорошим продуктом, к которым отношу и винду (и кстати их офис)- там есть ВСЕ, что бы вам не понадобилось:thumbsup:, только это "все" - надо сначала найти)
1. моя последняя идея - запуск паралельной (или той же нити) в приложении, выставление в ней ожидание события, и пока драйвер его не выставит перед началом удаления устройства...
как только событие доходит до этой нити, она освобождает ресурс и сигнализирует драйверу, что мол отлинковалась от драйвера. впринципе все очевидно.
2. так же существуют штатные средства сигнализации удаления устройства (символической ссылки на него, или удаления символической ссылки на его GUID интерфейс).
для этого в приложении регестрируется запрос на получение оконных сообщений WM_DEVICECHANGE об удалении символической ссылки на устройство в драйвере IoDeleteSymbolicLink() (или интерфейса устройства - к сожалению не помню функцию):
RegisterDeviceNotification()/ UnregisterDeviceNotification()
суть:
получаем в драйвере запрос IRP_MN_QUERY_REMOVE_DEVICE (или IRP_MN_SURPRISE_REMOVAL) удаляем символическую ссылку на устройство драйвера: IoDeleteSymbolicLink() и
ждем пока счетчик в драйвере привязанный на IRP_MJ_CREATE/IRP_MJ_CLOSE не обнулится. (по обнулению в драйвере можно выставить событие чтобы не было лишнего ожидания)
IRP_MN_QUERY_REMOVE_DEVICE/IRP_MN_SURPRISE_REMOVAL приходят в системной нити, поэтому все пользовательские процессы работают.
пользовательский процесс получает WM_DEVICECHANGE и производит деинициализацию и CloseHandle для устройства. как только последний handle будет закрыт, ожидание в драйвере завершится и он сможет перейти к обработке IRP_MN_REMOVE_DEVICE, по которому удалить само устройство IoDeleteDevice().
минусы метода как и для первого - масса функций ожидания обработки WM_DEVICECHANGE всеми подключенными процессами.
3. метод подстмотрен в книжке W. Oney. заключается в том что каждое приложение запускает отдельную нить, в которой вызывает специальный DeviceIoControl() драйверу. драйвер этот IOCTL помечает как PENDING. Перед тем как внезапно удалить устройство - он завершает данный IOCTL, таким образом происходит синхронизация удаления.
мне такой подход не очень понравился, но как метод - почему бы и нет? может для чего то и можно применить...
и в четвертых - в 98 был еще один метод описываемый W. Oney, но я его не рассматривал по понятным причинам.
резюме:
к сожалению без ожидания, пока все процессы не обработают удаление устройства - не обойтись. в моем случае скорее всего я реализую одновременно оба первых варианта, первый подойдет для работы процесса в котором мне неподвластна функция обработки сообщений. второй - для остальных случаев. короче подублировать лишним не будет